Endpoints
Method | Path | Description |
|---|---|---|
POST |
| Create a new person |
GET |
| Get a person by ID |
GET |
| List people |
PATCH |
| Update a person |
DELETE |
| Delete a person |
POST |
| Search people by name |
Create a Person
POST /rest/people
Required Fields
Field | Type | Description |
|---|---|---|
| string | First name |
Optional Fields
Field | Type | Description |
|---|---|---|
| string | Last name |
| string | Primary email address |
| string[] | Additional email addresses |
| string | Phone number (without country code) |
| string | Two-letter country code (e.g., |
| string | Calling code with |
| string | LinkedIn profile URL |
| string | Display label for the link |
| string | X (Twitter) profile URL |
| string | Display label for X |
| string | URL to avatar image |
| string | Job title or position |
| string | City of residence or work |
| UUID | Associated company ID |
| UUID | Record owner (workspace member ID) |
Request Example
Get a Person
Parameter | Type | Default | Description |
|---|---|---|---|
| UUID (path) | — | Person ID |
| number | 0 |
|
List People
Parameter | Type | Default | Description |
|---|---|---|---|
| number | 60 | Records per page |
| UUID | — | Pagination cursor (last record's ID) |
| string | — | Sort field and direction |
| string | — | Filter conditions |
| number | 0 | Related objects depth |
Update a Person
Send only the fields you want to change — omitted fields are left unchanged.
Delete a Person
Search People
People can be searched by name (via GraphQL), or by email, LinkedIn URL, or phone (via REST filter).
By Name — GraphQL + REST (Two Steps)
GraphQL full-text search returns record IDs only. You must follow up with a REST request to get full records.
Step 1: GraphQL search → get IDs
GraphQL caveats:
searchInputmust be a plainString!variable — do NOT pass it as{query: "...", includedObjectNameSingulars: [...]}(causes a type error)
limitmust be hardcoded in the query string, not passed as a$limitvariable (causes a type error)Do not use inline fragments like
... on PersonSearchResult— thesearchquery returns a unified structure; accessrecordId,label, etc. directly onnode
Step 2: Fetch full records
By Email — REST Filter
By LinkedIn URL — REST Filter
By Phone Number — REST Filter
Phone numbers are stored split: the calling code (+1) and the number (5551234567) are separate fields. Filter both for precise matching:
Filter Examples
Common Gotchas
Name is a nested object. Use
{ "name": { "firstName": "John" } }, not"firstName": "John"at the top level. Sending a flatfirstNamefield will be ignored.Link fields require the full structure. LinkedIn, X, and other link fields need
{ primaryLinkUrl, primaryLinkLabel, secondaryLinks: [] }. Sending just a URL string won't work.Phone search requires splitting the number. When given a number like
+15551234567, split it into calling code+1and number5551234567for the filter.Email filter uses a nested path. Use
emails.primaryEmail[ilike]:value, notprimaryEmail[ilike]:value.GraphQL search returns IDs only. Always follow up with
GET /rest/people?filter=id[in]:[id1,id2]to get full records.id[in]requires bracket syntax. Useid[in]:[uuid1,uuid2]— notid[in]:uuid1,uuid2. The brackets are required or you'll get a 500 error.URL-encode filter parameters. Filter strings contain
[,],:that break raw URLs. Usecurl -G --data-urlencode "filter=..."or equivalent in your HTTP library.depth=1list responses are large. A singledepth=1list call can return ~42KB+ per page. If you need depth on specific records, prefer fetching them individually viaGET /rest/people/{id}?depth=1.