Enrich your dashboard with an API lookup
For developers. Your internal dashboard shows a client record — this recipe adds a live "what have they connected?" panel by calling the ClientInvite API with the ID you already have.
The pattern
- When you send a client their connect link, append your own ID:
?ref=crm-record-8841. See how customRef works. - From then on,
GET /clients/{id}accepts that ref directly — no need to store ClientInvite's internal ID.
The call
curl
curl https://app.clientinvite.com/api/v1/clients/crm-record-8841 \
-H "Authorization: Bearer ci_live_xxxxxxxxxxxx"Response
{
"error": false,
"data": {
"id": "9c2d7f14-6b3e-4a8f-b1d2-7e5c0a9f3b21",
"name": "Acme Co",
"email": "hello@acme.com",
"customRef": "crm-record-8841",
"status": "completed",
"assetCount": 3,
"createdAt": "2026-07-13T09:38:02.000Z",
"lastConnectedAt": "2026-07-13T09:41:25.000Z",
"connectedAt": "2026-07-13T09:41:25.000Z",
"clientSummaryUrl": "https://app.clientinvite.com/clients",
"assets": [
{
"platform": "facebook",
"type": "facebook_ads",
"name": "Acme Co",
"externalId": "act_1086344871362999",
"permission": "admin",
"status": "GRANTED"
},
{
"platform": "facebook",
"type": "facebook_page",
"name": "Acme Co",
"externalId": "104217693118841",
"permission": "admin",
"status": "GRANTED"
},
{
"platform": "google",
"type": "google_ads",
"name": "acme.com",
"externalId": "7342018841",
"permission": "admin",
"status": "GRANTED"
}
],
"customRefs": [
"crm-record-8841"
],
"requestId": "5b0f3c8e-2d1a-4c7e-9a61-3f2e8d4b7c10",
"requestName": "Onboarding - Meta & Google",
"requestUrl": "https://app.clientinvite.com/workspace/acme-agency/onboarding",
"connectionAssets": [
{
"id": "act_1086344871362999",
"name": "Acme Co",
"type": "Meta ads",
"platform": "Meta",
"connectionStatus": "Connected",
"accessLevel": "admin",
"time": "2026-07-13T09:40:51.000Z",
"linkToAsset": null
},
{
"id": "104217693118841",
"name": "Acme Co",
"type": "Facebook page",
"platform": "Meta",
"connectionStatus": "Connected",
"accessLevel": "admin",
"time": "2026-07-13T09:40:12.000Z",
"linkToAsset": null
},
{
"id": "7342018841",
"name": "acme.com",
"type": "Google ads",
"platform": "Google",
"connectionStatus": "Connected",
"accessLevel": "admin",
"time": "2026-07-13T09:41:25.000Z",
"linkToAsset": null
}
]
}
}Node.js
// lookup.js — run with: CLIENTINVITE_API_KEY=ci_live_xxxxxxxxxxxx node lookup.js
const CRM_RECORD_ID = 'crm-record-8841';
async function getClientAccess(customRef) {
const res = await fetch(
`https://app.clientinvite.com/api/v1/clients/${encodeURIComponent(customRef)}`,
{ headers: { Authorization: `Bearer ${process.env.CLIENTINVITE_API_KEY}` } }
);
if (res.status === 404) return null; // not connected yet
if (!res.ok) throw new Error(`ClientInvite API: ${res.status}`);
const { data } = await res.json();
return data;
}
const client = await getClientAccess(CRM_RECORD_ID);
if (client) {
const connected = client.connectionAssets.filter((asset) => asset.connectionStatus === 'Connected');
console.log(`${client.name}: ${connected.length} of ${client.connectionAssets.length} assets connected`);
} else {
console.log('Client has not completed the connect flow yet.');
}Server-side only
Call the API from your backend, never from browser code — your key would be visible to anyone who opens dev tools. See authentication.
Notes
- A
404means no client has used a link with that ref yet — treat it as "not started", not an error. A client who started but hasn't finished comes back with"status": "pending". - The API is rate-limited to 60 requests/minute per key — cache responses if you render them on every page load.
- If you want the data pushed to you the moment it changes instead, use webhooks — most teams use both: webhook to ingest, API to re-fetch on demand.