Developer docs: Quickstart
Quickstart
From a new key to reading calls and placing one, in five steps. Every sample is complete: set BOOKIFYCALL_API_KEY in your environment and run it.
1. Get a key
In Settings → API keys, create a key named after your system. For this guide give it calls:read and calls:write (about keys and scopes). The API is part of the Enterprise plan; talk to sales if you are on another one.
2. Check the key
GET /me answers with your organization, plan and the key's scopes. If it works, everything else will.
curl "https://bookifycall.com/api/v1/external/me" \
-H "X-API-Key: $BOOKIFYCALL_API_KEY"3. List recent calls
Lists are newest first and paginated (page, limit up to 100). Filter by direction, status, agentId or a date range (all filters).
curl "https://bookifycall.com/api/v1/external/calls-history" \
-H "X-API-Key: $BOOKIFYCALL_API_KEY"4. Read one call
A call's detail adds the full transcript, the structured AI analysis (summary, outcome, intent, sentiment, caller details, follow-up), the lead it created and the appointment it booked. Audio is separate: GET /calls-history/:id/recording returns a signed link valid for up to an hour (scope recordings:read).
curl "https://bookifycall.com/api/v1/external/calls-history/00000000-0000-4000-8000-000000000001" \
-H "X-API-Key: $BOOKIFYCALL_API_KEY"{
"success": true,
"data": {
"id": "00000000-0000-4000-8000-000000000001",
"callType": "inbound",
"callStatus": "completed",
"duration": 250,
"hasRecording": true,
"analysis": {
"ready": true,
"summary": "Caller asked about pricing and booked a demo for Tuesday.",
"outcome": "appointment_booked",
"intent": "book_demo",
"intentDescription": "Wants a product demo",
"sentiment": "positive",
"satisfactionScore": 4,
"topics": [
"pricing"
],
"keyPoints": [
"Team of 12",
"Wants a demo"
],
"followUp": {
"needed": true,
"suggestedAction": "Send pricing sheet",
"dueHint": "before the demo"
},
"caller": {
"name": "Jane Doe",
"company": "Example Dental",
"email": "jane@example.com",
"callbackNumber": "+15551230001"
},
"leadId": "00000000-0000-4000-8000-000000000003",
"analyzedAt": "2026-01-15T16:34:30.000Z"
},
"appointmentId": "00000000-0000-4000-8000-000000000004",
"transcript": [
{
"timestamp": "2026-01-15T16:30:00.000Z",
"speaker": "agent",
"message": "Thanks for calling Example Dental, how can I help?"
},
{
"timestamp": "2026-01-15T16:30:05.000Z",
"speaker": "user",
"message": "I would like to book a demo."
}
]
}
}5. Keep your system in sync
Poll with updatedSince, ordered by updatedAt ascending, and store the last updatedAt you saw as your cursor. Calls change after they end (the AI analysis lands seconds later), so sync on updatedAt, not on creation time. Leads, appointments and scheduled calls take the same parameters.
// Pull every call changed since the last run, oldest change first.
const BASE = 'https://bookifycall.com/api/v1/external';
let cursor = await loadCursor(); // e.g. '2026-10-01T00:00:00Z', stored by your app
for (let page = 1; ; page++) {
const url = `${BASE}/calls-history?updatedSince=${encodeURIComponent(cursor)}` +
`&sort=updatedAt&order=asc&limit=100&page=${page}`;
const res = await fetch(url, { headers: { 'X-API-Key': process.env.BOOKIFYCALL_API_KEY } });
if (res.status === 429) {
await new Promise((r) => setTimeout(r, Number(res.headers.get('Retry-After') ?? 60) * 1000));
page--; // retry the same page
continue;
}
const { data, pagination } = await res.json();
for (const call of data) await upsertCall(call); // idempotent on call.id
if (data.length) await saveCursor(data.at(-1).updatedAt);
if (page >= pagination.pages) break;
}6. Place a call
With calls:write, ask an agent to call someone now. Send an Idempotency-Key so a retried request never places a second call (how it works).
curl -X POST "https://bookifycall.com/api/v1/external/calls/outbound" \
-H "X-API-Key: $BOOKIFYCALL_API_KEY" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{"agentId":"00000000-0000-4000-8000-000000000002","phoneNumber":"+15551230001","name":"Jane Doe","company":"Example Dental","callIntent":"Confirm Thursday appointment","notes":"Prefers mornings"}'