Swiftlee REST API
v1 · JSON over HTTPS · bearer auth · HMAC-signed outbound webhooks
Base URL
https://getswiftlee.com/api/v1
White-label operator subdomains (e.g. outdesk.getswiftlee.com) accept the same endpoints — API keys are still scoped to a specific company, not an operator.
Authentication
All endpoints require a bearer token. Get a key from Settings → API keys inside the Swiftlee portal. Keys look like sl_live_xxxxxxxxxxxxxxxxxxxxxxxxxxxx.
curl https://getswiftlee.com/api/v1/me \ -H "Authorization: Bearer sl_live_..."
The fallback header X-API-Key: sl_live_… also works for environments where Authorization headers are stripped by an upstream proxy.
Security: keys are shown ONCE on creation — we store only a SHA-256 hash. Lose it, revoke it, regenerate. Each key is scoped to a single company; cross-tenant access is impossible by construction.
Rate limits
100 requests per minute per key. 429 with Retry-After header on overage. If you need more, email support@getswiftlee.com.
Errors
Non-2xx responses share a stable shape:
{
"error": {
"code": "invalid_api_key",
"message": "API key not recognized."
}
}Common codes: missing_api_key (401), invalid_api_key (401), api_key_revoked (401), rate_limited (429), call_not_found (404), query_failed (500).
Endpoints
/v1/meAuth smoke test — returns the company the key belongs to.
{
"company": {
"id": "c0d4...",
"name": "Acme Co",
"slug": "acme-co",
"status": "active",
"created_at": "2026-01-12T09:00:00Z",
"operator_id": "00000000-0000-0000-0000-000000000001"
},
"plan": { "slug": "growth", "name": "Growth", "included_calls": 200 },
"api_version": "v1"
}/v1/callsList calls for the authed company, newest first. Cursor-paginated.
limit— 1–100, default 25cursor— ISO timestamp; returns calls with started_at strictly before thisdisposition— answered | missed | voicemail | overflow | transferred | ai_handled
{
"data": [
{
"id": "ab12...",
"caller_e164": "+13105551234",
"started_at": "2026-05-25T14:32:11Z",
"ended_at": "2026-05-25T14:34:55Z",
"disposition": "answered",
"summary": "Caller asking about roof replacement quote.",
"transcript": "Hi, this is...",
"recording_available": true
}
],
"has_more": true,
"next_cursor": "2026-05-25T14:32:11Z"
}/v1/calls/:idFull detail for one call. 404 if the call isn't in the authed company.
Webhooks
The richer integration pattern: subscribe to events at Settings → Webhooks and Swiftlee POSTs to your endpoint as events happen — no polling.
Event types: call.completed, call.qualified, call.disqualified, call.voicemail, call.no_answer, call.missed, message.captured, callback.queued, appointment.booked.
Signature: X-Swiftlee-Signature: t=<unix>,v1=<hex> — HMAC-SHA256 of ${t}.${rawBody} with your whsec_ signing secret. Reject if t is more than 5 minutes stale (replay defense).
// Node.js verification snippet
import crypto from "node:crypto";
function verifySwiftleeSignature(rawBody, header, secret) {
const parts = Object.fromEntries(
header.split(",").map((p) => p.split("=")),
);
const t = parts.t;
const v1 = parts.v1;
if (!t || !v1) return false;
const age = Math.floor(Date.now() / 1000) - Number(t);
if (age > 300 || age < -60) return false; // replay window
const expected = crypto
.createHmac("sha256", secret)
.update(`${t}.${rawBody}`)
.digest("hex");
return crypto.timingSafeEqual(
Buffer.from(expected, "hex"),
Buffer.from(v1, "hex"),
);
}Coming soon
POST /v1/messages— manually capture a messagePOST /v1/webhooks+ DELETE — programmatic subscription management- Test-mode keys (
sl_test_*) that don't mutate production data - Outbound dialing API + campaigns (
POST /v1/calls/outbound) — requires TCPA compliance review before launch
Need something not listed? Email support@getswiftlee.com— we'll prioritize based on partner demand.