Skip to content
Open app

Sync contacts

Contacts are the core CRM record in CRM Solid. This guide walks through creating a contact and then listing and searching your contacts via the Public API.

All requests go to the base URL https://api.crmsolid.com and must include your API key as a bearer token. If you haven’t set that up yet, start with the Quickstart and Authentication guides.

Send a POST to /v1/contacts. At least one of name, username, or phone must be provided. platform defaults to telegram if you omit it.

  1. Build the request body. Only the fields you want to set are required — everything is optional as long as one identifier is present.

    FieldTypeNotes
    platformstringtelegram (default) or twitter.
    namestringDisplay name.
    usernamestringHandle with or without a leading @ — the @ is stripped server-side.
    phonestringPhone number in any format.
    notesstringFree-text notes attached to the contact.
  2. Send the request.

    Terminal window
    curl -X POST https://api.crmsolid.com/v1/contacts \
    -H "Authorization: Bearer csk_live_..." \
    -H "Content-Type: application/json" \
    -d '{
    "platform": "telegram",
    "name": "Acme Inc.",
    "username": "john_doe",
    "notes": "Met at conference"
    }'
  3. Read the response. A successful create returns 201 Created with the full contact record:

    {
    "id": 101,
    "platform": "telegram",
    "name": "Acme Inc.",
    "username": "john_doe",
    "phone": null,
    "email": null,
    "company": null,
    "notes": "Met at conference",
    "stage": "Lead",
    "leadScore": null,
    "leadScoreIsAi": false,
    "assignedToUserId": null,
    "createdAt": "2024-03-01T10:00:00Z",
    "lastMessageAt": null,
    "hasUnreadMessages": false
    }

Send a GET to /v1/contacts. The endpoint is cursor-paginated: each page returns a nextCursor that you pass back as after to fetch the next page.

ParamTypeNotes
afterintegerCursor — returns contacts with an id strictly less than this value. Omit for the first page.
limitintegerPage size, clamped to 1–100. Defaults to 25.
platformstringFilter by telegram or twitter.
qstringCase-insensitive substring search across name, username, and phone.
Terminal window
curl "https://api.crmsolid.com/v1/contacts?limit=10&q=acme" \
-H "Authorization: Bearer csk_live_..."

The response is a paginated list. nextCursor is null when hasMore is false:

{
"items": [
{
"id": 101,
"platform": "telegram",
"name": "Acme Inc.",
"username": "john_doe",
"phone": null,
"notes": null,
"stage": "Lead",
"createdAt": "2024-03-01T10:00:00Z",
"lastMessageAt": null,
"hasUnreadMessages": false
}
],
"nextCursor": 101,
"hasMore": false
}

Keep requesting with after=nextCursor until hasMore is false:

let after;
const all = [];
do {
const params = new URLSearchParams({ limit: "100" });
if (after) params.set("after", String(after));
const res = await fetch(
`https://api.crmsolid.com/v1/contacts?${params}`,
{ headers: { Authorization: "Bearer csk_live_..." } },
);
const page = await res.json();
all.push(...page.items);
after = page.nextCursor;
} while (after != null);

To read one contact by id, GET /v1/contacts/{id}. This response also includes the contact’s tags array, which is omitted from list responses. A 404 is returned if the contact doesn’t exist or belongs to another workspace.

Terminal window
curl https://api.crmsolid.com/v1/contacts/101 \
-H "Authorization: Bearer csk_live_..."