OpenAPI reference · CRM sync
List the people CRM sync sends
/crm-peopleThe workspace's engagers whose Fit is at or above minFit, newest
engagement first — each one as the CRM sync payload, the same
object the signed CRM sync webhook delivers. person.id is the
stable key to upsert on; it is opaque and never a LinkedIn id.
People are judged when you pull, as they are when they are sent:
someone who objected to Scripe processing their data, someone the
workspace hid or excluded, and someone whose name Scripe cannot
refresh right now are left out. A page can therefore hold fewer
people than limit; keep paging while pagination.has_more is
true. Pass the time of your previous poll as since to read only
the people who engaged after it.
OAuth only. An API key is answered 403 scope_missing: CRM
sync is offered per person, so the request is judged as the person
the token acts for. That person must be a workspace admin
(403 admin_required otherwise) in a workspace where CRM sync is
available to them (404 not_found otherwise), on a plan that
includes it (403 plan_not_eligible otherwise). Every pull is
recorded in the workspace's Signals audit log.
Required scope: people:read. It is never part of the read or
write alias, so request it by name.
Authorization
AuthorizationstringrequiredBearer token in the Authorization header.
Pass
Authorization: Bearer scripe_sk_live_<...>(orscripe_sk_test_<...>for test keys) on every request. Keys are scoped to a single workspace and can be revoked from the Scripe dashboard.The same header also accepts an OAuth 2.1 access token (
scripe_oat_*); both credentials share one scope vocabulary and every operation below documents the scope it requires. An API key can hold every scope named on this surface exceptwebhooks:manage, which is grantable to OAuth tokens only today — the webhook-endpoint operations answer403 scope_missingto every API key. Operations that name no scope accept any valid token of the workspace.
Query parameters
cursorstringOpaque pagination cursor returned by the previous page.
limitintegerPage size. Default 50, max 100. Values above the max are clamped silently; only a non-integer or a value below 1 is rejected with
bad_pagination.Default: 50
minFitnumberOnly people whose Fit is at or above this score (1 to 5). The same default as CRM sync's automatic rule.
Default: 3.5
sincestring <date-time>ISO 8601 time: only people whose last engagement is at or after it. Use the time of your previous poll.
Header parameters
Scripe-Api-VersionstringPin the API version. Format
YYYY-MM-DD. Omit to receive the currently rolling default. Unknown versions return400 version_unsupported.
Responses
- 200
One page of people.
- 400
Malformed request (bad cursor, bad limit, etc.).
- 401
Missing, malformed, expired, or revoked API key.
- 403
Plan not eligible, scope missing, or workspace mismatch.
- 404
Resource not found in this workspace.
- 429
Sliding-window rate limit exceeded.
- 503
The pull could not be recorded in the audit log, so nothing was sent. Retry.
Example request
curl --request GET \
--url 'https://api.scripe.io/v1/crm-people' \
--header 'Authorization: Bearer <token>'Example response (200)
{
"data": [
{
"id": "string",
"type": "person.qualified",
"provenance": "LINKEDIN_ENGAGER",
"person": {
"id": "string",
"firstName": "string",
"lastName": "string",
"fullName": "string",
"headline": "string",
"title": "string",
"linkedinUrl": "string",
"email": null
},
"company": {
"id": "string",
"name": "string",
"domain": "string",
"linkedinUrl": "string",
"industry": "string",
"size": "1-10",
"fit": 0,
"peopleEngaged": 0
},
"fit": {
"score": 0,
"band": "STRICT",
"label": "string",
"person": 0,
"company": 0,
"reasons": [
"string"
]
},
"signal": {
"strength": 0,
"intent": "BUYING_SIGNAL"
},
"engagements": {
"count": 0,
"comments": 0,
"reactions": 0,
"reposts": 0,
"mentions": 0,
"firstAt": "2026-08-10T09:00:00Z",
"lastAt": "2026-08-10T09:00:00Z",
"profiles": [
"string"
],
"lastPostUrl": "string",
"latest": {
"kind": "COMMENT",
"excerpt": "string",
"postTitle": "string",
"postUrl": "string",
"at": "2026-08-10T09:00:00Z"
}
},
"source": "Engager",
"url": "string",
"occurredAt": "2026-08-10T09:00:00Z"
}
],
"pagination": {
"next_cursor": "string",
"has_more": true
}
}