Docs · API
REST API reference.
Every endpoint, every request/response, every auth requirement. Base URL https://callfunnel.ai/api (or wherever your tenant is hosted).
Your first request, in 60 seconds
If you've used Twilio or Anthropic before, this will feel identical. Three steps:
- Open /api-keys in your dashboard and mint a key. Copy the full
cf_live_…secret — it's shown once. - Pick any endpoint below. Send
Authorization: Bearer cf_live_…on every call. - Read the response. Errors are JSON with a
detailfield; HTTP status codes follow REST conventions.
Here's the smallest working call (reads your workspace's wallet balance — safe to run anytime):
cURL
Python (requests)
Node (fetch)
Expected response
Explore interactively
The API ships with auto-generated interactive docs. Useful when you want to try a call without leaving the browser, or when you want to import the schema into Postman/Insomnia.
- Swagger UI (try-it-out playground) — /api/docs
- ReDoc (cleaner reading layout) — /api/redoc
- OpenAPI JSON (import into Postman, Insomnia, codegen) — /api/openapi.json
Authentication
Three ways to authenticate. Server-to-server integrations should use API keys; browser apps use the session cookie.
- API key —
Authorization: Bearer cf_live_…. Created in your dashboard; identifies the workspace, not an individual user. Recommended for all programmatic access. - Cookie —
cf_session, HttpOnly + Secure (set byPOST /auth/login). Browser apps use this. - JWT bearer —
Authorization: Bearer <jwt>. Returned in the login response body. Use this for short-lived per-user sessions in non-browser clients.
JWT TTL: 7 days. Algorithm: HS256. Claims include sub, tid
(tenant), role, email, iat, exp.
API keys carry one of three scopes:
read— GET-only endpoints (balance, history, list resources, status).write— read + state-changing POST/PUT (top-ups, autocharge, provision numbers, credential updates).admin— write + destructive actions (release a number, delete provider credentials, DSR erase).
Keys are shown once when created and stored as a sha256 lookup on our side — we cannot recover a lost key. Optional expiry (days/months/never), revocable any time, audit-trailed.
Endpoints marked JWT below also accept an API key with the appropriate scope; endpoints marked JWT only require a logged-in user (account self-management) and reject API keys by design.
Auth
Create a new tenant + owner user. Sends verify-email best-effort. Auto-credits trial ($5 / ₹450).
Idempotent. Token TTL 24h.
Sets cf_session cookie + returns bearer token.
Clears the session cookie.
Current user + tenant.
API keys
Manage programmatic keys for your workspace. These routes require a logged-in user (cookie or JWT) — an API key cannot manage other API keys.
List every key in the workspace (active, expired, revoked). Secret values are never returned.
Mint a new key. The full secret is returned in this response and only this response — copy it before navigating away. Maximum 10 active keys per workspace.
Flip revoked_at on the key. Subsequent calls using it get 401 immediately. Idempotent — revoking an already-revoked key is a no-op.
Hard-delete a key row (removes audit trail). Only allowed after revoke — call /revoke first or you get 409.
Workflows
A workflow is one campaign — a rule-book (NL prompt + Opus-generated script), an audience CSV, and a schedule. Lifecycle: draft → live ↔ paused → retired. Workflows are the core resource you'll create with the API.
List your workspace's workflows. Filter by status with ?status=draft|live|paused|retired.
Full workflow detail including the rule book.
Create a workflow from a natural-language prompt. We send the prompt to Claude Opus, validate the generated rule book, and persist it. Failures return 422 with the validator errors so you can edit + retry.
Update name, persona, schedule, or rule-book fields. Returns 409 if the workflow is currently live — pause it first to edit.
Attach an audience by uploading a CSV (multipart) or posting a JSON list. Phone numbers are normalised to E.164 and filtered against your DNC list + NCPR (India) + 7-day cool-down.
Start a run — kicks off the dialer for this workflow. Pre-call billing precheck applies (insufficient funds → 402).
Pause the dialer. In-flight calls finish; queued targets stop. Resumable by calling /run again.
Terminal state — workflow can't be un-retired. Refuses if any run is currently running (pause first).
Re-run the Opus generator against the workflow's nl_prompt (or a new prompt in the body). Useful when you've edited the prompt or you want a fresh generation. Returns 422 if the regenerated rule book fails validation.
Soft-delete — sets status=retired + archived_at. Refuses if any run is currently running.
Last N runs for this workflow, newest first.
Stateless TTS preview — send a script line + persona, get back an MP3 URL. Useful to hear an opener before creating the workflow.
Approvals
When the AI proposes something material — a discount, a refund waiver, a callback handoff — it routes to your Slack (or appears here) for a human decision. The approvals queue + decide endpoint are the API equivalent.
Pending approvals queue for your workspace. Filter by ?workflow_id= or ?status=pending|approved|denied.
Approve or deny a pending decision. Same endpoint Slack interactivity hits — record the outcome and resume the AI's conversation.
Customer timeline
Cross-channel narrative for one contact — calls, WA messages, email touches, decisions. Identify the contact by phone, email, or user_id. Limit defaults to 50, max 500.
Compliance & DNC
Your tenant's do-not-call list. Audience uploads automatically filter against this; you can also pre-check a number before dialling manually.
List DNC entries. Paginated with ?limit=100&offset=0.
Add a number to DNC. Idempotent — re-adding refreshes the timestamp + reason.
Remove a number from DNC. URL-encode the leading +.
Test a number against DNC + NCPR (India) + 7-day cool-down without committing a call.
Bulk-import a DNC list. Accepts a CSV upload (multipart) or a JSON array.
Attest consent for a workflow (TCPA / DPDP / GDPR). The attestation records the logged-in user as consent_attested_by_user_id — that's why API keys are rejected here; the audit trail needs a human identity.
Reports & shared library
PDF digest for a date range — workflow KPIs, approval volume, top objections, cost breakdown.
Global shared library of seeded objections + suggested rebuttals. Read-only catalog, not tenant-scoped — useful when authoring custom rule books outside the wizard.
Onboarding
Catalogue of supported providers + field schemas (Anthropic, Twilio, Exotel, Cartesia, Deepgram).
Current onboarding mode, validation state per provider, completion checklist.
Switch between bundled and byok. Saved keys stay; just go dormant.
Save + live-validate a provider credential. AES-256-GCM encrypted at rest. Returns 503 if MEK is not set.
Remove a credential. Tenant onboarding flips back to incomplete.
Mark onboarding done. 409 if not ready (lists missing fields).
Billing
Wallet balance, per-minute rate, minutes remaining, autocharge config.
Pre-call gate. Returns ok / insufficient_funds / trial_expired / account_suspended.
Immutable wallet ledger. Max 200 entries per call.
Create a top-up checkout intent. Wallet credits on webhook confirmation, not on intent creation.
Configure auto-recharge.
Payment-processor webhook. HMAC-SHA256 signature verified, idempotent on event id.
Numbers
List tenant numbers (provisioned + imported).
Search available inventory.
Buy a number. Webhooks (voice inbound + status callback) auto-configured.
Import an existing number (you must own it on the provider side).
Release a number. Webhooks unwired. Monthly recurring stops.
Health & public
Service health + provider config status.
Available personas (6 EN + 1 HI) with sample MP3 URLs.
DPDP / DSR
Export everything for a contact. Returns under 30s.
Erase everything for a contact. Audit-keep rows pseudonymised.
Error format
All errors return JSON:
HTTP statuses follow the obvious mapping: 400 bad request, 401 auth required, 403 forbidden, 404 not found, 409 conflict, 422 validation, 429 rate-limited, 5xx server.
Rate limits
Per-tenant rate limits are not enforced yet in the public beta. Be reasonable — sustained > 10 req/sec from a single workspace will eventually trip an automated alarm. When we activate enforcement we'll publish concrete per-endpoint thresholds and emit X-RateLimit-Limit, X-RateLimit-Remaining, and Retry-After headers on 429 responses. If you have a known burst pattern that needs higher headroom, email hello@callfunnel.ai ahead of time.
Versioning
The API is unversioned today (pre-1.0). Breaking changes are announced 60 days ahead via
a banner in the dashboard and an email to admin users. Post-launch we'll add a
/v1/ prefix; current callers stay on the unprefixed path through a sunset window.