API Reference
A small, read-only REST API for looking up your clients and their connections. If you want ClientInvite to push data to you instead, use webhooks.
Authentication
Create an API key in Settings → API & Webhooks. The key is shown once — store it somewhere safe. Send it on every request:
Authorization: Bearer ci_live_xxxxxxxxxxxxKeep your key server-side
Never expose your API key in client-side code, mobile apps, or public repos. Anyone with the key can read your client list. There is no OAuth — the key is the whole credential.
The API is available on the Agency plan. Requests from Freelancer-plan workspaces return 403.
Base URL, versioning & responses
https://app.clientinvite.com/api/v1The version is in the path (/v1). Breaking changes will only ever ship under a new version. Every response uses the same envelope:
{ "error": false, "data": ... }{
"error": true,
"code": "plan_required",
"msg": "The API is available on the Agency plan. Upgrade in Settings → Billing."
}| Field | Type | Description |
|---|---|---|
| 200 | status | Success. |
| 400 bad_request | status + code | Malformed parameter — the msg says which. |
| 401 unauthorized | status + code | Missing or invalid API key. |
| 403 plan_required | status + code | Your workspace is not on the Agency plan. |
| 404 not_found | status + code | No client matches that ID or ref. |
| 429 rate_limited | status + code | Over the rate limit — back off and retry. |
Rate limit: 60 requests per minute per key. v1 is read-only — there are no write endpoints yet (see the changelog for what's planned).
GET /me
Verify your key and see which workspace it belongs to.
curl https://app.clientinvite.com/api/v1/me \
-H "Authorization: Bearer ci_live_xxxxxxxxxxxx"{
"error": false,
"data": {
"agencyName": "Acme Agency",
"plan": "agency",
"keyCreatedAt": "2026-07-01T08:12:04Z"
}
}GET /clients
List your clients, most recent first.
| Field | Type | Description |
|---|---|---|
| ref | string | Filter to the client tagged with this customRef. |
| string | Filter by the email the client entered in the connect flow. | |
| status | string | Filter by connection status, e.g. CONNECTED. |
| limit | integer | Page size, 1–100. Default 25. |
| cursor | string | Pagination cursor from a previous response. |
| sort | string | "connectedAt" (default) or "name". Prefix with - to reverse. |
curl "https://app.clientinvite.com/api/v1/clients?limit=25" \
-H "Authorization: Bearer ci_live_xxxxxxxxxxxx"{
"error": false,
"data": {
"items": [
{
"id": "cl_7d81mq",
"name": "Acme Co",
"email": "hello@acme.com",
"customRef": "crm-record-8841",
"status": "CONNECTED",
"connectedAt": "2026-07-13T09:41:25Z",
"assetCount": 4
}
],
"nextCursor": "eyJpZCI6ImNsXzdkODFtcSJ9"
}
}Pagination: when more results exist, the response includes nextCursor. Pass it back as ?cursor= to get the next page; nextCursor is null on the last page.
GET /clients/{id}
Fetch one client with their full asset list. {id} accepts either the internal ID (cl_...) or your own customRef — so you can go straight from a CRM record to a lookup:
curl https://app.clientinvite.com/api/v1/clients/crm-record-8841 \
-H "Authorization: Bearer ci_live_xxxxxxxxxxxx"{
"error": false,
"data": {
"id": "cl_7d81mq",
"name": "Acme Co",
"email": "hello@acme.com",
"customRef": "crm-record-8841",
"status": "CONNECTED",
"connectedAt": "2026-07-13T09:41:25Z",
"assets": [
{
"platform": "facebook",
"type": "ad_account",
"name": "Acme Co",
"externalId": "act_1086344871362999",
"permission": "manage",
"status": "GRANTED"
},
{
"platform": "google",
"type": "ads_account",
"name": "acme.com",
"externalId": "734-201-8841",
"permission": "manage",
"status": "GRANTED"
}
]
}
}