Skip to content

API reference

API: Messaging

Markdown version

MethodPathWhat it doesScope
GET/v1/mediaYour files (owners: everyone's)messages:read
POST/v1/mediaUpload a file to send (up to 15 MB): a voice note in your own voice (confirm it with own_voice: true), an image, a video or a PDF (web app only)messages:write
DELETE/v1/media/:idArchive a file (it isn't sent again)messages:write
GET/v1/media/:id/:exp/:sigA file by its signed, expiring link (what the channels fetch) (no sign-in)—
POST/v1/media/capturesThe browser extension's screenshot of your own tab, as an image for a messagemessages:write
GET/v1/media/likenessYour likeness consents for AI video (owners: everyone's) and the statement you'd typemessages:read
POST/v1/media/likenessConsent to AI video of yourself: your own photo (HeyGen) or your own Tavus replica, with the dated statement typed exactly (web app only)messages:write
DELETE/v1/media/likeness/:idWithdraw a likeness consent (you, or an owner): its videos stop being sendablemessages:write
POST/v1/media/screenshotsA screenshot of a public web page (ScreenshotOne, your organization's key) as an image for a messagemessages:write
GET/v1/media/videosYour AI videos (owners: everyone's): rendering, ready (a draft), approvedmessages:read
POST/v1/media/videosMake an AI video of yourself from a script ({first_name} and {company} filled from a contact); it's a draft until you approve it (web app only)messages:write
POST/v1/media/videos/:id/decisionApprove or reject your AI video (only the person in it); nothing is sent (web app only)messages:write
POST/v1/media/voice-notesMake an AI voice note in your own cloned voice (your consent must cover voice messages; at most a minute); it's sent only by you, always with a line saying it was made with AI (web app only)messages:write
GET/v1/messaging/connectionsYour organization's messaging channels (WhatsApp, Telegram, Instagram, iMessage) and their webhook URLsconnections:read
POST/v1/messaging/connectionsConnect a channel account with your own credentials (checked with the provider first). The response shows, once, what to paste into Meta's dashboard or Sendblue. iMessage needs acknowledge_platform_risk: true (web app only)integrations:write
DELETE/v1/messaging/connections/:idDisconnect a channel: nothing more is sent or captured (web app only)integrations:write
PATCH/v1/messaging/connections/:idChange a channel's settings: the AI agent on or off, the WABA id, Instagram's Human Agent permission (web app only)integrations:write
POST/v1/messaging/telegram/linkA Telegram deep link: for a contact (their chat with the bot is tied to them), or for yourself (capture your own Telegram Business chats, private to you) (web app only)connections:write
GET/v1/messaging/templatesWhatsApp templates and their Meta review statusmessages:read
POST/v1/messaging/templatesSubmit a WhatsApp template to Meta for review (owners) (web app only)settings:write
POST/v1/messaging/templates/syncRefresh template statuses from Metasettings:write
GET/v1/messaging/threadsConversations you may see, newest first (optionally one contact's)messages:read
GET/v1/messaging/threads/:idOne conversation: its messages and what may be sent now (the channel's window)messages:read
POST/v1/messaging/threads/:id/contactTie the conversation to a contact (its messages join their timeline)messages:write
GET/v1/messaging/threads/:id/media/:assetA file someone sent in the conversationmessages:read
POST/v1/messaging/threads/:id/messagesSend as yourself: text, your files, or (WhatsApp, outside the window) an approved template. The channel's rules, opt-outs, consent and the organization's policy apply; anything they refuse is refused before it's sent (web app only)messages:send
GET/v1/messaging/webhooks/:tokenMeta's webhook subscription handshake (hub.challenge, checked against your verify token) (no sign-in)—
POST/v1/messaging/webhooks/:tokenChannel webhooks (public): Meta's X-Hub-Signature-256 over the raw body, Telegram's secret token header, or Sendblue's header secret; each message applied once (no sign-in)—

Examples

GET /v1/media

Your files (owners: everyone's)

curl -s "https://api.closefinch.com/v1/media" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/media`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

DELETE /v1/media/$ID

Archive a file (it isn't sent again)

curl -s -X DELETE "https://api.closefinch.com/v1/media/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/media/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/media/captures

The browser extension's screenshot of your own tab, as an image for a message

curl -s -X POST "https://api.closefinch.com/v1/media/captures" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/media/captures`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/media/likeness

Your likeness consents for AI video (owners: everyone's) and the statement you'd type

curl -s "https://api.closefinch.com/v1/media/likeness" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/media/likeness`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

DELETE /v1/media/likeness/$ID

Withdraw a likeness consent (you, or an owner): its videos stop being sendable

curl -s -X DELETE "https://api.closefinch.com/v1/media/likeness/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/media/likeness/${id}`, {
  method: "DELETE",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/media/screenshots

A screenshot of a public web page (ScreenshotOne, your organization's key) as an image for a message

curl -s -X POST "https://api.closefinch.com/v1/media/screenshots" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/media/screenshots`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/media/videos

Your AI videos (owners: everyone's): rendering, ready (a draft), approved

curl -s "https://api.closefinch.com/v1/media/videos" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/media/videos`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

GET /v1/messaging/connections

Your organization's messaging channels (WhatsApp, Telegram, Instagram, iMessage) and their webhook URLs

curl -s "https://api.closefinch.com/v1/messaging/connections" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/messaging/connections`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

GET /v1/messaging/templates

WhatsApp templates and their Meta review status

curl -s "https://api.closefinch.com/v1/messaging/templates" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/messaging/templates`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/messaging/templates/sync

Refresh template statuses from Meta

curl -s -X POST "https://api.closefinch.com/v1/messaging/templates/sync" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/messaging/templates/sync`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/messaging/threads

Conversations you may see, newest first (optionally one contact's)

curl -s "https://api.closefinch.com/v1/messaging/threads" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/messaging/threads`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

GET /v1/messaging/threads/$ID

One conversation: its messages and what may be sent now (the channel's window)

curl -s "https://api.closefinch.com/v1/messaging/threads/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/messaging/threads/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

POST /v1/messaging/threads/$ID/contact

Tie the conversation to a contact (its messages join their timeline)

curl -s -X POST "https://api.closefinch.com/v1/messaging/threads/$ID/contact" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/messaging/threads/${id}/contact`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/messaging/threads/$ID/media/$ASSET

A file someone sent in the conversation

curl -s "https://api.closefinch.com/v1/messaging/threads/$ID/media/$ASSET" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/messaging/threads/${id}/media/${asset}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();

Request and response schemas: https://www.closefinch.com/openapi.json. All resources: API reference.

Send feedback

Tell us what's broken, confusing or missing on this page, or an idea. It goes to the team that builds the product.

Please don't include passwords or card numbers.
Only to reply about this. Never added to any mailing list.