Skip to content

API reference

API: Customers

Markdown version

MethodPathWhat it doesScope
GET/v1/customer-playsRetention plays with their signals, tasks and drafted emailscustomers:read
POST/v1/customer-plays/:id/closeClose a retention play as done or dismissed (its owner, the account's owner, or an owner)customers:write
GET/v1/customer-settingsCustomer settings: health weights, renewal probabilities, the onboarding channel, the default customer success owner, whether webhook secrets are set (never the secrets)customers:read
PUT/v1/customer-settingsChange customer settings (owners)settings:write
PUT/v1/customer-settings/collectionsInvoice reminders: on or off, and the finance member told about overdue invoices (owners)settings:write
PUT/v1/customer-settings/npsNPS surveys: on or off, days before the first survey (after they became a customer) and between surveys (owners)settings:write
PUT/v1/customer-settings/nurtureNurture: on or off, a sequence for leads (else drafts), and the most touches a day (owners)settings:write
GET/v1/customer-settings/onboarding-templateThe onboarding template (milestones with a day, a side and an optional first-value usage event)customers:read
PUT/v1/customer-settings/onboarding-templateChange the onboarding template (owners); null goes back to the defaultsettings:write
GET/v1/customer-settings/programsNPS, collections and nurture settingscustomers:read
PUT/v1/customer-settings/vendor-secrets/:vendorSet (or clear) a support tool's webhook secret (owners): Zendesk's signing secret or Intercom's client secret as given; for Freshdesk (which signs nothing) a token is generated and shown once, for an x-ra-token header on its webhook. Never returned againintegrations:write
POST/v1/customer-settings/webhook-secretA new signing secret for customer-data webhooks (owners): shown once; the old one stops working at onceintegrations:write
GET/v1/customersCustomers: health score and band, change over 30 days, the next renewal, ARR, open tickets and the open retention playcustomers:read
GET/v1/customers/:idA customer's scorecard: health with each component's inputs (and which have no data), its history, usage by week, tickets and churn signalscustomers:read
PUT/v1/customers/:id/entitlementsSet (or clear with null) what an account is entitled to for a usage metric (seats, a commit): upsell compares usage with it. An active contract's line quantities count too, for a usage metric named after the product's SKUcustomers:write
POST/v1/customers/:id/npsDraft an NPS survey for this customer now (into your approval inbox; NPS must be on; the account's owner or CSM, or an owner)customers:write
POST/v1/customers/:kindSend product usage, support tickets, orders or invoices (M9c: amounts in currency units, a due date, a status; up to 1,000 rows; idempotent by source and external id). Each row names its account by account_id, account_domain or the requester's emailcustomers:write
POST/v1/customers/:kind/uploadUpload a CSV (text) or a CSV/XLSX file (base64) of usage, tickets or orders, read by its headers (or a mapping); up to 20,000 rowscustomers:write
POST/v1/customers/runRecompute health, the renewal radar and churn signals soon (owners; queued at most every 5 minutes; it also runs daily)settings:write
POST/v1/customers/skills/handoff-notesInstall the handoff-notes skill (owners): agents can then write a won deal's handoff notesettings:write
GET/v1/deals/:id/handoff-noteA won deal's handoff note: why they bought, promises made, what they signed, stakeholders, the next stepdeals:read
GET/v1/invoices/:idAn invoice and its reminder trail (each step, its draft and task)customers:read
POST/v1/invoices/:id/actionsA promise to pay (pauses reminders until then, at most 60 days), a dispute, paid (not for Stripe's), stop, or resume (an owner, the finance member, or the account's owner or CSM)customers:write
GET/v1/lifecycle-templatesLifecycle templates (date offsets, reorders, events) with how many drafts each madecustomers:read
POST/v1/lifecycle-templatesAdd a lifecycle template (owners), or presets by key: lease_end, warranty_end, renewal, service, reorder, onboarding_welcomesettings:write
DELETE/v1/lifecycle-templates/:idDelete a template (owners)settings:write
PATCH/v1/lifecycle-templates/:idChange a template's name, subject, body or whether it's on (owners)settings:write
GET/v1/npsNPS over a period: the score, promoters, passives and detractors, response rate, by industry, and the latest answers with commentscustomers:read
GET/v1/nurtureNurture: the last 90 days' touches (drafts and sequence enrolments) with their cohort and reason, and countscustomers:read
GET/v1/nurture/previewWho qualifies for nurture now (dead leads, closed-lost, customers) and the reason to write to each; nothing is draftedcustomers:read
PATCH/v1/onboarding-milestones/:idChange a plan's milestone: its owner (a member who can see the account), due date, or first-value usage event (the plan's owner, the account's owner or CSM, or an owner)customers:write
POST/v1/onboarding-milestones/:idMark a milestone done, skipped or open again (the plan's owner, the account's owner or CSM, or an owner)customers:write
GET/v1/onboarding-plansOnboarding plans: progress, overdue and stalled milestones, first valuecustomers:read
POST/v1/onboarding-plansStart an onboarding plan for a customer account by hand (from the template)customers:write
GET/v1/onboarding-plans/:idAn onboarding plan with its milestones, whether it's shared, and its viewscustomers:read
DELETE/v1/onboarding-plans/:id/shareStop the customer's link workingcustomers:write
POST/v1/onboarding-plans/:id/shareA link for the customer to see their plan (90 days; replaces any earlier link). Shown oncecustomers:write
GET/v1/onboarding-reportTime to first value: median and worst tenth (days), and plans still waitingcustomers:read
GET/v1/public/nps/:tokenThe NPS survey a customer was sent, by its link (no sign-in)—
POST/v1/public/nps/:tokenAnswer the NPS survey: a score of 0 to 10 and an optional comment (changeable for 24 hours) (no sign-in)—
GET/v1/public/onboarding/:tokenA customer's onboarding plan, by its link (no sign-in)—
GET/v1/receivablesWho owes what: open and disputed invoices by age (not due, 1–30, 31–60, 61–90, over 90 days), totals per currency, each account's payment risk, and each invoice's next remindercustomers:read
GET/v1/renewalsThe retention forecast: renewals in the next 12 months by quarter and band, each with its expected value (amount × its band's probability, or the owner's call)customers:read
PATCH/v1/renewals/:id/callMake (or clear) the call on a renewal: commit, likely, at risk or churning (the account's owner or CSM, or an owner)customers:write
PATCH/v1/renewals/:id/checklistTick or untick an item of a renewal's 90/60/30-day gate checklist, e.g. 90.value_review (the account's owner or CSM, or an owner)customers:write
PATCH/v1/renewals/:id/failure-modeName a renewal's likeliest failure mode yourself (none: no likely failure), or clear it to use the computed one (the account's owner or CSM, or an owner)customers:write
GET/v1/white-spaceWhite space: customers against product families: owned (observed), cross-sell from peers in the same industry and size (a hypothesis, 5 peers or more), upsell from usage at 80% of entitlement for 2 weeks, and growth signalscustomers:read
GET/v1/winbacksDormant and declining customers (from orders and signed quotes) with the evidence, what they're worth if they come back, the lapsed bucket and the drafted openercustomers:read
POST/v1/winbacks/:id/closeMark a win-back as won back or dismissed (the account's owner or CSM, or an owner)customers:write

Examples

GET /v1/customer-plays

Retention plays with their signals, tasks and drafted emails

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

POST /v1/customer-plays/$ID/close

Close a retention play as done or dismissed (its owner, the account's owner, or an owner)

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

Customer settings: health weights, renewal probabilities, the onboarding channel, the default customer success owner, whether webhook secrets are set (never the secrets)

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

PUT /v1/customer-settings

Change customer settings (owners)

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

Invoice reminders: on or off, and the finance member told about overdue invoices (owners)

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

NPS surveys: on or off, days before the first survey (after they became a customer) and between surveys (owners)

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

Nurture: on or off, a sequence for leads (else drafts), and the most touches a day (owners)

curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/nurture" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/customer-settings/nurture`, {
  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/customer-settings/onboarding-template

The onboarding template (milestones with a day, a side and an optional first-value usage event)

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

PUT /v1/customer-settings/onboarding-template

Change the onboarding template (owners); null goes back to the default

curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/onboarding-template" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/customer-settings/onboarding-template`, {
  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/customer-settings/programs

NPS, collections and nurture settings

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

PUT /v1/customer-settings/vendor-secrets/$VENDOR

Set (or clear) a support tool's webhook secret (owners): Zendesk's signing secret or Intercom's client secret as given; for Freshdesk (which signs nothing) a token is generated and shown once, for an x-ra-token header on its webhook. Never returned again

curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/vendor-secrets/$VENDOR" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/customer-settings/vendor-secrets/${vendor}`, {
  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/customer-settings/webhook-secret

A new signing secret for customer-data webhooks (owners): shown once; the old one stops working at once

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

Customers: health score and band, change over 30 days, the next renewal, ARR, open tickets and the open retention play

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

GET /v1/customers/$ID

A customer's scorecard: health with each component's inputs (and which have no data), its history, usage by week, tickets and churn signals

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

PUT /v1/customers/$ID/entitlements

Set (or clear with null) what an account is entitled to for a usage metric (seats, a commit): upsell compares usage with it. An active contract's line quantities count too, for a usage metric named after the product's SKU

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

Draft an NPS survey for this customer now (into your approval inbox; NPS must be on; the account's owner or CSM, or an owner)

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

Send product usage, support tickets, orders or invoices (M9c: amounts in currency units, a due date, a status; up to 1,000 rows; idempotent by source and external id). Each row names its account by account_id, account_domain or the requester's email

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

Upload a CSV (text) or a CSV/XLSX file (base64) of usage, tickets or orders, read by its headers (or a mapping); up to 20,000 rows

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

Recompute health, the renewal radar and churn signals soon (owners; queued at most every 5 minutes; it also runs daily)

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

Install the handoff-notes skill (owners): agents can then write a won deal's handoff note

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

A won deal's handoff note: why they bought, promises made, what they signed, stakeholders, the next step

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

GET /v1/invoices/$ID

An invoice and its reminder trail (each step, its draft and task)

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

POST /v1/invoices/$ID/actions

A promise to pay (pauses reminders until then, at most 60 days), a dispute, paid (not for Stripe's), stop, or resume (an owner, the finance member, or the account's owner or CSM)

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

Lifecycle templates (date offsets, reorders, events) with how many drafts each made

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

POST /v1/lifecycle-templates

Add a lifecycle template (owners), or presets by key: lease_end, warranty_end, renewal, service, reorder, onboarding_welcome

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

Delete a template (owners)

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

PATCH /v1/lifecycle-templates/$ID

Change a template's name, subject, body or whether it's on (owners)

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

NPS over a period: the score, promoters, passives and detractors, response rate, by industry, and the latest answers with comments

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

GET /v1/nurture

Nurture: the last 90 days' touches (drafts and sequence enrolments) with their cohort and reason, and counts

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

GET /v1/nurture/preview

Who qualifies for nurture now (dead leads, closed-lost, customers) and the reason to write to each; nothing is drafted

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

PATCH /v1/onboarding-milestones/$ID

Change a plan's milestone: its owner (a member who can see the account), due date, or first-value usage event (the plan's owner, the account's owner or CSM, or an owner)

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

Mark a milestone done, skipped or open again (the plan's owner, the account's owner or CSM, or an owner)

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

Onboarding plans: progress, overdue and stalled milestones, first value

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

POST /v1/onboarding-plans

Start an onboarding plan for a customer account by hand (from the template)

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

An onboarding plan with its milestones, whether it's shared, and its views

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

DELETE /v1/onboarding-plans/$ID/share

Stop the customer's link working

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

POST /v1/onboarding-plans/$ID/share

A link for the customer to see their plan (90 days; replaces any earlier link). Shown once

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

Time to first value: median and worst tenth (days), and plans still waiting

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

GET /v1/public/nps/$TOKEN

The NPS survey a customer was sent, by its link. No sign-in, so it sends no key.

curl -s "https://api.closefinch.com/v1/public/nps/$TOKEN"
const res = await fetch(`https://api.closefinch.com/v1/public/nps/${token}`, {
  method: "GET",
});
const data = await res.json();

POST /v1/public/nps/$TOKEN

Answer the NPS survey: a score of 0 to 10 and an optional comment (changeable for 24 hours). No sign-in, so it sends no key.

curl -s -X POST "https://api.closefinch.com/v1/public/nps/$TOKEN" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/public/nps/${token}`, {
  method: "POST",
  headers: { "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

GET /v1/public/onboarding/$TOKEN

A customer's onboarding plan, by its link. No sign-in, so it sends no key.

curl -s "https://api.closefinch.com/v1/public/onboarding/$TOKEN"
const res = await fetch(`https://api.closefinch.com/v1/public/onboarding/${token}`, {
  method: "GET",
});
const data = await res.json();

GET /v1/receivables

Who owes what: open and disputed invoices by age (not due, 1–30, 31–60, 61–90, over 90 days), totals per currency, each account's payment risk, and each invoice's next reminder

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

GET /v1/renewals

The retention forecast: renewals in the next 12 months by quarter and band, each with its expected value (amount × its band's probability, or the owner's call)

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

PATCH /v1/renewals/$ID/call

Make (or clear) the call on a renewal: commit, likely, at risk or churning (the account's owner or CSM, or an owner)

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

PATCH /v1/renewals/$ID/checklist

Tick or untick an item of a renewal's 90/60/30-day gate checklist, e.g. 90.value_review (the account's owner or CSM, or an owner)

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

PATCH /v1/renewals/$ID/failure-mode

Name a renewal's likeliest failure mode yourself (none: no likely failure), or clear it to use the computed one (the account's owner or CSM, or an owner)

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

White space: customers against product families: owned (observed), cross-sell from peers in the same industry and size (a hypothesis, 5 peers or more), upsell from usage at 80% of entitlement for 2 weeks, and growth signals

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

GET /v1/winbacks

Dormant and declining customers (from orders and signed quotes) with the evidence, what they're worth if they come back, the lapsed bucket and the drafted opener

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

POST /v1/winbacks/$ID/close

Mark a win-back as won back or dismissed (the account's owner or CSM, or an owner)

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