Overview & conventions
API overview & conventions
The Telenow REST API lets you do everything the dashboard does — manage agents, place calls, stream events, run chats, and more. This page covers the conventions that apply to every endpoint.
Base URL
https://api.telenow.ai
All endpoints are prefixed with /api (e.g. GET /api/agents). On white‑label/self‑hosted deployments, substitute your own host — see White‑label & branding.
Two API surfaces
Telenow exposes two request surfaces under /api. They differ in audience, authentication, and response shape — pick the one that matches your use case.
Dashboard API (/api/*) | Integration API (/api/v1/*) | |
|---|---|---|
| Built for | The web dashboard, SDKs, full programmatic control | Automation platforms (Zapier, Make, n8n, viaSocket) and simple glue code |
| Auth | User JWT (Authorization: Bearer … + X-Org-Id) or API key (X-API-Key) | API key only (X-API-Key) — no JWT fallback |
| Response shape | { "success": true, "data": { … } } envelope | Flat JSON — fields at the top level, no envelope |
| Org scoping | From X-Org-Id (JWT) or implicit from the key | Always implicit from the key — never from the path or a header |
| Coverage | Full CRUD for every resource | A curated slice: me, hooks, slim agent/number lists, calls, events sample, chat |
Both surfaces live under the same /api mount, so they share the same rate‑limit pool, idempotency handling, and audit logging.
Dashboard API example
curl https://api.telenow.ai/api/agents \
-H "X-API-Key: vai_live_…"
{
"success": true,
"data": {
"agents": [ /* full agent objects */ ],
"total": 12,
"limit": 50,
"offset": 0
}
}
Integration API example
curl https://api.telenow.ai/api/v1/agents \
-H "X-API-Key: vai_live_…"
{
"agents": [
{ "id": "…", "name": "Support Bot", "description": "…", "is_active": true,
"created_at": "…", "updated_at": "…" }
],
"total": 12
}
Note the integration response has no success/data wrapper — automation glue code can map response.agents directly. It also returns a slim projection (no system prompt or provider config). See Agents API for the difference, and Automation platforms for connector setup.
Which should I build against? If you're writing your own backend or want full control, use the Dashboard API. If you're wiring Telenow into a no‑code automation tool, use the Integration API (
/api/v1). The official SDKs wrap the Dashboard API.
Authentication
Two mechanisms, both detailed in Authentication:
- API key (server‑to‑server) —
X-API-Key: vai_live_…. The key is organization‑scoped, so no org header is needed. The only way to call/api/v1. - User JWT (dashboard sessions) —
Authorization: Bearer <token>, plusX-Org-Id: <orgId>for organization‑scoped routes. Works on/api/*only.
Request & response format
Requests and responses are JSON (Content-Type: application/json).
On the Dashboard API every response uses an envelope:
Success:
{
"success": true,
"data": { /* the result */ },
"message": "optional human-readable note"
}
Error:
{
"success": false,
"error": "human-readable message",
"code": "optional machine code"
}
On the Integration API (/api/v1) successful responses are flat (the object itself, no wrapper). Errors raised by the framework still carry the { "success": false, "error": … } shape; a few handler‑specific cases return a flat { "error": …, "code": … } instead (for example a 410 when a chat session has expired — see Chat API guide).
Always branch on the HTTP status code first, then read data/error.
HTTP status codes
| Status | Meaning |
|---|---|
200 OK | Success |
201 Created | Resource created |
204 No Content | Success, no body (e.g. delete) |
400 Bad Request | Validation failed / malformed input |
401 Unauthorized | Missing/invalid/expired credentials. JWT errors include code: "token_expired" or "token_invalid"; an MFA‑gated login returns error: "mfa_required" |
403 Forbidden | Authenticated but not allowed (role, non‑membership, quota reached, demo‑mode block) |
404 Not Found | Resource doesn't exist (or is hidden cross‑org) |
409 Conflict | State conflict (e.g. a call already in progress, a chat turn already running) |
410 Gone | The targeted runtime is gone (e.g. an expired chat session — code: "SESSION_EXPIRED") |
413 Payload Too Large | Body exceeds the size limit |
429 Too Many Requests | Rate limit exceeded — includes retryAfter (seconds) |
500 Internal Server Error | Unexpected server error |
503 Service Unavailable | Server draining / temporarily unavailable |
A 429 body looks like:
{ "success": false, "error": "Too many requests, please try again later", "retryAfter": 15 }
Rate limits
| Scope | Limit |
|---|---|
/api/* (incl. /api/v1/*) | 1000 requests per 15 minutes, per IP |
/webhooks/* (carrier callbacks) | 500 requests per 5 minutes, per IP |
Public widget session‑init (/api/public/widget/{slug}/session) | 10 attempts per 60 s, per slug + IP |
Because the Integration API is nested under /api, calls to /api/v1 count toward the same 1000‑requests‑per‑15‑minutes pool as the Dashboard API. When you hit a limit you get 429 with a retryAfter — back off for that many seconds.
Idempotency
Mutating requests (POST) can be made safely retryable by sending an Idempotency-Key header with a unique value (e.g. a UUID). If a request with the same key is retried, the original result is returned instead of performing the action twice — useful for network retries when creating resources or placing calls. The idempotency layer applies to all /api POSTs (including /api/v1) and is a no‑op when you don't send the header.
Pagination
List endpoints accept:
limit— page size (defaults and caps vary by resource; commonly default50, max200)offset— number of rows to skip (default0)
The Dashboard API returns the page plus a total:
{
"success": true,
"data": { "calls": [ /* … */ ], "total": 1234, "limit": 100, "offset": 0 }
}
The Integration API returns the same idea flat: { "calls": [ … ], "total": 1234 }.
Endpoint‑specific filters (date ranges, status, agent, …) are documented on each resource page.
Health & status
Unauthenticated endpoints for uptime checks and service discovery (these live outside /api, so they're not rate‑limited):
| Method | Path | Purpose |
|---|---|---|
GET | /health | Health status (includes basic stats) |
GET | /health/live | Liveness probe |
GET | /health/ready | Readiness probe (503 while the server is draining) |
SDKs & clients
Official SDKs cover the browser (web & React), mobile apps (React Native), and backends (Node & Python) — they handle session init, the audio WebSocket, and call control so you don't implement this reference by hand. The API itself is plain REST + JSON, so any HTTP client works too; examples in this reference use curl. For browser voice without any code, embed the widget, or see Programmatic web calls for the raw protocol.
Versioning & compatibility
New fields may be added to responses over time; clients should ignore unknown fields rather than fail. Breaking changes are communicated in advance. The /api/v1 path is the stable, versioned integration surface — new versions, if introduced, will live under a new prefix rather than changing v1 in place.
Where to next
- Authentication — keys, JWTs, roles, headers
- Agents API · Sessions & calls · Chat API guide
- Organizations, team & API keys · Audit log API
- Webhooks and webhook events
- Automation platforms