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 forThe web dashboard, SDKs, full programmatic controlAutomation platforms (Zapier, Make, n8n, viaSocket) and simple glue code
AuthUser 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": { … } } envelopeFlat JSON — fields at the top level, no envelope
Org scopingFrom X-Org-Id (JWT) or implicit from the keyAlways implicit from the key — never from the path or a header
CoverageFull CRUD for every resourceA 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>, plus X-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

StatusMeaning
200 OKSuccess
201 CreatedResource created
204 No ContentSuccess, no body (e.g. delete)
400 Bad RequestValidation failed / malformed input
401 UnauthorizedMissing/invalid/expired credentials. JWT errors include code: "token_expired" or "token_invalid"; an MFA‑gated login returns error: "mfa_required"
403 ForbiddenAuthenticated but not allowed (role, non‑membership, quota reached, demo‑mode block)
404 Not FoundResource doesn't exist (or is hidden cross‑org)
409 ConflictState conflict (e.g. a call already in progress, a chat turn already running)
410 GoneThe targeted runtime is gone (e.g. an expired chat session — code: "SESSION_EXPIRED")
413 Payload Too LargeBody exceeds the size limit
429 Too Many RequestsRate limit exceeded — includes retryAfter (seconds)
500 Internal Server ErrorUnexpected server error
503 Service UnavailableServer draining / temporarily unavailable

A 429 body looks like:

{ "success": false, "error": "Too many requests, please try again later", "retryAfter": 15 }

Rate limits

ScopeLimit
/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 default 50, max 200)
  • offset — number of rows to skip (default 0)

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):

MethodPathPurpose
GET/healthHealth status (includes basic stats)
GET/health/liveLiveness probe
GET/health/readyReadiness 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