# API: Lead routing

| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | `/v1/inbound/campaigns` | Conversion by campaign (UTM): visitors, chats, qualified, booked | `inbound:read` |
| GET | `/v1/inbound/credits` | Meetings booked for teammates and credited, per person | `inbound:read` |
| GET | `/v1/inbound/forms` | Forms: drafts and published, with the hosted link and the embed code | `inbound:read` |
| POST | `/v1/inbound/forms` | Add a form (a draft until an owner publishes it) | `inbound:write` |
| PATCH | `/v1/inbound/forms/:id` | Change a form (it goes back to draft) | `inbound:write` |
| POST | `/v1/inbound/forms/:id/publish` | Publish or unpublish a form (owners: the approval for agent-drafted forms) | `settings:write` |
| POST | `/v1/inbound/forms/draft` | Have the agent draft a form from a brief (a draft for an owner to review and publish) | `inbound:write` |
| GET | `/v1/inbound/leads` | Inbound leads: source, grade, owner, how they were routed, and their response time | `inbound:read` |
| POST | `/v1/inbound/leads` | Send a lead in (it's graded, routed and recorded like any other) | `inbound:write` |
| GET | `/v1/inbound/leads/:id` | A lead and its routing decision: every rule evaluated, the candidates and why each was skipped | `inbound:read` |
| POST | `/v1/inbound/leads/:id/touch` | Accept a lead (stops its response-time clock) | `inbound:write` |
| POST | `/v1/inbound/meetings/book-for` | Book a meeting for a teammate (SDR → AE): the meeting is theirs, the credit yours | `inbound:write` |
| GET | `/v1/inbound/referrals` | Partner referrals (unknown partners wait for review) | `inbound:read` |
| POST | `/v1/inbound/referrals/:id/decide` | Accept (creates and links the records) or reject a referral | `inbound:write` |
| GET | `/v1/inbound/sources` | Lead intake sources (webhook, Typeform, Google Forms, Facebook Lead Ads, CSV) | `inbound:read` |
| POST | `/v1/inbound/sources` | Add an intake source (owners); its signing secret is shown once | `settings:write` |
| POST | `/v1/inbound/sources/:id/csv` | Upload leads to a CSV source (rows as JSON objects; up to 1,000) | `inbound:write` |
| POST | `/v1/inbound/sources/:id/rotate-secret` | Replace a source's signing secret (owners); shown once | `settings:write` |
| GET | `/v1/routing/decisions` | Routing decisions, newest first (optionally for one queue) | `inbound:read` |
| GET | `/v1/routing/graph` | The current routing graph and its earlier versions | `inbound:read` |
| POST | `/v1/routing/graph` | Publish a new version of the routing graph (owners): condition, branch, account owner, territory, queue and person nodes | `settings:write` |
| PUT | `/v1/routing/people/:id/away` | Mark someone away until a time (round-robin skips them); yourself, or anyone for owners | `inbound:write` |
| GET | `/v1/routing/queues` | Round-robin queues | `inbound:read` |
| POST | `/v1/routing/queues` | Add a round-robin queue (owners) | `settings:write` |
| PATCH | `/v1/routing/queues/:id` | Change a queue's name, members, weights or caps, or archive it (owners) | `settings:write` |
| GET | `/v1/routing/settings` | SLA by tier, escalation, the enterprise tier for demo prep, the partner manager, the meeting credit rule | `inbound:read` |
| PUT | `/v1/routing/settings` | Change routing settings (owners) | `settings:write` |
| POST | `/v1/routing/simulate` | Dry run: what the current graph would decide for a lead (nothing is written) | `inbound:read` |

## Examples

### GET /v1/inbound/campaigns

Conversion by campaign (UTM): visitors, chats, qualified, booked

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/campaigns`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/inbound/credits

Meetings booked for teammates and credited, per person

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/credits`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/inbound/forms

Forms: drafts and published, with the hosted link and the embed code

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/forms`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/inbound/forms

Add a form (a draft until an owner publishes it)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/forms`, {
  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();
```

### PATCH /v1/inbound/forms/$ID

Change a form (it goes back to draft)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/forms/${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/inbound/forms/$ID/publish

Publish or unpublish a form (owners: the approval for agent-drafted forms)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/forms/${id}/publish`, {
  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/inbound/forms/draft

Have the agent draft a form from a brief (a draft for an owner to review and publish)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/forms/draft`, {
  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/inbound/leads

Inbound leads: source, grade, owner, how they were routed, and their response time

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/leads`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/inbound/leads

Send a lead in (it's graded, routed and recorded like any other)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/leads`, {
  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/inbound/leads/$ID

A lead and its routing decision: every rule evaluated, the candidates and why each was skipped

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/leads/${id}`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/inbound/leads/$ID/touch

Accept a lead (stops its response-time clock)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/leads/${id}/touch`, {
  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/inbound/meetings/book-for

Book a meeting for a teammate (SDR → AE): the meeting is theirs, the credit yours

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/meetings/book-for`, {
  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/inbound/referrals

Partner referrals (unknown partners wait for review)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/referrals`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/inbound/referrals/$ID/decide

Accept (creates and links the records) or reject a referral

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/referrals/${id}/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/inbound/sources

Lead intake sources (webhook, Typeform, Google Forms, Facebook Lead Ads, CSV)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/sources`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/inbound/sources

Add an intake source (owners); its signing secret is shown once

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/sources`, {
  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/inbound/sources/$ID/csv

Upload leads to a CSV source (rows as JSON objects; up to 1,000)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/sources/${id}/csv`, {
  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/inbound/sources/$ID/rotate-secret

Replace a source's signing secret (owners); shown once

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

```js
const res = await fetch(`https://api.closefinch.com/v1/inbound/sources/${id}/rotate-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/routing/decisions

Routing decisions, newest first (optionally for one queue)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/decisions`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### GET /v1/routing/graph

The current routing graph and its earlier versions

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/graph`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/routing/graph

Publish a new version of the routing graph (owners): condition, branch, account owner, territory, queue and person nodes

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/graph`, {
  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/routing/people/$ID/away

Mark someone away until a time (round-robin skips them); yourself, or anyone for owners

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/people/${id}/away`, {
  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/routing/queues

Round-robin queues

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/queues`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### POST /v1/routing/queues

Add a round-robin queue (owners)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/queues`, {
  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();
```

### PATCH /v1/routing/queues/$ID

Change a queue's name, members, weights or caps, or archive it (owners)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/queues/${id}`, {
  method: "PATCH",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();
```

### GET /v1/routing/settings

SLA by tier, escalation, the enterprise tier for demo prep, the partner manager, the meeting credit rule

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/settings`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();
```

### PUT /v1/routing/settings

Change routing settings (owners)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/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();
```

### POST /v1/routing/simulate

Dry run: what the current graph would decide for a lead (nothing is written)

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

```js
const res = await fetch(`https://api.closefinch.com/v1/routing/simulate`, {
  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).
