Skip to content

API reference

API: Replies

Markdown version

MethodPathWhat it doesScope
GET/v1/follow-upsFollow-ups after one-off sends and callbacks people asked for, with their statemessages:read
PATCH/v1/follow-ups/:idMove a follow-up, or mark it done or cancelledmessages:write
GET/v1/inboxConversations: needs reply, interested, replies, escalated or done, with a count per viewmessages:read
GET/v1/inbox-tagsThe organization's conversation tagsmessages:read
POST/v1/inbox-tagsCreate a tagmessages:write
DELETE/v1/inbox-tags/:idDelete a tag (it comes off every conversation)messages:write
PATCH/v1/inbox-tags/:idRename or recolor a tagmessages:write
GET/v1/inbox/:contact_idOne conversation: messages in time order, each reply's labels and actions, and the side panel (research, CRM, sequences, meetings)messages:read
POST/v1/inbox/:contact_id/assignGive a conversation to a teammate (an escalated one: its current person or an owner, signed in)messages:write
POST/v1/inbox/:contact_id/deescalateClear an escalation: the agent may draft and (within the autopilot rules) answer again (web app only)messages:write
POST/v1/inbox/:contact_id/statusMark a conversation done, or reopen it (a new message reopens it too)messages:write
PUT/v1/inbox/:contact_id/tagsSet a conversation's tagsmessages:write
PUT/v1/me/reply-autopilotLet eligible replies be answered from your mailbox without your approval of each (the organization's autopilot rules still apply) (web app only)messages:send
POST/v1/replies-evalRun the reply-label eval set with your model: per-label precision and recall (web app only)settings:write
GET/v1/replies-statsReply handling: by label, time from receipt to answer (autopilot and approved), escalationsmessages:read
GET/v1/replies/:idA reply: triage, labels with confidence and rationale, and what the labels didmessages:read
POST/v1/replies/:id/categorySet a message's category yourself (prospect reply, customer, vendor, internal, automated, newsletter, spam, other): audited; automated, newsletter, spam and internal leave the inboxmessages:write
POST/v1/replies/:id/labelsCorrect a reply's labels: audited; actions that are safe to repeat run againmessages:write
POST/v1/replies/:id/remindSnooze a reply: you're told about it again in this many hours (1–168) unless it's answered or the conversation is donemessages:write
GET/v1/reply-libraryApproved answers to objections and questions (autopilot replies must be grounded in one)messages:read
POST/v1/reply-libraryAdd an entry (an owner approves it before it grounds a reply)messages:write
DELETE/v1/reply-library/:idDelete an entrymessages:write
PATCH/v1/reply-library/:idEdit an entry (it needs approving again)messages:write
POST/v1/reply-library/:id/approveApprove an entry (owners, signed in) (web app only)settings:write
GET/v1/routing-logWhy each email to a shared address went to whommessages:read
GET/v1/settings/repliesHow replies are labeled, escalated, answered, routed and followed upmessages:read
PUT/v1/settings/repliesChange the reply settings (owners, signed in) (web app only)settings:write
GET/v1/snoozesSnoozed conversations coming up (yours, or everyone's for owners)messages:read
POST/v1/snoozes/:id/cancelCancel a snooze (the sequence stays stopped)messages:write
POST/v1/snoozes/:id/confirmConfirm (or change) the date a snoozed conversation resumesmessages:write

Examples

GET /v1/follow-ups

Follow-ups after one-off sends and callbacks people asked for, with their state

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

PATCH /v1/follow-ups/$ID

Move a follow-up, or mark it done or cancelled

curl -s -X PATCH "https://api.closefinch.com/v1/follow-ups/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/follow-ups/${id}`, {
  method: "PATCH",
  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/inbox

Conversations: needs reply, interested, replies, escalated or done, with a count per view

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

GET /v1/inbox-tags

The organization's conversation tags

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

POST /v1/inbox-tags

Create a tag

curl -s -X POST "https://api.closefinch.com/v1/inbox-tags" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/inbox-tags`, {
  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();

DELETE /v1/inbox-tags/$ID

Delete a tag (it comes off every conversation)

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

PATCH /v1/inbox-tags/$ID

Rename or recolor a tag

curl -s -X PATCH "https://api.closefinch.com/v1/inbox-tags/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/inbox-tags/${id}`, {
  method: "PATCH",
  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/inbox/$CONTACT_ID

One conversation: messages in time order, each reply's labels and actions, and the side panel (research, CRM, sequences, meetings)

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

POST /v1/inbox/$CONTACT_ID/assign

Give a conversation to a teammate (an escalated one: its current person or an owner, signed in)

curl -s -X POST "https://api.closefinch.com/v1/inbox/$CONTACT_ID/assign" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/inbox/${contact_id}/assign`, {
  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();

POST /v1/inbox/$CONTACT_ID/status

Mark a conversation done, or reopen it (a new message reopens it too)

curl -s -X POST "https://api.closefinch.com/v1/inbox/$CONTACT_ID/status" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/inbox/${contact_id}/status`, {
  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();

PUT /v1/inbox/$CONTACT_ID/tags

Set a conversation's tags

curl -s -X PUT "https://api.closefinch.com/v1/inbox/$CONTACT_ID/tags" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/inbox/${contact_id}/tags`, {
  method: "PUT",
  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/replies-stats

Reply handling: by label, time from receipt to answer (autopilot and approved), escalations

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

GET /v1/replies/$ID

A reply: triage, labels with confidence and rationale, and what the labels did

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

POST /v1/replies/$ID/category

Set a message's category yourself (prospect reply, customer, vendor, internal, automated, newsletter, spam, other): audited; automated, newsletter, spam and internal leave the inbox

curl -s -X POST "https://api.closefinch.com/v1/replies/$ID/category" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/replies/${id}/category`, {
  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();

POST /v1/replies/$ID/labels

Correct a reply's labels: audited; actions that are safe to repeat run again

curl -s -X POST "https://api.closefinch.com/v1/replies/$ID/labels" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/replies/${id}/labels`, {
  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();

POST /v1/replies/$ID/remind

Snooze a reply: you're told about it again in this many hours (1–168) unless it's answered or the conversation is done

curl -s -X POST "https://api.closefinch.com/v1/replies/$ID/remind" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/replies/${id}/remind`, {
  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/reply-library

Approved answers to objections and questions (autopilot replies must be grounded in one)

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

POST /v1/reply-library

Add an entry (an owner approves it before it grounds a reply)

curl -s -X POST "https://api.closefinch.com/v1/reply-library" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/reply-library`, {
  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();

DELETE /v1/reply-library/$ID

Delete an entry

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

PATCH /v1/reply-library/$ID

Edit an entry (it needs approving again)

curl -s -X PATCH "https://api.closefinch.com/v1/reply-library/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/reply-library/${id}`, {
  method: "PATCH",
  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/routing-log

Why each email to a shared address went to whom

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

GET /v1/settings/replies

How replies are labeled, escalated, answered, routed and followed up

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

GET /v1/snoozes

Snoozed conversations coming up (yours, or everyone's for owners)

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

POST /v1/snoozes/$ID/cancel

Cancel a snooze (the sequence stays stopped)

curl -s -X POST "https://api.closefinch.com/v1/snoozes/$ID/cancel" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/snoozes/${id}/cancel`, {
  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();

POST /v1/snoozes/$ID/confirm

Confirm (or change) the date a snoozed conversation resumes

curl -s -X POST "https://api.closefinch.com/v1/snoozes/$ID/confirm" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/snoozes/${id}/confirm`, {
  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();

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.