API reference
API: People data
| Method | Path | What it does | Scope |
|---|---|---|---|
| GET | /v1/accounts/:id/headcount | An account's headcount by function: the latest snapshot per source (PDL estimate, or counted from your CRM's contacts: not complete), each quarter's snapshot and its change against the quarter before | accounts:read |
| POST | /v1/accounts/:id/headcount/snapshot | Take this month's headcount snapshot now: counted from the CRM, and from PDL when a key is set (one company credit, cached about a month) | accounts:write |
| GET | /v1/job-changes | Detected job changes (company change, title change, possible departure) with old and new values, each source's evidence and date, the confidence and whether a person needs to confirm it | signals:read |
| POST | /v1/job-changes/:id/confirm | Confirm a job change: it's applied to the CRM (the new account and contact, the title, a task on the old account when it has an open deal) and counts as a source for re-activation | signals:write |
| POST | /v1/job-changes/:id/dismiss | Dismiss a job change (it won't be raised again from the same evidence) | signals:write |
| POST | /v1/job-changes/scan | Look for job changes in the background: bounces, synced mail that isn't private (new addresses, threads, signatures), CRM edits, and PDL for watched people when a key is set; then the re-activation pass. One pass per organization at a time; poll /v1/people-data/pass. | signals:write |
| GET | /v1/people-data/headcount | Filter accounts by a function's headcount and its change over a window (e.g. engineering, at least 20% growth over 90 days), with the figures, snapshot dates and source | prospecting:read |
| POST | /v1/people-data/import | Import previewed results into the CRM (an explicit action; audited). Each is deduplicated against existing contacts and accounts by email, LinkedIn and domain: a match is linked and only its empty fields are filled; a person's company is found or created. Importing twice does nothing the second time. | prospecting:write |
| GET | /v1/people-data/pass | The latest people-data pass (a scan, a re-activation pass or the daily one): queued, running, succeeded or failed | prospecting:read |
| POST | /v1/people-data/search | Search people or companies in the people and company database (PDL): by a description (compiled like the CRM search), the CRM search's facets, or a query (titles, seniorities, functions, industries, size, places, companies, technologies). Results are previews with each field's source and as-of date and any CRM match; nothing is imported. It runs in the request, so a page is at most 10 records (each record returned costs a credit); the same search within 7 days is free. Without a key: your CRM's matches and what's missing. | prospecting:write |
| GET | /v1/people-data/status | Whether the people and company database (PDL) is on for this organization, whose key it uses, today's credits and the daily cap, and what works without it | prospecting:read |
| GET | /v1/reactivations | Past customers' users, lost-deal contacts and engaged buyers found at a new company: why they're watched, the history, how the move was verified, the ICP check, and the drafted re-intro (if any) | signals:read |
| POST | /v1/reactivations/:id/dismiss | Dismiss a re-activation | signals:write |
| POST | /v1/reactivations/scan | Queue the re-activation pass over confirmed moves (verify, ICP check, alert the owner, draft a re-intro for approval); poll /v1/people-data/pass | signals:write |
| POST | /v1/records/:id/people-data/enrich | Look a contact (by email or LinkedIn) or account (by domain) up in the people and company database. A hit or a miss is kept 90 days (never billed twice). With apply, only its empty fields are filled (audited). | contacts:write |
Examples
GET /v1/accounts/$ID/headcount
An account's headcount by function: the latest snapshot per source (PDL estimate, or counted from your CRM's contacts: not complete), each quarter's snapshot and its change against the quarter before
curl -s "https://api.closefinch.com/v1/accounts/$ID/headcount" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/accounts/${id}/headcount`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/accounts/$ID/headcount/snapshot
Take this month's headcount snapshot now: counted from the CRM, and from PDL when a key is set (one company credit, cached about a month)
curl -s -X POST "https://api.closefinch.com/v1/accounts/$ID/headcount/snapshot" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/accounts/${id}/headcount/snapshot`, {
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/job-changes
Detected job changes (company change, title change, possible departure) with old and new values, each source's evidence and date, the confidence and whether a person needs to confirm it
curl -s "https://api.closefinch.com/v1/job-changes" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/job-changes`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/job-changes/$ID/confirm
Confirm a job change: it's applied to the CRM (the new account and contact, the title, a task on the old account when it has an open deal) and counts as a source for re-activation
curl -s -X POST "https://api.closefinch.com/v1/job-changes/$ID/confirm" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/job-changes/${id}/confirm`, {
method: "POST",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();POST /v1/job-changes/$ID/dismiss
Dismiss a job change (it won't be raised again from the same evidence)
curl -s -X POST "https://api.closefinch.com/v1/job-changes/$ID/dismiss" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/job-changes/${id}/dismiss`, {
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/job-changes/scan
Look for job changes in the background: bounces, synced mail that isn't private (new addresses, threads, signatures), CRM edits, and PDL for watched people when a key is set; then the re-activation pass. One pass per organization at a time; poll /v1/people-data/pass.
curl -s -X POST "https://api.closefinch.com/v1/job-changes/scan" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/job-changes/scan`, {
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/people-data/headcount
Filter accounts by a function's headcount and its change over a window (e.g. engineering, at least 20% growth over 90 days), with the figures, snapshot dates and source
curl -s "https://api.closefinch.com/v1/people-data/headcount" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/people-data/headcount`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/people-data/import
Import previewed results into the CRM (an explicit action; audited). Each is deduplicated against existing contacts and accounts by email, LinkedIn and domain: a match is linked and only its empty fields are filled; a person's company is found or created. Importing twice does nothing the second time.
curl -s -X POST "https://api.closefinch.com/v1/people-data/import" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/people-data/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();GET /v1/people-data/pass
The latest people-data pass (a scan, a re-activation pass or the daily one): queued, running, succeeded or failed
curl -s "https://api.closefinch.com/v1/people-data/pass" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/people-data/pass`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/people-data/search
Search people or companies in the people and company database (PDL): by a description (compiled like the CRM search), the CRM search's facets, or a query (titles, seniorities, functions, industries, size, places, companies, technologies). Results are previews with each field's source and as-of date and any CRM match; nothing is imported. It runs in the request, so a page is at most 10 records (each record returned costs a credit); the same search within 7 days is free. Without a key: your CRM's matches and what's missing.
curl -s -X POST "https://api.closefinch.com/v1/people-data/search" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/people-data/search`, {
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/people-data/status
Whether the people and company database (PDL) is on for this organization, whose key it uses, today's credits and the daily cap, and what works without it
curl -s "https://api.closefinch.com/v1/people-data/status" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/people-data/status`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();GET /v1/reactivations
Past customers' users, lost-deal contacts and engaged buyers found at a new company: why they're watched, the history, how the move was verified, the ICP check, and the drafted re-intro (if any)
curl -s "https://api.closefinch.com/v1/reactivations" \
-H "Authorization: Bearer $RA_API_KEY"const res = await fetch(`https://api.closefinch.com/v1/reactivations`, {
method: "GET",
headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
const data = await res.json();POST /v1/reactivations/$ID/dismiss
Dismiss a re-activation
curl -s -X POST "https://api.closefinch.com/v1/reactivations/$ID/dismiss" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/reactivations/${id}/dismiss`, {
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/reactivations/scan
Queue the re-activation pass over confirmed moves (verify, ICP check, alert the owner, draft a re-intro for approval); poll /v1/people-data/pass
curl -s -X POST "https://api.closefinch.com/v1/reactivations/scan" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/reactivations/scan`, {
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/records/$ID/people-data/enrich
Look a contact (by email or LinkedIn) or account (by domain) up in the people and company database. A hit or a miss is kept 90 days (never billed twice). With apply, only its empty fields are filled (audited).
curl -s -X POST "https://api.closefinch.com/v1/records/$ID/people-data/enrich" \
-H "Authorization: Bearer $RA_API_KEY" \
-H "content-type: application/json" \
-d '{}'const res = await fetch(`https://api.closefinch.com/v1/records/${id}/people-data/enrich`, {
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.