# API: Customers

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/customer-plays` | Retention plays with their signals, tasks and drafted emails | `customers:read` |
| POST | `/v1/customer-plays/:id/close` | Close a retention play as done or dismissed (its owner, the account's owner, or an owner) | `customers:write` |
| 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) | `customers:read` |
| PUT | `/v1/customer-settings` | Change customer settings (owners) | `settings:write` |
| PUT | `/v1/customer-settings/collections` | Invoice reminders: on or off, and the finance member told about overdue invoices (owners) | `settings:write` |
| PUT | `/v1/customer-settings/nps` | NPS surveys: on or off, days before the first survey (after they became a customer) and between surveys (owners) | `settings:write` |
| PUT | `/v1/customer-settings/nurture` | Nurture: on or off, a sequence for leads (else drafts), and the most touches a day (owners) | `settings:write` |
| GET | `/v1/customer-settings/onboarding-template` | The onboarding template (milestones with a day, a side and an optional first-value usage event) | `customers:read` |
| PUT | `/v1/customer-settings/onboarding-template` | Change the onboarding template (owners); null goes back to the default | `settings:write` |
| GET | `/v1/customer-settings/programs` | NPS, collections and nurture settings | `customers:read` |
| 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 | `integrations:write` |
| POST | `/v1/customer-settings/webhook-secret` | A new signing secret for customer-data webhooks (owners): shown once; the old one stops working at once | `integrations:write` |
| GET | `/v1/customers` | Customers: health score and band, change over 30 days, the next renewal, ARR, open tickets and the open retention play | `customers:read` |
| 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 | `customers:read` |
| 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 | `customers:write` |
| 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) | `customers:write` |
| 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 | `customers:write` |
| 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 | `customers:write` |
| POST | `/v1/customers/run` | Recompute 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-notes` | Install the handoff-notes skill (owners): agents can then write a won deal's handoff note | `settings:write` |
| GET | `/v1/deals/:id/handoff-note` | A won deal's handoff note: why they bought, promises made, what they signed, stakeholders, the next step | `deals:read` |
| GET | `/v1/invoices/:id` | An invoice and its reminder trail (each step, its draft and task) | `customers:read` |
| 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) | `customers:write` |
| GET | `/v1/lifecycle-templates` | Lifecycle templates (date offsets, reorders, events) with how many drafts each made | `customers:read` |
| POST | `/v1/lifecycle-templates` | Add a lifecycle template (owners), or presets by key: lease_end, warranty_end, renewal, service, reorder, onboarding_welcome | `settings:write` |
| DELETE | `/v1/lifecycle-templates/:id` | Delete a template (owners) | `settings:write` |
| PATCH | `/v1/lifecycle-templates/:id` | Change a template's name, subject, body or whether it's on (owners) | `settings:write` |
| GET | `/v1/nps` | NPS over a period: the score, promoters, passives and detractors, response rate, by industry, and the latest answers with comments | `customers:read` |
| GET | `/v1/nurture` | Nurture: the last 90 days' touches (drafts and sequence enrolments) with their cohort and reason, and counts | `customers:read` |
| GET | `/v1/nurture/preview` | Who qualifies for nurture now (dead leads, closed-lost, customers) and the reason to write to each; nothing is drafted | `customers:read` |
| 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) | `customers:write` |
| 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) | `customers:write` |
| GET | `/v1/onboarding-plans` | Onboarding plans: progress, overdue and stalled milestones, first value | `customers:read` |
| POST | `/v1/onboarding-plans` | Start an onboarding plan for a customer account by hand (from the template) | `customers:write` |
| GET | `/v1/onboarding-plans/:id` | An onboarding plan with its milestones, whether it's shared, and its views | `customers:read` |
| DELETE | `/v1/onboarding-plans/:id/share` | Stop the customer's link working | `customers:write` |
| POST | `/v1/onboarding-plans/:id/share` | A link for the customer to see their plan (90 days; replaces any earlier link). Shown once | `customers:write` |
| GET | `/v1/onboarding-report` | Time to first value: median and worst tenth (days), and plans still waiting | `customers:read` |
| GET | `/v1/public/nps/:token` | The NPS survey a customer was sent, by its link (no sign-in) | — |
| 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) | — |
| GET | `/v1/public/onboarding/:token` | A customer's onboarding plan, by its link (no sign-in) | — |
| 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 | `customers:read` |
| 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) | `customers:read` |
| 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) | `customers:write` |
| 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) | `customers:write` |
| 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) | `customers:write` |
| 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 | `customers:read` |
| 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 | `customers:read` |
| POST | `/v1/winbacks/:id/close` | Mark 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

```bash
curl -s "https://api.closefinch.com/v1/customer-plays" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
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 '{}'
```

```js
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)

```bash
curl -s "https://api.closefinch.com/v1/customer-settings" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/customer-settings" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/collections" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/nps" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X PUT "https://api.closefinch.com/v1/customer-settings/nurture" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s "https://api.closefinch.com/v1/customer-settings/onboarding-template" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
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 '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/customer-settings/programs" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
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 '{}'
```

```js
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

```bash
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 '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/customers" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/customers/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s -X PUT "https://api.closefinch.com/v1/customers/$ID/entitlements" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/customers/$ID/nps" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s -X POST "https://api.closefinch.com/v1/customers/$KIND" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s -X POST "https://api.closefinch.com/v1/customers/$KIND/upload" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/customers/run" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
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 '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/deals/$ID/handoff-note" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s "https://api.closefinch.com/v1/invoices/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/invoices/$ID/actions" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/lifecycle-templates" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s -X POST "https://api.closefinch.com/v1/lifecycle-templates" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/lifecycle-templates/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/lifecycle-templates/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/nps" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/nurture" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/nurture/preview" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/onboarding-milestones/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/onboarding-milestones/$ID" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/onboarding-plans" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/onboarding-plans" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/onboarding-plans/$ID" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s -X DELETE "https://api.closefinch.com/v1/onboarding-plans/$ID/share" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
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 '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/onboarding-report" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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.

```bash
curl -s "https://api.closefinch.com/v1/public/nps/$TOKEN"
```

```js
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.

```bash
curl -s -X POST "https://api.closefinch.com/v1/public/nps/$TOKEN" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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.

```bash
curl -s "https://api.closefinch.com/v1/public/onboarding/$TOKEN"
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/receivables" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s "https://api.closefinch.com/v1/renewals" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/renewals/$ID/call" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
curl -s -X PATCH "https://api.closefinch.com/v1/renewals/$ID/checklist" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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)

```bash
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 '{}'
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/white-space" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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

```bash
curl -s "https://api.closefinch.com/v1/winbacks" \
  -H "Authorization: Bearer $RA_API_KEY"
```

```js
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)

```bash
curl -s -X POST "https://api.closefinch.com/v1/winbacks/$ID/close" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
```

```js
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](https://www.closefinch.com/openapi.json). All resources: [API reference](https://www.closefinch.com/docs/api).
