API reference
API: Outbound
| Method | Path | What it does | Scope |
|---|---|---|---|
| POST | /v1/adaptive-proposals/decide | Approve or reject enrollment proposals (the sequence's owner or an organization owner) | messages:send |
| GET | /v1/consent | An address's consent and lawful-basis history (newest first) and current status per channel | sequences:read |
| POST | /v1/consent | Record consent, a lawful basis, a withdrawal or an objection (append-only; granted entries by owners) | sequences:write |
| GET | /v1/consent-records | The whole consent ledger, newest first (export; owners) | settings:write |
| GET | /v1/enrollments | Enrollments (by sequence, contact, sender or status) | sequences:read |
| POST | /v1/enrollments/:id/resume | Resume a paused enrollment (after an interrupted send: resend it, or skip it as sent) | messages:send |
| POST | /v1/enrollments/:id/stop | Stop an enrollment; never_contact also adds the address to the do-not-contact list | sequences:write |
| POST | /v1/enrollments/bulk | Pause, resume or stop many enrollments (a sequence's, a sender's, an account's, or a list); preview counts first, and a bulk pause's ref undoes it | sequences:write |
| GET | /v1/me/day | My day: sequence emails waiting for you, tasks due from sequences, and replies | sequences:read |
| GET | /v1/me/mailbox-delegates | Teammates who may approve and send sequence email from your mailbox | sequences:read |
| PUT | /v1/me/mailbox-delegates | Set who may send sequence email from your mailbox (signed-in people only) (web app only) | sequences:write |
| PUT | /v1/me/mailbox-delegates/expiry | Set when a delegate's access to your mailbox ends (null: no end) (web app only) | sequences:write |
| PUT | /v1/me/mailbox-pause | Pause sequence email from your mailbox until a time (null resumes) | sequences:write |
| PUT | /v1/me/outbound-profile | Your signature and booking link for sequence email | sequences:write |
| GET | /v1/me/sender-health | Your mailbox, 14-day reputation, today's limit and (dns=true) your domain's SPF, DKIM and DMARC | sequences:read |
| PUT | /v1/me/sequence-autopilot | Let sequences on autopilot (or after a first approval) send from your mailbox without your approval of each email (web app only) | messages:send |
| GET | /v1/me/tasks | My Day: your sequence tasks due today (or overdue) across sequences, calls first, with the context prepared for each | sequences:read |
| PUT | /v1/members/:id/outbound-profile | Set a teammate's signature and booking link (owner) | members:write |
| GET | /v1/opt-out-reviews | Replies that may be opt-outs, waiting for you to decide (owners see everyone's) | sequences:read |
| POST | /v1/opt-out-reviews/:id | Decide a held reply: an opt-out (recorded, their sequences end) or not (the hold lifts) | sequences:write |
| GET | /v1/outbound-analytics | Sequence results across the organization: sent, delivered, replies, positive replies, meetings, unsubscribes, progress | sequences:read |
| GET | /v1/outbound-messages | What the platform sent from people's mailboxes (by enrollment or sequence) | sequences:read |
| GET | /v1/sender-personas | Your personas and the organization's | sequences:read |
| POST | /v1/sender-personas | Save a sender persona (voice and writing samples) | sequences:write |
| DELETE | /v1/sender-personas/:id | Delete a persona (yours, or a shared one as an owner) | sequences:write |
| PATCH | /v1/sender-personas/:id | Edit a persona (yours, or a shared one as an owner); bumps its version | sequences:write |
| POST | /v1/sender-personas/eval | Check two personas produce distinguishable openers for a contact | sequences:write |
| GET | /v1/senders/:id/health | A teammate's sender health (owner) | settings:write |
| PUT | /v1/senders/:id/pause | Pause a teammate's sequence email until a time (owner) | settings:write |
| GET | /v1/sequence-rulesets | Reusable rulesets (exclusions, eligibility, behavior) | sequences:read |
| POST | /v1/sequence-rulesets | Create a ruleset (owner) | settings:write |
| PUT | /v1/sequence-rulesets/:id | Change a ruleset (owner; a new version, applied to every sequence using it). preview=true says what changes and how many active enrollments it would now exclude | settings:write |
| GET | /v1/sequence-tasks/:id | A sequence task: assignee and rule, SLA, prepared context, outcome | sequences:read |
| POST | /v1/sequence-tasks/:id/outcome | Log a call's outcome from its task (a call activity on the contact; a meeting or "not interested" ends the enrollment; do not call suppresses the number) | sequences:write |
| POST | /v1/sequence-tasks/bulk | Complete, skip, reassign or snooze many sequence tasks (yours, your sequences', or any as an organization owner) | sequences:write |
| GET | /v1/sequences | Sequences, with counts | sequences:read |
| POST | /v1/sequences | Create a sequence (a draft) | sequences:write |
| GET | /v1/sequences/:id | A sequence | sequences:read |
| PATCH | /v1/sequences/:id | Change a sequence (its owner or an organization owner) | sequences:write |
| GET | /v1/sequences/:id/adaptive | An adaptive sequence's enrollment proposals and the agent's recorded choices (with reasons) | sequences:read |
| POST | /v1/sequences/:id/adaptive/propose | Have the agent propose who to enroll from the sequence's audience, and when | sequences:write |
| GET | /v1/sequences/:id/analytics | One sequence's results, and each contact's status | sequences:read |
| POST | /v1/sequences/:id/enrollments | Enroll contacts (each is checked; skipped ones say why) | messages:send |
| GET | /v1/sequences/:id/experiments | Every experiment in a sequence (message variants, factorial designs, path and audience splits): sends, replies, positive replies and meetings per arm, and whether a winner is significant | sequences:read |
| PUT | /v1/sequences/:id/experiments/:key | Set an experiment's rule (metric, sample, significance, minimum days, auto-promotion); key is a step id or "audience" (with the audiences as arms). The sequence's owner or an organization owner | sequences:write |
| POST | /v1/sequences/:id/experiments/:key/promote | Promote a winner: new contacts get only it (weight 100, the rest 0). Without force, only the winner the significance rule found; for a factorial step the winner is factor=level | sequences:write |
| POST | /v1/sequences/:id/experiments/:key/stop | Stop an experiment (its numbers stay; nothing in the sequence changes; auto-promotion turns off) | sequences:write |
| GET | /v1/sequences/:id/experiments/export | Every experiment's arms and results as CSV (base64, for download) | sequences:read |
| POST | /v1/sequences/:id/preview | Each email of a sequence as one contact would get it (and whether they can be enrolled) | sequences:read |
| POST | /v1/sequences/:id/status | Turn a sequence on, pause it (optionally until a date) or archive it | sequences:write |
| POST | /v1/sequences/:id/test | Try a sequence on yourself: one step now, or the whole sequence as a test prospect (subject [Test]) | messages:send |
| GET | /v1/sequences/:id/variants | A/B results per step (reply rates and whether a variant has won) | sequences:read |
| GET | /v1/settings/outbound | The organization's outbound settings | sequences:read |
| PUT | /v1/settings/outbound | Set the organization's outbound settings (owner) | settings:write |
| PUT | /v1/settings/outbound/legitimate-interest | Adopt the organization's legitimate interest assessment (owner) (web app only) | settings:write |
| GET | /v1/suppressions | The do-not-contact list | sequences:read |
| POST | /v1/suppressions | Add someone (address, domain, phone, LinkedIn, company, or a name at a company) to the do-not-contact list (ends their enrollments) | sequences:write |
| DELETE | /v1/suppressions/:id | Take an entry off the list (owner; an unsubscribe's objection stays in the consent ledger) | settings:write |
| POST | /v1/suppressions/import | Upload a CSV of addresses or domains (a column named email or domain; up to 10,000 rows) | sequences:write |
Examples
POST /v1/adaptive-proposals/decide
Approve or reject enrollment proposals (the sequence's owner or an organization owner)
curl -s -X POST "https://api.closefinch.com/v1/adaptive-proposals/decide" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/adaptive-proposals/decide`, {
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/consent
An address's consent and lawful-basis history (newest first) and current status per channel
curl -s "https://api.closefinch.com/v1/consent" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/consent`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/consent
Record consent, a lawful basis, a withdrawal or an objection (append-only; granted entries by owners)
curl -s -X POST "https://api.closefinch.com/v1/consent" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/consent`, {
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/consent-records
The whole consent ledger, newest first (export; owners)
curl -s "https://api.closefinch.com/v1/consent-records" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/consent-records`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/enrollments
Enrollments (by sequence, contact, sender or status)
curl -s "https://api.closefinch.com/v1/enrollments" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/enrollments`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/enrollments/$ID/resume
Resume a paused enrollment (after an interrupted send: resend it, or skip it as sent)
curl -s -X POST "https://api.closefinch.com/v1/enrollments/$ID/resume" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/enrollments/${id}/resume`, {
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/enrollments/$ID/stop
Stop an enrollment; never_contact also adds the address to the do-not-contact list
curl -s -X POST "https://api.closefinch.com/v1/enrollments/$ID/stop" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/enrollments/${id}/stop`, {
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/enrollments/bulk
Pause, resume or stop many enrollments (a sequence's, a sender's, an account's, or a list); preview counts first, and a bulk pause's ref undoes it
curl -s -X POST "https://api.closefinch.com/v1/enrollments/bulk" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/enrollments/bulk`, {
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/me/day
My day: sequence emails waiting for you, tasks due from sequences, and replies
curl -s "https://api.closefinch.com/v1/me/day" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/me/day`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/me/mailbox-delegates
Teammates who may approve and send sequence email from your mailbox
curl -s "https://api.closefinch.com/v1/me/mailbox-delegates" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/me/mailbox-delegates`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/me/mailbox-pause
Pause sequence email from your mailbox until a time (null resumes)
curl -s -X PUT "https://api.closefinch.com/v1/me/mailbox-pause" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/me/mailbox-pause`, {
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();PUT /v1/me/outbound-profile
Your signature and booking link for sequence email
curl -s -X PUT "https://api.closefinch.com/v1/me/outbound-profile" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/me/outbound-profile`, {
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/me/sender-health
Your mailbox, 14-day reputation, today's limit and (dns=true) your domain's SPF, DKIM and DMARC
curl -s "https://api.closefinch.com/v1/me/sender-health" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/me/sender-health`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/me/tasks
My Day: your sequence tasks due today (or overdue) across sequences, calls first, with the context prepared for each
curl -s "https://api.closefinch.com/v1/me/tasks" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/me/tasks`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/members/$ID/outbound-profile
Set a teammate's signature and booking link (owner)
curl -s -X PUT "https://api.closefinch.com/v1/members/$ID/outbound-profile" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/members/${id}/outbound-profile`, {
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/opt-out-reviews
Replies that may be opt-outs, waiting for you to decide (owners see everyone's)
curl -s "https://api.closefinch.com/v1/opt-out-reviews" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/opt-out-reviews`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/opt-out-reviews/$ID
Decide a held reply: an opt-out (recorded, their sequences end) or not (the hold lifts)
curl -s -X POST "https://api.closefinch.com/v1/opt-out-reviews/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/opt-out-reviews/${id}`, {
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/outbound-analytics
Sequence results across the organization: sent, delivered, replies, positive replies, meetings, unsubscribes, progress
curl -s "https://api.closefinch.com/v1/outbound-analytics" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/outbound-analytics`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/outbound-messages
What the platform sent from people's mailboxes (by enrollment or sequence)
curl -s "https://api.closefinch.com/v1/outbound-messages" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/outbound-messages`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/sender-personas
Your personas and the organization's
curl -s "https://api.closefinch.com/v1/sender-personas" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sender-personas`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sender-personas
Save a sender persona (voice and writing samples)
curl -s -X POST "https://api.closefinch.com/v1/sender-personas" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sender-personas`, {
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/sender-personas/$ID
Delete a persona (yours, or a shared one as an owner)
curl -s -X DELETE "https://api.closefinch.com/v1/sender-personas/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sender-personas/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PATCH /v1/sender-personas/$ID
Edit a persona (yours, or a shared one as an owner); bumps its version
curl -s -X PATCH "https://api.closefinch.com/v1/sender-personas/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sender-personas/${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();POST /v1/sender-personas/eval
Check two personas produce distinguishable openers for a contact
curl -s -X POST "https://api.closefinch.com/v1/sender-personas/eval" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sender-personas/eval`, {
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/senders/$ID/health
A teammate's sender health (owner)
curl -s "https://api.closefinch.com/v1/senders/$ID/health" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/senders/${id}/health`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/senders/$ID/pause
Pause a teammate's sequence email until a time (owner)
curl -s -X PUT "https://api.closefinch.com/v1/senders/$ID/pause" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/senders/${id}/pause`, {
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/sequence-rulesets
Reusable rulesets (exclusions, eligibility, behavior)
curl -s "https://api.closefinch.com/v1/sequence-rulesets" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequence-rulesets`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequence-rulesets
Create a ruleset (owner)
curl -s -X POST "https://api.closefinch.com/v1/sequence-rulesets" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequence-rulesets`, {
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/sequence-rulesets/$ID
Change a ruleset (owner; a new version, applied to every sequence using it). preview=true says what changes and how many active enrollments it would now exclude
curl -s -X PUT "https://api.closefinch.com/v1/sequence-rulesets/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequence-rulesets/${id}`, {
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/sequence-tasks/$ID
A sequence task: assignee and rule, SLA, prepared context, outcome
curl -s "https://api.closefinch.com/v1/sequence-tasks/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequence-tasks/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequence-tasks/$ID/outcome
Log a call's outcome from its task (a call activity on the contact; a meeting or "not interested" ends the enrollment; do not call suppresses the number)
curl -s -X POST "https://api.closefinch.com/v1/sequence-tasks/$ID/outcome" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequence-tasks/${id}/outcome`, {
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/sequence-tasks/bulk
Complete, skip, reassign or snooze many sequence tasks (yours, your sequences', or any as an organization owner)
curl -s -X POST "https://api.closefinch.com/v1/sequence-tasks/bulk" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequence-tasks/bulk`, {
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/sequences
Sequences, with counts
curl -s "https://api.closefinch.com/v1/sequences" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequences
Create a sequence (a draft)
curl -s -X POST "https://api.closefinch.com/v1/sequences" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences`, {
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/sequences/$ID
A sequence
curl -s "https://api.closefinch.com/v1/sequences/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PATCH /v1/sequences/$ID
Change a sequence (its owner or an organization owner)
curl -s -X PATCH "https://api.closefinch.com/v1/sequences/$ID" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${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/sequences/$ID/adaptive
An adaptive sequence's enrollment proposals and the agent's recorded choices (with reasons)
curl -s "https://api.closefinch.com/v1/sequences/$ID/adaptive" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/adaptive`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequences/$ID/adaptive/propose
Have the agent propose who to enroll from the sequence's audience, and when
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/adaptive/propose" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/adaptive/propose`, {
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/sequences/$ID/analytics
One sequence's results, and each contact's status
curl -s "https://api.closefinch.com/v1/sequences/$ID/analytics" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/analytics`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequences/$ID/enrollments
Enroll contacts (each is checked; skipped ones say why)
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/enrollments" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/enrollments`, {
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/sequences/$ID/experiments
Every experiment in a sequence (message variants, factorial designs, path and audience splits): sends, replies, positive replies and meetings per arm, and whether a winner is significant
curl -s "https://api.closefinch.com/v1/sequences/$ID/experiments" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/experiments`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/sequences/$ID/experiments/$KEY
Set an experiment's rule (metric, sample, significance, minimum days, auto-promotion); key is a step id or "audience" (with the audiences as arms). The sequence's owner or an organization owner
curl -s -X PUT "https://api.closefinch.com/v1/sequences/$ID/experiments/$KEY" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/experiments/${key}`, {
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();POST /v1/sequences/$ID/experiments/$KEY/promote
Promote a winner: new contacts get only it (weight 100, the rest 0). Without force, only the winner the significance rule found; for a factorial step the winner is factor=level
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/experiments/$KEY/promote" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/experiments/${key}/promote`, {
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/sequences/$ID/experiments/$KEY/stop
Stop an experiment (its numbers stay; nothing in the sequence changes; auto-promotion turns off)
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/experiments/$KEY/stop" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/experiments/${key}/stop`, {
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/sequences/$ID/experiments/export
Every experiment's arms and results as CSV (base64, for download)
curl -s "https://api.closefinch.com/v1/sequences/$ID/experiments/export" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/experiments/export`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/sequences/$ID/preview
Each email of a sequence as one contact would get it (and whether they can be enrolled)
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/preview" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/preview`, {
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/sequences/$ID/status
Turn a sequence on, pause it (optionally until a date) or archive it
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/status" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${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();POST /v1/sequences/$ID/test
Try a sequence on yourself: one step now, or the whole sequence as a test prospect (subject [Test])
curl -s -X POST "https://api.closefinch.com/v1/sequences/$ID/test" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/test`, {
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/sequences/$ID/variants
A/B results per step (reply rates and whether a variant has won)
curl -s "https://api.closefinch.com/v1/sequences/$ID/variants" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/sequences/${id}/variants`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/settings/outbound
The organization's outbound settings
curl -s "https://api.closefinch.com/v1/settings/outbound" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/settings/outbound`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();PUT /v1/settings/outbound
Set the organization's outbound settings (owner)
curl -s -X PUT "https://api.closefinch.com/v1/settings/outbound" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/settings/outbound`, {
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/suppressions
The do-not-contact list
curl -s "https://api.closefinch.com/v1/suppressions" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/suppressions`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/suppressions
Add someone (address, domain, phone, LinkedIn, company, or a name at a company) to the do-not-contact list (ends their enrollments)
curl -s -X POST "https://api.closefinch.com/v1/suppressions" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/suppressions`, {
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/suppressions/$ID
Take an entry off the list (owner; an unsubscribe's objection stays in the consent ledger)
curl -s -X DELETE "https://api.closefinch.com/v1/suppressions/$ID" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/suppressions/${id}`, {
method: "DELETE",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/suppressions/import
Upload a CSV of addresses or domains (a column named email or domain; up to 10,000 rows)
curl -s -X POST "https://api.closefinch.com/v1/suppressions/import" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/suppressions/import`, {
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.