Skip to main content
AI sessions are created automatically when a voice agent connects to a call. The control endpoint lets your AI service (or any authorized caller) send telephony commands to an active session.
For the full list of 25 control verbs with detailed parameters, see the Control API reference.

Send a control event

Dispatches a telephony verb to an active AI session. Your AI service calls this endpoint during or after a conversation to transfer, hang up, set dispositions, manage conferences, and more.
Status: 200 OK

Authentication

Two auth options — use whichever fits your architecture: Callback tokens are delivered in the metadata frame when the WebSocket connects. They auto-rotate at 25 minutes via a token_refresh text frame — your AI service should swap to the new token on receipt.

Request body

Response

Rate limit

10 requests per second per call_id. Exceeding returns 429.

Report a post-call outcome

Send what your agent learned once the call is over: why it ended, who ended it, and the fields it collected. Yotel shows it on the call and writes it into the tenant’s CRM.
Status: 200 OK — { "ok": true, "call_id": "...", "reported_at": "..." }
Unlike control verbs, this endpoint accepts a session that has already ended, and the per-call token stays valid for 180 seconds after the audio WebSocket closes — for this endpoint only, and only for that automatic close-triggered revocation. If Yotel (or your own integration) revokes the token explicitly — e.g. because it leaked — that revocation takes effect immediately, however recently it happened; it never gets this grace. Send the report from your post-call step. Retries are safe: the latest report replaces the previous one.
Response: { "ok": true, "call_id": "...", "reported_at": "...", "disposition_status": "written" } — disposition_status is present only when you sent a disposition:
Feature-detect before you send disposition. A Yotel deployment that predates this field rejects the whole report with 422 on the unknown key. Call the disposition list at call start and include disposition only when that response carried "outcome_accepts_disposition": true. If you ever get a 422 with the fields present, resend once without them.
Two keys inside collected_data are reserved and always dropped: end_reason and end_initiated_by. Send those as the top-level fields above instead — the top-level values are what Yotel stores and forwards to your CRM, so a same-named key nested inside collected_data would otherwise duplicate them.
Unknown is not an outcome. The literal value unknown (or a blank) in end_reason or end_initiated_by is stored verbatim but is never forwarded as a result: the CRM line reads outcome=not reported by the voice agent, and end_initiated_by then falls back to who the telephony layer saw hang up (ended_by=customer (hung up) when the far end sent the BYE on a normally cleared call). If your agent cannot determine a reason, omit the detail rather than inventing one — and prefer calling your end-of-call tool when the caller says goodbye, so the reason is yours and not inferred.

List the dispositions your agent may set

Fetch the tenant’s disposition list at call start and build your agent’s vocabulary from it, so a disposition the tenant adds, renames or switches off on the dialer reaches your agent with no code change.
Status: 200 OK
  • Rows are the tenant’s dispositions marked AI may set (Settings → Dispositions), in the tenant’s own order. code is what you send back as disposition on the outcome report — a leaf’s own code, never its group’s.
  • parent_code names the group a leaf rolls up to (null for a group row). Tenants can hold their CRM’s exact outcome vocabulary as leaves under Yotel’s groups, so labels are theirs verbatim; ignore this key if your agent has no use for grouping.
  • is_dnc tells your agent which row means “do not call”. Key your do-not-call behaviour on this flag, never on a hardcoded code — tenants rename rows.
  • The list is served from your callback token alone; it does not depend on the call having been recorded yet, so it is safe to fetch the moment your session starts. Do not cache a failure: a 404 or 5xx means “try again on the next call”, not “this tenant has no list”.
  • outcome_accepts_disposition is the capability flag for the disposition field on the outcome report. It is always true on a deployment that serves this route; an older deployment answers 404.
Same authentication and rate limit as control verbs; the 180-second post-close token grace does not apply here.

Revoke a callback token

Immediately invalidates a per-call callback token. Use this when your AI service detects a token compromise or needs to force a session handoff.
Scope: ai_sessions:control_admin  |  Status: 200 OK

Response

Token revocation requires ai_sessions:control_admin scope — callback tokens cannot revoke themselves. The token’s embedded call_id must match the URL path call_id (tenant fence).

Control verbs reference

The control endpoint supports 25 verbs organized in three groups: See the Control API reference for detailed parameters, idempotency behavior, and error codes for each verb.

Errors