Skip to content

API reference

API: Deals

Markdown version

MethodPathWhat it doesScope
GET/v1/dealsList deals (filters: q, owner_id, list_id, linked_to, dismissed, filter[field]=value, filter[field][gte|lte|gt|lt|in|exists]=value)deals:read
POST/v1/dealsCreate a dealdeals:write
DELETE/v1/deals/:idArchive a record (restore with POST …/restore)deals:write
GET/v1/deals/:idGet a record (as_of=ISO time for its values at that moment). A merged record answers 301 with the survivor's id.deals:read
PATCH/v1/deals/:idUpdate values or owner. A merged record answers 410. Pass version for optimistic concurrency.deals:write
POST/v1/deals/:id/dismissDismiss a noise record so it stops resurfacing (undo with dismissed: false)deals:write
GET/v1/deals/:id/historyEvery change to this record, newest first, with field-level before and after. Values that came from an item now private (or metadata-only) to someone else show as null with redacted: true.deals:read
POST/v1/deals/:id/mergeMerge other records into this one. They redirect here afterwards.deals:write
GET/v1/deals/:id/provenanceWhere each current value came from (user, API, import, activity, agent or sync). link points at the activity, import row or record behind it.deals:read
POST/v1/deals/:id/restoreRestore an archived recorddeals:write
GET/v1/deals/:id/timelineActivity about this record, newest first (deleted-at-source items hidden)activities:read
POST/v1/deals/analyze-writeBefore creating or updating: does this record already exist? Returns create, update (with the record to update) or review, with every match (same email, domain, phone, LinkedIn, same or similar name), rows of a batch that repeat each other, and for updates the values that would be overwritten. Agents' creates run this check and are refused when the record exists.deals:read
POST/v1/deals/bulkCreate up to 25 records. Each row_key (yours alone) is idempotent: the same key and data replays the record it created; the same key with different data is a conflict.deals:write
POST/v1/deals/dismissDismiss (or undo with dismissed: false) many noise records at oncedeals:write
POST/v1/deals/duplicatesCheck for existing records before creating or updating (same email, domain, phone, LinkedIn or name)deals:read
GET/v1/deals/possible-duplicatesGroups of records that look like the same thing (shared email, domain, phone, LinkedIn or exact name), to review and mergedeals:read
GET/v1/deals/schemaJSON Schemas for create and update bodies, including this organization's custom fieldsdeals:read

Examples

GET /v1/deals

List deals (filters: q, owner_id, list_id, linked_to, dismissed, filter[field]=value, filter[field][gte|lte|gt|lt|in|exists]=value)

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

POST /v1/deals

Create a deal

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

Archive a record (restore with POST …/restore)

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

GET /v1/deals/$ID

Get a record (as_of=ISO time for its values at that moment). A merged record answers 301 with the survivor's id.

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

PATCH /v1/deals/$ID

Update values or owner. A merged record answers 410. Pass version for optimistic concurrency.

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

Dismiss a noise record so it stops resurfacing (undo with dismissed: false)

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

GET /v1/deals/$ID/history

Every change to this record, newest first, with field-level before and after. Values that came from an item now private (or metadata-only) to someone else show as null with redacted: true.

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

POST /v1/deals/$ID/merge

Merge other records into this one. They redirect here afterwards.

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

Where each current value came from (user, API, import, activity, agent or sync). link points at the activity, import row or record behind it.

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

POST /v1/deals/$ID/restore

Restore an archived record

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

Activity about this record, newest first (deleted-at-source items hidden)

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

POST /v1/deals/analyze-write

Before creating or updating: does this record already exist? Returns create, update (with the record to update) or review, with every match (same email, domain, phone, LinkedIn, same or similar name), rows of a batch that repeat each other, and for updates the values that would be overwritten. Agents' creates run this check and are refused when the record exists.

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

Create up to 25 records. Each row_key (yours alone) is idempotent: the same key and data replays the record it created; the same key with different data is a conflict.

curl -s -X POST "https://api.closefinch.com/v1/deals/bulk" \
  -H "Authorization: Bearer $RA_API_KEY" \
  -H "content-type: application/json" \
  -d '{}'
const res = await fetch(`https://api.closefinch.com/v1/deals/bulk`, {
  method: "POST",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}`, "content-type": "application/json" },
  body: JSON.stringify({}), // fields: see the OpenAPI schema
});
const data = await res.json();

POST /v1/deals/dismiss

Dismiss (or undo with dismissed: false) many noise records at once

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

Check for existing records before creating or updating (same email, domain, phone, LinkedIn or name)

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

Groups of records that look like the same thing (shared email, domain, phone, LinkedIn or exact name), to review and merge

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

GET /v1/deals/schema

JSON Schemas for create and update bodies, including this organization's custom fields

curl -s "https://api.closefinch.com/v1/deals/schema" \
  -H "Authorization: Bearer $RA_API_KEY"
const res = await fetch(`https://api.closefinch.com/v1/deals/schema`, {
  method: "GET",
  headers: { authorization: `Bearer ${process.env.RA_API_KEY}` },
});
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.