Browse the documentation

Documentation

API reference

Updated 55 min read

Ask AI about this page

The Open Voice Shield REST API is served under /api at https://ovs.telecomsxchange.com and authenticates with either a bearer token or an API key sent as X-API-Key. This page lists every customer-facing endpoint with its parameters, request and response shapes and the errors it raises.

Base URL and versioning#

Every path below is served under /api at https://ovs.telecomsxchange.com: so GET /calls is GET /api/calls against that host. The interactive explorer is at /api/docs and the machine-readable schema at /api/openapi.json: that schema is what this page is generated from, so the two cannot disagree.

Requests and responses are JSON unless a row below says otherwise. Timestamps are UTC, ISO 8601. Identifiers are UUIDs. Lists take limit and offset and return a total, so you can page without losing rows.

Authentication#

There are two ways to authenticate, and they are interchangeable on every endpoint marked Bearer or API key:

Bearer token
Authorization: Bearer <access token>. You get one from POST /auth/login or POST /auth/signup. It is short-lived; a browser session renews it with POST /auth/refresh. Use this for a person at a screen.
API key
X-API-Key: <key>. It does not expire and is the right credential for a script, a switch integration or a scheduled job.

Create a key with POST /auth/api-keys as the account owner. The full key is in that one response and is stored only as a hash: it can never be shown again. Lose it and you mint a new one and revoke the old. A key acts as the user who minted it: revoke it with DELETE /auth/api-keys/{key_id}, or deactivate that user, and it stops working at once.

Owner-only endpoints

Anything that mints or revokes a credential, or that changes who can sign in, is owner-only. A member session answers 403 owner_required. Those rows are marked owner only in the Auth column.

Errors#

An error is a JSON body with a detail field and one of the status codes below. The Errors column on each endpoint lists only what that handler raises: 401 on a bad or missing credential and 422 on a malformed parameter apply everywhere and are not repeated row by row.

Status codes used across the API.
CodeMeansWhat to do
401Not authenticatedThe token expired, the key is wrong or was revoked. Refresh or re-issue.
403ForbiddenThe credential is valid but not allowed here: a member on an owner-only route, or a suspended account.
404Not foundNo such record on your account. Another account's record is a 404, never a 403.
409ConflictThe request contradicts what exists: a duplicate, or a state that does not allow it.
422Validation errorA field is missing or out of range. The body names the field.
429Too many requestsBack off. Retry-After carries the number of seconds.

Authentication, sessions and keys#

Create an account, sign in, rotate a session and mint the API keys your own systems use. A key is minted by a signed-in owner and is shown once.

sign in, then mint a key: the key is shown once


TOKEN=$(curl -s -X POST https://ovs.telecomsxchange.com/api/auth/login \
  -H 'Content-Type: application/json' \
  -d '{"email":"ops@acme.example","password":"correct-horse-battery"}' \
  | sed -n 's/.*"access_token":"\([^"]*\)".*/\1/p')

curl -s -X POST https://ovs.telecomsxchange.com/api/auth/api-keys \
  -H "Authorization: Bearer $TOKEN" -H 'Content-Type: application/json' \
  -d '{"name":"noc-integration"}'
# 201 {"id":"...","name":"noc-integration","prefix":"ovs_...","key":"ovs_...","revoked_at":null}
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /auth/api-keys List the account keys, by prefix. The secret is not included. Bearer or API key
POST /auth/api-keys Mint an API key. The full key is in the response and is never shown again. Bearer or API key, owner only
DELETE /auth/api-keys/{key_id} Revoke a key immediately. Bearer or API key, owner only
POST /auth/change-password Set a new password and end every other session. Bearer or API key
GET /auth/config What the sign-in and sign-up screens need to know, before anyone signs in. None
POST /auth/login Sign in with e-mail and password. Returns a token, or a second-factor challenge when a passkey is registered. None
POST /auth/login/passkey Complete a two-factor sign-in by answering the passkey challenge from the password step. None
POST /auth/login/passkey/enroll Register a passkey during sign-in for a member of a two-factor account who has none yet, then complete the sign-in. None
POST /auth/logout End this browser session and clear its refresh cookie. Refresh cookie + X-Requested-With
POST /auth/logout-all Sign out of every browser session at once. API keys keep working. Bearer or API key
GET /auth/me The account behind the current credentials. Bearer or API key
GET /auth/passkeys List the passkeys registered on the account. Bearer or API key, owner only
DELETE /auth/passkeys/{passkey_id} Remove a passkey. Removing the last one turns two-factor sign-in off. Bearer or API key, owner only
PATCH /auth/passkeys/{passkey_id} Rename a registered passkey. Bearer or API key, owner only
DELETE /auth/passkeys/members/{user_id} As the account owner, remove every passkey of a team member who lost their device. Bearer or API key, owner only
POST /auth/passkeys/register/begin Start registering a passkey: returns the options the browser needs. Bearer or API key, owner only
POST /auth/passkeys/register/complete Finish registering a passkey and turn on two-factor sign-in. Bearer or API key, owner only
POST /auth/refresh Exchange the refresh cookie for a new access token and rotate the cookie. Refresh cookie + X-Requested-With
POST /auth/signup Create an account and return a first access token. None
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /auth/api-keys : : 200 ApiKeyOut[] :
POST /auth/api-keys : name string, required 201 ApiKeyCreated 403 owner_required
DELETE /auth/api-keys/{key_id} key_id uuid, required : 204 No content 403 owner_required
404 API key not found
POST /auth/change-password : current_password string, required
new_password string, required
204 No content 400 invalid_current_password
422 new_password must differ from the current password
GET /auth/config : : 200 AuthConfigOut :
POST /auth/login : email email, required
password string, required
200 TokenResponse, or TwoFactorRequired when a passkey is registered 401 Invalid email or password
403 Account suspended
429 Too many requests
POST /auth/login/passkey : login_token string, required
assertion object, required
200 TokenResponse 401 invalid_login
POST /auth/login/passkey/enroll : enroll_token string, required
credential object, required
name string or null
200 TokenResponse 401 invalid_login
409 passkey_already_registered
POST /auth/logout : : 204 No content :
POST /auth/logout-all : : 204 No content :
GET /auth/me : : 200 CustomerOut :
GET /auth/passkeys : : 200 PasskeyOut[] 403 owner_required
DELETE /auth/passkeys/{passkey_id} passkey_id uuid, required : 204 No content 403 owner_required
404 Passkey not found
PATCH /auth/passkeys/{passkey_id} passkey_id uuid, required name string, required 200 PasskeyOut 403 owner_required
404 Passkey not found
DELETE /auth/passkeys/members/{user_id} user_id uuid, required : 204 No content 403 owner_required
404 User not found
POST /auth/passkeys/register/begin : : 200 PasskeyRegisterBeginOut 403 owner_required
POST /auth/passkeys/register/complete : credential object, required
state string, required
name string or null
201 PasskeyOut 400 Bad request
403 owner_required
409 passkey_already_registered
POST /auth/refresh : : 200 TokenResponse 401 Not authenticated
POST /auth/signup : email email, required
password string, required
company string or null
full_name string or null
attribution object or null
accept_terms boolean, default false
201 SignupResponse 403 Signup is disabled
409 Email already registered
422 Validation error
429 Too many requests

Users on your account#

Every person who signs in to your account has a user row. Owners invite, rename and deactivate; members can read the list.

invite a member (owner only)

curl -s -X POST https://ovs.telecomsxchange.com/api/customer/users \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"email":"analyst@acme.example","name":"Night shift"}'
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /customer/users List the people who can sign in to the account, owner first. Bearer or API key
POST /customer/users Invite a member. They receive a temporary password and must change it on first sign-in. Bearer or API key, owner only
PATCH /customer/users/{user_id} Rename, deactivate or reactivate a member. The owner cannot be deactivated. Bearer or API key, owner only
POST /customer/users/{user_id}/resend-invite Issue a new temporary password and re-send the invitation. The old one stops working. Bearer or API key, owner only
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /customer/users : : 200 CustomerUserList :
POST /customer/users : email email, required
name string or null
201 CustomerUserInvited 403 owner_required
409 Email already registered
PATCH /customer/users/{user_id} user_id uuid, required name string or null
is_active boolean or null
200 CustomerUserOut 400 cannot_deactivate_owner
403 owner_required
404 User not found
POST /customer/users/{user_id}/resend-invite user_id uuid, required : 200 CustomerUserInvited 400 cannot_reset_owner
403 owner_required
404 User not found

Trunk, whitelist, destinations and routing#

The connection itself: the address your switch sends to, the source addresses allowed to send, where a call goes next, and the prefix rules that choose between destinations.

whitelist the address your switch sends from

curl -s https://ovs.telecomsxchange.com/api/customer/network-info -H "X-API-Key: $OVS_KEY"

curl -s -X POST https://ovs.telecomsxchange.com/api/customer/ips \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"cidr":"203.0.113.7/32","label":"Toronto SBC"}'
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /customer/destinations Where analyzed calls are handed on to, each with its SIP OPTIONS monitor state (up, down, unknown, last check, round trip). Bearer or API key
POST /customer/destinations Add a destination: the SBC, PBX or carrier the call was already going to. It is checked with SIP OPTIONS right away and monitored if it answers. Bearer or API key
DELETE /customer/destinations/{dest_id} Remove a destination. Bearer or API key
PATCH /customer/destinations/{dest_id} Change a destination, make it the default, or switch its monitoring on or off. Bearer or API key
POST /customer/destinations/{dest_id}/check Send one SIP OPTIONS to the destination now and get its refreshed monitor state back. Bearer or API key
GET /customer/ips The source addresses allowed to send you traffic. Bearer or API key
POST /customer/ips Whitelist a source address or range. Traffic from anywhere else is rejected. With a dial prefix, the entry is one sub-customer behind that address. Bearer or API key
DELETE /customer/ips/{ip_id} Remove a whitelisted address. Bearer or API key
PATCH /customer/ips/{ip_id} Change a whitelisted entry's label, dial prefix, destination or enabled flag in place, without refusing its calls meanwhile. Bearer or API key
GET /customer/network-info The host, port and transports your switch sends the INVITE to. Bearer or API key
GET /customer/routing-rules The prefix rules that choose a destination. Bearer or API key
POST /customer/routing-rules Route a dialled prefix to a specific destination. Bearer or API key
DELETE /customer/routing-rules/{rule_id} Remove a prefix rule. Bearer or API key
PATCH /customer/routing-rules/{rule_id} Change a prefix rule, its priority or its destination. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /customer/destinations : : 200 DestinationOut[] :
POST /customer/destinations : host string, required
port integer, default 5060
transport "udp" | "tcp" | "tls", default "udp"
is_default boolean, default false
label string or null
kind "sip" | "voice_ai", default "sip"
provider string or null
agent_id string or null
config object or null
tech_prefix string or null
monitor_enabled boolean or null
processing string or null
sample_rate integer or null
sample_mode string or null
transfer_mode string or null
auth_username string or null
auth_password string or null
auth_realm string or null
webhook_secret string or null
provider_api_key string or null
201 DestinationOut 409 Maximum number of destinations reached
422 Validation error
DELETE /customer/destinations/{dest_id} dest_id uuid, required : 204 No content 404 Destination not found
PATCH /customer/destinations/{dest_id} dest_id uuid, required host string or null
port integer or null
transport "udp" | "tcp" | "tls" or null
is_default boolean or null
label string or null
kind "sip" | "voice_ai" or null
provider string or null
agent_id string or null
config object or null
tech_prefix string or null
monitor_enabled boolean or null
processing string or null
sample_rate integer or null
sample_mode string or null
transfer_mode string or null
auth_username string or null
auth_password string or null
auth_realm string or null
clear_credential boolean or null
webhook_secret string or null
provider_api_key string or null
clear_webhook_secret boolean or null
clear_provider_key boolean or null
rotate_webhook_token boolean or null
200 DestinationOut 404 Destination not found
422 Validation error
POST /customer/destinations/{dest_id}/check dest_id uuid, required : 200 DestinationOut 404 Destination not found
GET /customer/ips : : 200 IpOut[] :
POST /customer/ips : cidr string, required
label string or null
dial_prefix string or null
destination_id uuid or null
enabled boolean, default true
201 IpOut 404 Destination not found
409 CIDR overlaps a range registered to another account
422 Validation error
503 Whitelist busy, retry
DELETE /customer/ips/{ip_id} ip_id uuid, required : 204 No content 404 IP entry not found
PATCH /customer/ips/{ip_id} ip_id uuid, required label string or null
dial_prefix string or null
destination_id uuid or null
enabled boolean or null
200 IpOut 404 IP entry not found
409 Entry already exists
GET /customer/network-info : : 200 NetworkInfoOut :
GET /customer/routing-rules : : 200 RoutingRuleOut[] :
POST /customer/routing-rules : prefix string, required
destination_id uuid, required
enabled boolean, default true
priority integer, default 100
label string or null
201 RoutingRuleOut 404 Destination not found
409 Conflict
DELETE /customer/routing-rules/{rule_id} rule_id uuid, required : 204 No content 404 Routing rule not found
PATCH /customer/routing-rules/{rule_id} rule_id uuid, required prefix string or null
destination_id uuid or null
enabled boolean or null
priority integer or null
label string or null
200 RoutingRuleOut 404 Destination not found
409 Conflict

Calls and analysis#

Every call that traversed the platform, its verdict, its transcript, its recording, its SIP flow and a self-contained evidence bundle.

the high-risk calls of the last day, then one verdict

curl -s "https://ovs.telecomsxchange.com/api/calls?min_probability=70&limit=20" -H "X-API-Key: $OVS_KEY"

curl -s https://ovs.telecomsxchange.com/api/calls/$CALL_ID/analysis -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /calls Search and filter your calls: by time, status, verdict, category, route or route alert, by an exact entity or keywords, and by what the call was about (title, entity, keywords), sorted over every match. Bearer or API key
GET /calls/{call_id} One call: numbers, timing, where it was routed and its verdict. Bearer or API key
GET /calls/{call_id}/analysis The verdict on its own: probability, category, red flags and recommendation. Bearer or API key
POST /calls/{call_id}/analyze Analyse a recorded call the sampling policy left out, or a record-only call, on demand. The analysis fee applies. Bearer or API key
GET /calls/{call_id}/export Download a self-contained evidence bundle for the call: it opens offline, with no account. Bearer or API key
GET /calls/{call_id}/inspect Everything the live line inspector shows, in one document: the call, the SIP ladder so far, post-dial delay, early media and codec, the relay’s per-leg media statistics while the call is up, the measured quality and the verdict once it has one. Poll it every couple of seconds while a call is up. Bearer or API key
GET /calls/{call_id}/pcap Download the media capture of the call. Bearer or API key
GET /calls/{call_id}/recording Download the call audio as a stereo WAV. Bearer or API key
GET /calls/{call_id}/recording-token A short-lived token for streaming the recording in a player that cannot send an Authorization header. Bearer or API key
GET /calls/{call_id}/report.pdf A branded PDF report of the call: verdict, red flags, route alert, quality and the transcript, for sharing with a vendor or a customer. Bearer or API key
GET /calls/{call_id}/sip-log The SIP message flow of the call, as rows and as a plain-text log. Bearer or API key
GET /calls/{call_id}/transcript The transcript of the call, with its language and confidence. Bearer or API key
POST /calls/{call_id}/transfer Ask a voice agent on a live call to transfer the caller to a number. Bearer or API key
GET /calls/entities The entities callers claimed most often in your recent analyzed calls (a bank, a retailer, an agency), each with its count. Bearer or API key
GET /calls/keywords The keywords that come up most in your recent analyzed calls, each with its count: one click from a keyword filter. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /calls status string or null
analysis_status string or null
from timestamp or null
to timestamp or null
min_probability integer or null, 0–100
external_id string or null
origin string or null
sip_call_id string or null
sampled boolean or null
q string or null
category string or null
recommendation string or null
destination_id uuid or null
route_alert boolean or null
entity string or null
sub_customer string or null
keyword string[] or null
sort string or null
limit integer, default 50, 1–500
offset integer, default 0, 0–2147483647
: 200 CallList 422 origin must be 'sip', 'dialer' or 'test'
GET /calls/{call_id} call_id uuid, required : 200 CallDetail 404 Call not found
GET /calls/{call_id}/analysis call_id uuid, required : 200 AnalysisOut 404 Call not found
POST /calls/{call_id}/analyze call_id uuid, required : 202 AnalyzeQueued 404 Call not found
409 relay_only: nothing was recorded for this call, so there is nothing to analyse
GET /calls/{call_id}/export call_id uuid, required : 200 application/zip: the evidence bundle 404 Call not found
429 too_many_exports
GET /calls/{call_id}/inspect call_id uuid, required : 200 CallInspectOut 404 Call not found
GET /calls/{call_id}/pcap call_id uuid, required : 200 The capture file, or a zip when the call had several media legs 404 Call not found
GET /calls/{call_id}/recording call_id uuid, required
t string or null
: 200 audio/wav: the file, or a redirect to a short-lived download URL 404 Call not found
GET /calls/{call_id}/recording-token call_id uuid, required : 200 MediaTokenOut 404 Call not found
GET /calls/{call_id}/report.pdf call_id uuid, required : 200 application/pdf: the call report 404 Call not found
429 too_many_exports
GET /calls/{call_id}/sip-log call_id uuid, required : 200 SipLogOut 404 Call not found
GET /calls/{call_id}/transcript call_id uuid, required : 200 TranscriptOut 404 Call not found
POST /calls/{call_id}/transfer call_id uuid, required target string, required 202 TransferQueued 404 Call not found
409 only a call that is up can be transferred
422 target must be a number (digits, * and # only)
GET /calls/entities days integer, default 30, 1–365
limit integer, default 12, 1–50
: 200 EntityCount[] :
GET /calls/keywords days integer, default 30, 1–365
limit integer, default 12, 1–50
: 200 KeywordCount[] :

Sharing a call outside your account#

A password-protected link to one call, for a carrier or a customer who has no account. The owner side is authenticated; the reader side is not.

share one call, then open it as the reader would

curl -s -X POST https://ovs.telecomsxchange.com/api/calls/$CALL_ID/share \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"expires_in_hours":72,"label":"carrier dispute"}'
# 201: "password" is in this response and in no other

curl -s -X POST https://ovs.telecomsxchange.com/api/public/shares/$TOKEN/unlock \
  -H 'Content-Type: application/json' -d '{"password":"..."}'

curl -s https://ovs.telecomsxchange.com/api/public/shares/$TOKEN -H "X-Share-Token: $VIEW_TOKEN"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
POST /calls/{call_id}/share Create a password-protected public link to one call. The password is returned once. Bearer or API key
GET /calls/{call_id}/shares The links that exist for this call. Passwords are never included. Bearer or API key
DELETE /calls/shares/{share_id} Revoke a link. It stops opening immediately. Bearer or API key
POST /calls/shares/{share_id}/rotate Issue a new password for the same link, returned once. Bearer or API key
POST /public/leads Ask for a setup call: the website form. Stores the request and mails the team; answers 202. None
GET /public/shares/{token} The shared call, once unlocked. View token
GET /public/shares/{token}/meta Whether a link is real and still live, and who shared it. Nothing about the call. None
GET /public/shares/{token}/recording The shared call audio, once unlocked. View token
POST /public/shares/{token}/unlock Exchange the link password for a short-lived view token. None
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
POST /calls/{call_id}/share call_id uuid, required expires_in_hours integer or null
label string or null
201 CallShareCreated 404 Call not found
GET /calls/{call_id}/shares call_id uuid, required : 200 CallShareList 404 Call not found
DELETE /calls/shares/{share_id} share_id uuid, required : 200 CallShareOut 404 Share link not found
POST /calls/shares/{share_id}/rotate share_id uuid, required : 200 CallShareCreated 404 Share link not found
409 This link is revoked or expired
POST /public/leads : name string, required
email email, required
company string or null
platform string or null
volume string or null
message string or null
page string or null
attribution object or null
website string or null
202 object 429 Too many requests, try again later
GET /public/shares/{token} token string, required
t string or null
: 200 PublicSharePayload 401 Invalid link or password
404 This link is no longer available
GET /public/shares/{token}/meta token string, required : 200 ShareMetaOut :
GET /public/shares/{token}/recording token string, required
t string or null
: 200 audio/wav: the file, or a redirect to a short-lived download URL 401 Invalid link or password
404 This link is no longer available
POST /public/shares/{token}/unlock token string, required password string, required 200 ShareUnlockOut 401 Invalid link or password
429 too_many_attempts

Cases#

The investigation record attached to a call: title, severity, status, assignee and a comment thread.

open a case on a call and comment on it

CASE=$(curl -s -X POST https://ovs.telecomsxchange.com/api/cases \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"title":"Wangiri from +1 555","severity":"high","call_id":"'$CALL_ID'"}')

curl -s -X POST https://ovs.telecomsxchange.com/api/cases/$CASE_ID/comments \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"body":"Carrier notified."}'
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /cases Search cases by status, severity or assignee. Bearer or API key
POST /cases Open a case, optionally attached to a call. Bearer or API key
GET /cases/{case_id} One case, with its comment thread. Bearer or API key
PATCH /cases/{case_id} Change status, severity, text or assignee. The new assignee is notified. Bearer or API key
POST /cases/{case_id}/comments Add a comment to a case. Bearer or API key
GET /cases/prefill Suggested title, severity and description for a case about a given call. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /cases status string or null
severity string or null
assigned_to uuid or null
call_id uuid or null
limit integer, default 50, 1–200
offset integer, default 0
: 200 CaseList 422 Validation error
POST /cases : title string, required
description string or null
severity "low" | "medium" | "high" | "critical", default "medium"
call_id uuid or null
201 CaseOut 404 Call not found
409 case_already_exists_for_call
GET /cases/{case_id} case_id uuid, required : 200 CaseDetail 404 Case not found
PATCH /cases/{case_id} case_id uuid, required title string or null
description string or null
status "open" | "in_review" | "resolved" | "dismissed" or null
severity "low" | "medium" | "high" | "critical" or null
assigned_to uuid or null
clear_assigned_to boolean, default false
200 CaseOut 404 Case not found
422 assigned_to must be an active user of this account
POST /cases/{case_id}/comments case_id uuid, required body string, required 201 CaseCommentOut 404 Case not found
GET /cases/prefill call_id uuid, required : 200 JSON object: title, severity, description, existing_case_id 404 Call not found

Support tickets#

A question, a problem, a feature request, a billing query, or a call whose verdict you dispute: a ticket with a thread that a person answers. Replies also arrive by e-mail.

dispute the verdict on a call, then read the reply

TICKET=$(curl -s -X POST https://ovs.telecomsxchange.com/api/support/tickets \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"kind":"analysis","subject":"Verdict should be allow","body":"This was our own IT vendor.","call_id":"'$CALL_ID'"}')

curl -s https://ovs.telecomsxchange.com/api/support/tickets/$TICKET_ID -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /support/tickets List your support tickets, newest first, filterable by status and kind. Bearer or API key
POST /support/tickets Open a ticket: a question, problem, feature request or billing query, or a dispute of one call’s analysis when call_id names one of your calls. Bearer or API key
GET /support/tickets/{ticket_id} One ticket with its thread and, when it is about a call, that call. Bearer or API key
PATCH /support/tickets/{ticket_id} Close a ticket, or reopen it. Bearer or API key
POST /support/tickets/{ticket_id}/messages Write on the ticket. It goes back to our team, and a closed ticket reopens. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /support/tickets status string or null
kind string or null
limit integer, default 50, 1–200
offset integer, default 0
: 200 TicketList 422 Validation error
POST /support/tickets : kind "question" | "bug" | "feature" | "analysis" | "billing", default "question"
subject string, required
body string, required
call_id uuid or null
201 TicketOut 404 Call not found
GET /support/tickets/{ticket_id} ticket_id uuid, required : 200 TicketDetail 404 Ticket not found
PATCH /support/tickets/{ticket_id} ticket_id uuid, required status "open" | "answered" | "closed", required 200 TicketOut 404 Ticket not found
422 only a reply from support marks a ticket answered
POST /support/tickets/{ticket_id}/messages ticket_id uuid, required body string, required 201 TicketMessageOut 404 Ticket not found

Automation and controlled numbers#

Rules that act on a verdict without a human: block or divert a number for a set time: and the table of numbers currently under control.

block a number for 24 hours when the verdict is 90 or above

curl -s -X POST https://ovs.telecomsxchange.com/api/automation/rules \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"name":"auto-block","min_probability":90,"action":"block","duration_hours":24}'

curl -s https://ovs.telecomsxchange.com/api/automation/controls -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /automation/controls The numbers currently blocked or diverted by a rule. Bearer or API key
POST /automation/controls/{control_id}/release Release a controlled number so it is treated normally again. Bearer or API key
GET /automation/rules The automation rules on the account. Bearer or API key
POST /automation/rules Add a rule that blocks or diverts a number when a verdict crosses a threshold. Bearer or API key
DELETE /automation/rules/{rule_id} Remove a rule. Bearer or API key
PATCH /automation/rules/{rule_id} Change a rule, or turn it off. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /automation/controls include_released boolean, default false
limit integer, default 50, 1–500
offset integer, default 0, 0–2147483647
: 200 AniControlList :
POST /automation/controls/{control_id}/release control_id uuid, required : 200 AniControlOut 404 control not found
409 control already released
GET /automation/rules : : 200 AutomationRuleOut[] :
POST /automation/rules : name string, required
enabled boolean, default true
min_probability integer, default 90
recommendations string[] or null, default ["block"]
action "block" | "divert", default "block"
divert_destination_id uuid or null
duration_hours integer or null
201 AutomationRuleOut 404 divert destination not found
409 Maximum number of automation rules reached
DELETE /automation/rules/{rule_id} rule_id uuid, required : 204 No content 404 automation rule not found
PATCH /automation/rules/{rule_id} rule_id uuid, required name string or null
enabled boolean or null
min_probability integer or null
recommendations string[] or null
action "block" | "divert" or null
divert_destination_id uuid or null
duration_hours integer or null
clear_duration boolean, default false
200 AutomationRuleOut 404 divert destination not found
422 divert_destination_id is required when action is 'divert'

Alerts and webhooks#

Push a verdict out: e-mail alert rules with their own thresholds, and one signed HTTP webhook for your own systems.

point a webhook at your own system and test it

curl -s -X PUT https://ovs.telecomsxchange.com/api/customer/webhook \
  -H "X-API-Key: $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"url":"https://noc.acme.example/hooks/ovs","secret":"a-long-random-string"}'

curl -s -X POST https://ovs.telecomsxchange.com/api/customer/webhook/test -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /customer/alert-rules The e-mail alert rules on the account. Bearer or API key
POST /customer/alert-rules Alert named recipients when a verdict crosses a threshold. Bearer or API key
DELETE /customer/alert-rules/{rule_id} Remove an alert rule. Bearer or API key
PATCH /customer/alert-rules/{rule_id} Change an alert rule, or turn it off. Bearer or API key
POST /customer/alert-rules/{rule_id}/test Send a sample alert to the rule recipients now. Bearer or API key
GET /customer/webhook The webhook URL configured for the account. Bearer or API key
PUT /customer/webhook Set or clear the webhook URL and its signing secret. Bearer or API key
POST /customer/webhook/test Deliver one signed test event now and report what the endpoint answered. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /customer/alert-rules : : 200 AlertRuleOut[] :
POST /customer/alert-rules : name string, required
enabled boolean, default true
min_probability integer, default 70
categories string[] or null
recommendations string[] or null
recipients string[] or null
throttle_minutes integer, default 0
include_transcript boolean, default false
include_sip_log boolean, default false
include_pcap boolean, default false
include_recording boolean, default false
trigger string, default "fraud"
max_mos number or string or null
channel_ids uuid[] or null
email_enabled boolean, default true
201 AlertRuleOut 409 Maximum number of alert rules reached
422 the rule needs at least one delivery: email or a connected channel
DELETE /customer/alert-rules/{rule_id} rule_id uuid, required : 204 No content 404 alert rule not found
PATCH /customer/alert-rules/{rule_id} rule_id uuid, required name string or null
enabled boolean or null
min_probability integer or null
categories string[] or null
recommendations string[] or null
recipients string[] or null
throttle_minutes integer or null
include_transcript boolean or null
include_sip_log boolean or null
include_pcap boolean or null
include_recording boolean or null
trigger string or null
max_mos number or string or null
channel_ids uuid[] or null
email_enabled boolean or null
200 AlertRuleOut 404 alert rule not found
422 the rule needs at least one delivery: email or a connected channel
POST /customer/alert-rules/{rule_id}/test rule_id uuid, required : 200 AlertRuleTestOut 404 alert rule not found
409 no_delivery
GET /customer/webhook : : 200 WebhookOut :
PUT /customer/webhook : url string or null
secret string or null
200 WebhookOut 422 webhook_secret_required: set the signing secret on the Developers page of the portal first
POST /customer/webhook/test : : 200 WebhookTestOut :

Test calls#

Have the platform place a call for you: it dials a number through one of your destinations, plays a speech sample and hangs up. The call is recorded and analysed like any other, so a script or an AI agent can exercise a route without a switch.

dial a number through your route with the scam sample, then poll

curl -s -X POST https://ovs.telecomsxchange.com/api/customer/test-calls \
  -H "Authorization: Bearer $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"number":"18005550100","destination_id":"DEST_ID","seconds":30,"speech":"scam_sample"}'
# 202 {"id":"TC_ID","status":"queued","sip_call_id":"ovs-test-...","call_id":null,...}

curl -s https://ovs.telecomsxchange.com/api/customer/test-calls/TC_ID -H "Authorization: Bearer $OVS_KEY"
# {"status":"done","answered":true,"sip_code":200,"talk_seconds":30.0,"ended_by":"caller","call_id":"CALL_ID",...}
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /customer/test-calls The recent test calls of the account, newest first. Bearer or API key
POST /customer/test-calls Queue a test call: the platform dials the number through a destination, opens with the automated-test-call announcement and plays a speech sample for the requested seconds. The caller ID must be one of the account's verified numbers (default: the platform's own); the scam sample and agent mode only ring verified numbers. A request made with an AI connector's token waits as awaiting_confirm until a person confirms it in the portal. Poll the returned id. Bearer or API key
GET /customer/test-calls/{test_call_id} One test call: its placement status, whether it was answered, the SIP code and the id of the resulting call. Bearer or API key
POST /customer/test-calls/{test_call_id}/cancel Withdraw a test call that is still awaiting confirmation; it never rings. Bearer or API key
POST /customer/test-calls/{test_call_id}/confirm A person confirms a test call an AI agent asked for; portal sessions only, and only while the request is fresh (ten minutes). The call is then queued. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /customer/test-calls : : 200 TestCallOut[] :
POST /customer/test-calls : number string, required
destination_id uuid or null
caller_id string or null
seconds integer, default 30
speech string, default "route_test"
agent_destination_id uuid or null
instruction string or null
202 TestCallOut 403 test_calls_disabled
404 Voice agent destination not found
409 Add a destination before placing a test call
422 caller_id_not_verified: a test call may only present one of the account's verified numbers
GET /customer/test-calls/{test_call_id} test_call_id uuid, required : 200 TestCallOut 404 test call not found
POST /customer/test-calls/{test_call_id}/cancel test_call_id uuid, required : 200 TestCallOut 404 test call not found
POST /customer/test-calls/{test_call_id}/confirm test_call_id uuid, required : 200 TestCallOut 404 test call not found
409 Conflict
422 caller_id_not_verified

MCP server for AI agents#

A Model Context Protocol server over Streamable HTTP (JSON-RPC 2.0, stateless) that exposes the common steps, from sign-in to a verdict, as tools with descriptions and input schemas. Sign-in is OAuth on the first account tool; credentials travel on the HTTP request, never as tool arguments, and a test call requested this way rings only after a person confirms it in the portal. See the agent guide.

list the tools, then call one with an API key

curl -s -X POST https://ovs.telecomsxchange.com/api/mcp -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'

curl -s -X POST https://ovs.telecomsxchange.com/api/mcp \
  -H "Authorization: Bearer $OVS_KEY" -H 'Content-Type: application/json' \
  -d '{"jsonrpc":"2.0","id":2,"method":"tools/call","params":{"name":"list_calls","arguments":{"origin":"test","limit":5}}}'
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /.well-known/oauth-authorization-server OAuth 2.1 authorization server metadata (RFC 8414) for the MCP endpoint: endpoints, S256 PKCE, dynamic registration, scopes. None
GET /.well-known/oauth-protected-resource Protected resource metadata (RFC 9728): which authorization server guards /api/mcp and the scopes it accepts. None
DELETE /mcp Streamable HTTP session end. The server keeps no session, so this is a no-op that answers 204. None
GET /mcp How to talk to the MCP server: the tool names, the endpoint and the authentication rule. None
POST /mcp The MCP endpoint: JSON-RPC 2.0 initialize, ping, tools/list and tools/call. None
GET /oauth/authorize The consent page: sign in, or create an account, to let the client use it. Returns to the client with a code. None
POST /oauth/authorize The consent form. Not for API clients: the browser posts it. None
POST /oauth/register Dynamic client registration (RFC 7591) for an MCP client: redirect URIs in, client_id out (a secret only for confidential clients). None
POST /oauth/revoke Revoke a refresh token and everything issued with it (RFC 7009). None
POST /oauth/token Exchange a code (with the PKCE verifier) or a refresh token for an access token; refresh tokens rotate. None
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /.well-known/oauth-authorization-server : : 200 JSON object: RFC 8414 authorization server metadata :
GET /.well-known/oauth-protected-resource : : 200 JSON object: RFC 9728 protected resource metadata :
DELETE /mcp : : 204 No content :
GET /mcp : : 200 JSON object: protocol, protocolVersion, transport, endpoint, auth, tools, openapi, docs :
POST /mcp : : 200 JSON-RPC 2.0 response object (result or error) :
GET /oauth/authorize : : 200 text/html: the consent page, or a 302 back to the client :
POST /oauth/authorize : : 200 302 to the client's redirect URI with code and state (or error), or the page again with the reason :
POST /oauth/register : : 201 JSON object: the registered client (client_id, redirect_uris, token_endpoint_auth_method, grant_types; client_secret once, for confidential clients) :
POST /oauth/revoke : : 200 Empty 200 :
POST /oauth/token : : 200 JSON object: access_token, token_type, expires_in, scope, refresh_token :

Plans, balance and payments#

What the plans are, what you are on, what you have spent and how to add credit or subscribe by card.

what the plans cost, and what is left

curl -s https://ovs.telecomsxchange.com/api/plans

curl -s https://ovs.telecomsxchange.com/api/customer/balance -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /ai-modes The AI tiers and their per-call analysis fees. No credentials needed, like /plans. None
PUT /customer/ai-mode Switch the account to another AI tier. Applies to new calls instantly. Bearer or API key
GET /customer/ai-modes The AI tiers with their fees, and which one this account is on. Bearer or API key
GET /customer/balance Current credit, plan and the minutes left in the cycle. Bearer or API key
GET /customer/ledger Every credit and debit on the account, newest first. Bearer or API key
POST /customer/payments/checkout Start a one-off top-up and return the URL to send the browser to. Bearer or API key
GET /customer/payments/config Whether card payment is enabled, and the presets the billing page offers. Bearer or API key
POST /customer/payments/subscribe Start a card subscription to a plan and return the URL to send the browser to. Bearer or API key
POST /customer/plan Move the account to another plan. Bearer or API key
GET /plans The plans on offer, with their prices and included minutes. None
POST /webhooks/stripe Payment-provider callback. Credits a top-up and renews a plan cycle. Not called by you. Provider signature
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /ai-modes : : 200 PublicAiModeOut[] :
PUT /customer/ai-mode : mode string, required 200 AiModePublicOut 422 Validation error
GET /customer/ai-modes : : 200 AiModePublicOut[] :
GET /customer/balance : : 200 BalanceOut :
GET /customer/ledger limit integer, default 50, 1–500
offset integer, default 0, 0–2147483647
: 200 LedgerList :
POST /customer/payments/checkout : amount number or string, required 200 CheckoutSessionOut 409 Conflict
502 Payment provider error
GET /customer/payments/config : : 200 PaymentsPublicConfig :
POST /customer/payments/subscribe : plan_code string, required 200 CheckoutSessionOut 400 Pay-as-you-go has no monthly fee: nothing to subscribe to
404 Plan not found
409 Conflict
502 Payment provider error
POST /customer/plan : plan_code string, required 200 CustomerOut 402 Insufficient balance for the first month's fee
404 Plan not found
409 Already subscribed to this plan
GET /plans : : 200 PlanOut[] :
POST /webhooks/stripe : : 200 JSON object acknowledging the event 400 Invalid signature
409 Conflict

Dashboard, statistics and live calls#

Aggregates for a dashboard, and the calls that are in progress right now.

a week of activity, and what is on the wire now

curl -s "https://ovs.telecomsxchange.com/api/customer/dashboard?days=7" -H "X-API-Key: $OVS_KEY"

curl -s https://ovs.telecomsxchange.com/api/customer/live-calls -H "X-API-Key: $OVS_KEY"
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /customer/dashboard Calls, minutes, spend and risk distribution over the last N days. Bearer or API key
GET /customer/live-calls Calls in progress right now, with elapsed time and the credit countdown. Bearer or API key
GET /customer/stats Headline counters for the account. Bearer or API key
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /customer/dashboard days integer, default 30, 1–366 : 200 CustomerDashboardOut :
GET /customer/live-calls : : 200 LiveCallsOut :
GET /customer/stats from timestamp or null
to timestamp or null
: 200 StatsOut :

Service health#

One unauthenticated endpoint to poll from your own monitoring.

poll from your monitoring

curl -s https://ovs.telecomsxchange.com/api/health
# {"status":"ok",...}
Endpoints in this group. Prefix every path with /api.
MethodPathDoesAuth
GET /health Liveness of the service. No credentials needed. None
Parameters, payloads and the errors each endpoint raises.
EndpointPath and queryRequest bodyReturnsErrors
GET /health : : 200 HealthOut :

Objects#

Every object named above, with its fields as the API returns and accepts them. A field marked or null can be absent.

AiModePublicOut
FieldTypeRequired
modestringyes
analysis_fee_per_callnumberyes
currentbooleandefault false
AiModeUpdate
FieldTypeRequired
modestringyes
AlertRuleCreate
FieldTypeRequired
namestringyes
enabledbooleandefault true
min_probabilityintegerdefault 70
categoriesstring[] or nullno
recommendationsstring[] or nullno
recipientsstring[] or nullno
throttle_minutesintegerdefault 0
include_transcriptbooleandefault false
include_sip_logbooleandefault false
include_pcapbooleandefault false
include_recordingbooleandefault false
triggerstringdefault "fraud"
max_mosnumber or string or nullno
channel_idsuuid[] or nullno
email_enabledbooleandefault true
AlertRuleOut
FieldTypeRequired
iduuidyes
namestringyes
enabledbooleanyes
min_probabilityintegeryes
categoriesstring[] or nullyes
recommendationsstring[] or nullyes
recipientsstring[] or nullyes
throttle_minutesintegeryes
include_transcriptbooleanyes
include_sip_logbooleanyes
include_pcapbooleanyes
include_recordingbooleanyes
triggerstringdefault "fraud"
max_mosnumber or nullno
channel_idsuuid[] or nullno
email_enabledbooleandefault true
created_attimestampyes
updated_attimestampyes
AlertRuleTestOut
FieldTypeRequired
sentbooleanyes
errorstring or nullno
latency_msintegeryes
recipientsstring[]yes
channelsChannelDeliveryOut[]default []
AlertRuleUpdate
FieldTypeRequired
namestring or nullno
enabledboolean or nullno
min_probabilityinteger or nullno
categoriesstring[] or nullno
recommendationsstring[] or nullno
recipientsstring[] or nullno
throttle_minutesinteger or nullno
include_transcriptboolean or nullno
include_sip_logboolean or nullno
include_pcapboolean or nullno
include_recordingboolean or nullno
triggerstring or nullno
max_mosnumber or string or nullno
channel_idsuuid[] or nullno
email_enabledboolean or nullno
AnalysisOut
FieldTypeRequired
iduuidyes
providerstring or nullno
modelstring or nullno
locationstring or nullno
prompt_versionstringyes
titlestring or nullyes
probabilityintegeryes
categorystringyes
entitystring or nullyes
caller_identitystring or nullyes
red_flagsstring[] or nullyes
languagestring or nullyes
tcpa_commentstring or nullyes
summarystring or nullyes
recommendationstringyes
keywordsstring[] or nullyes
route_alertobject or nullno
input_tokensintegeryes
output_tokensintegeryes
costnumberyes
latency_msintegeryes
created_attimestampyes
AnalysisSummary
FieldTypeRequired
titlestring or nullyes
probabilityintegeryes
categorystringyes
recommendationstringyes
red_flagsstring[] or nullyes
entitystring or nullno
keywordsstring[] or nullno
AnalyzeQueued
FieldTypeRequired
job_iduuidyes
analysis_statusstringyes
AniControlList
FieldTypeRequired
totalintegeryes
limitintegeryes
offsetintegeryes
itemsAniControlOut[]yes
AniControlOut
FieldTypeRequired
iduuidyes
anistringyes
actionstringyes
divert_destination_iduuid or nullyes
reasonstring or nullyes
expires_attimestamp or nullyes
released_attimestamp or nullyes
created_attimestampyes
ApiKeyCreate
FieldTypeRequired
namestringyes
ApiKeyCreated
FieldTypeRequired
iduuidyes
namestringyes
prefixstringyes
last_used_attimestamp or nullyes
revoked_attimestamp or nullyes
created_attimestampyes
keystringyes
ApiKeyOut
FieldTypeRequired
iduuidyes
namestringyes
prefixstringyes
last_used_attimestamp or nullyes
revoked_attimestamp or nullyes
created_attimestampyes
AuthConfigOut
FieldTypeRequired
signup_enabledbooleanyes
password_min_lengthintegerdefault 12
access_token_ttl_secintegeryes
session_idle_timeout_minintegerdefault 0
AutomationRuleCreate
FieldTypeRequired
namestringyes
enabledbooleandefault true
min_probabilityintegerdefault 90
recommendationsstring[] or nulldefault ["block"]
action"block" | "divert"default "block"
divert_destination_iduuid or nullno
duration_hoursinteger or nullno
AutomationRuleOut
FieldTypeRequired
iduuidyes
namestringyes
enabledbooleanyes
min_probabilityintegeryes
recommendationsstring[] or nullyes
actionstringyes
divert_destination_iduuid or nullyes
duration_hoursinteger or nullyes
created_attimestampyes
updated_attimestampyes
AutomationRuleUpdate
FieldTypeRequired
namestring or nullno
enabledboolean or nullno
min_probabilityinteger or nullno
recommendationsstring[] or nullno
action"block" | "divert" or nullno
divert_destination_iduuid or nullno
duration_hoursinteger or nullno
clear_durationbooleandefault false
BalanceOut
FieldTypeRequired
balancenumberyes
planstringyes
plan_namestringyes
portsintegeryes
active_callsintegeryes
cycle_minutes_usednumberyes
included_minutesinteger or nullyes
per_minute_ratenumberyes
plan_renews_attimestamp or nullyes
CallDetail
FieldTypeRequired
iduuidyes
sip_call_idstringyes
customer_iduuidyes
originstringdefault "sip"
src_ipstringyes
anistring or nullyes
dialedstring or nullyes
dest_countrystring or nullno
dest_hoststringyes
dest_portintegeryes
dest_transportstringyes
media_ipstring or nullyes
external_idstring or nullno
external_namestring or nullno
sub_customerstring or nullno
dial_prefixstring or nullno
routed_destination_iduuid or nullno
routed_destination_labelstring or nullno
route_prefixstring or nullno
dest_kindstringdefault "sip"
dest_tech_prefixstring or nullno
dest_providerstring or nullno
agent_secondsinteger or nullno
agent_rate_appliednumber or nullno
ai_modestring or nullno
mosnumber or nullno
jitter_msnumber or nullno
packet_loss_pctnumber or nullno
qosobject or nullno
codecstring or nullno
pdd_msinteger or nullno
answer_delay_msinteger or nullno
early_mediaboolean or nullno
hangup_bystring or nullno
q850_causeinteger or nullno
q850_textstring or nullno
directionstringyes
statusstringyes
sip_codeinteger or nullyes
end_reasonstring or nullyes
started_attimestampyes
answered_attimestamp or nullyes
ended_attimestamp or nullyes
duration_secinteger or nullyes
billsecinteger or nullyes
charged_amountnumberyes
rate_appliednumber or nullyes
recording_wav_pathstring or nullyes
recording_availablebooleandefault false
transcript_statusstringyes
analysis_statusstringyes
processingstringdefault "full"
sampledbooleandefault true
transfer_targetstring or nullno
transfer_statusstring or nullno
transfer_codeinteger or nullno
transfer_attimestamp or nullno
transfer_modestring or nullno
transfer_call_iduuid or nullno
dtmfDtmfEventOut[] or nullno
processing_errorstring or nullyes
created_attimestampyes
analysisAnalysisOut or nullno
has_route_alertbooleandefault false
recording_pcap_pathsstring[] or nullyes
captured_headersobject or nullno
case_iduuid or nullno
routed_to_labelstring or nullno
transcriptTranscriptMeta or nullno
transcript_summarystring or nullno
CallInspectOut
FieldTypeRequired
callInspectCallyes
livebooleanyes
ladderSipLogMessage[]yes
signallingInspectSignallingyes
mediaInspectMedia or nullno
qualityInspectQuality or nullno
pipelineInspectPipelineyes
verdictInspectVerdict or nullno
sampled_attimestampyes
CallList
FieldTypeRequired
totalintegeryes
limitintegeryes
offsetintegeryes
itemsCallOut[]yes
CallOut
FieldTypeRequired
iduuidyes
sip_call_idstringyes
customer_iduuidyes
originstringdefault "sip"
src_ipstringyes
anistring or nullyes
dialedstring or nullyes
dest_countrystring or nullno
dest_hoststringyes
dest_portintegeryes
dest_transportstringyes
media_ipstring or nullyes
external_idstring or nullno
external_namestring or nullno
sub_customerstring or nullno
dial_prefixstring or nullno
routed_destination_iduuid or nullno
routed_destination_labelstring or nullno
route_prefixstring or nullno
dest_kindstringdefault "sip"
dest_tech_prefixstring or nullno
dest_providerstring or nullno
agent_secondsinteger or nullno
agent_rate_appliednumber or nullno
ai_modestring or nullno
mosnumber or nullno
jitter_msnumber or nullno
packet_loss_pctnumber or nullno
qosobject or nullno
codecstring or nullno
pdd_msinteger or nullno
answer_delay_msinteger or nullno
early_mediaboolean or nullno
hangup_bystring or nullno
q850_causeinteger or nullno
q850_textstring or nullno
directionstringyes
statusstringyes
sip_codeinteger or nullyes
end_reasonstring or nullyes
started_attimestampyes
answered_attimestamp or nullyes
ended_attimestamp or nullyes
duration_secinteger or nullyes
billsecinteger or nullyes
charged_amountnumberyes
rate_appliednumber or nullyes
recording_wav_pathstring or nullyes
recording_availablebooleandefault false
transcript_statusstringyes
analysis_statusstringyes
processingstringdefault "full"
sampledbooleandefault true
transfer_targetstring or nullno
transfer_statusstring or nullno
transfer_codeinteger or nullno
transfer_attimestamp or nullno
transfer_modestring or nullno
transfer_call_iduuid or nullno
dtmfDtmfEventOut[] or nullno
processing_errorstring or nullyes
created_attimestampyes
analysisAnalysisSummary or nullno
has_route_alertbooleandefault false
CallShareCreated
FieldTypeRequired
iduuidyes
call_iduuidyes
urlstringyes
labelstring or nullyes
created_bystring or nullyes
created_attimestampyes
expires_attimestamp or nullyes
revoked_attimestamp or nullyes
view_countintegeryes
last_viewed_attimestamp or nullyes
activebooleanyes
passwordstringyes
CallShareList
FieldTypeRequired
itemsCallShareOut[]yes
CallShareOut
FieldTypeRequired
iduuidyes
call_iduuidyes
urlstringyes
labelstring or nullyes
created_bystring or nullyes
created_attimestampyes
expires_attimestamp or nullyes
revoked_attimestamp or nullyes
view_countintegeryes
last_viewed_attimestamp or nullyes
activebooleanyes
CallsPerDay
FieldTypeRequired
datestringyes
callsintegeryes
high_riskintegeryes
CaseCommentCreate
FieldTypeRequired
bodystringyes
CaseCommentOut
FieldTypeRequired
iduuidyes
author_kindstringyes
author_labelstring or nullyes
bodystringyes
created_attimestampyes
CaseCreate
FieldTypeRequired
titlestringyes
descriptionstring or nullno
severity"low" | "medium" | "high" | "critical"default "medium"
call_iduuid or nullno
CaseDetail
FieldTypeRequired
iduuidyes
case_nointegeryes
customer_iduuidyes
call_iduuid or nullyes
titlestringyes
descriptionstring or nullyes
statusstringyes
severitystringyes
created_bystring or nullyes
assigned_touuid or nullyes
created_attimestampyes
updated_attimestampyes
assigned_to_labelstring or nullno
comment_countintegerdefault 0
commentsCaseCommentOut[]default []
callCallOut or nullno
CaseList
FieldTypeRequired
totalintegeryes
limitintegeryes
offsetintegeryes
itemsCaseOut[]yes
CaseOut
FieldTypeRequired
iduuidyes
case_nointegeryes
customer_iduuidyes
call_iduuid or nullyes
titlestringyes
descriptionstring or nullyes
statusstringyes
severitystringyes
created_bystring or nullyes
assigned_touuid or nullyes
created_attimestampyes
updated_attimestampyes
assigned_to_labelstring or nullno
comment_countintegerdefault 0
CaseUpdate
FieldTypeRequired
titlestring or nullno
descriptionstring or nullno
status"open" | "in_review" | "resolved" | "dismissed" or nullno
severity"low" | "medium" | "high" | "critical" or nullno
assigned_touuid or nullno
clear_assigned_tobooleandefault false
ChangePasswordRequest
FieldTypeRequired
current_passwordstringyes
new_passwordstringyes
ChannelDeliveryOut
FieldTypeRequired
iduuidyes
kindstringyes
labelstringyes
sentbooleanyes
errorstring or nullno
latency_msintegerdefault 0
CheckoutRequest
FieldTypeRequired
amountnumber or stringyes
CheckoutSessionOut
FieldTypeRequired
session_idstringyes
urlstringyes
CountryCount
FieldTypeRequired
codestring or nullyes
namestringyes
isobooleanyes
countintegeryes
CustomerDashboardOut
FieldTypeRequired
daysintegeryes
fromtimestampyes
totimestampyes
calls_todayintegeryes
calls_periodintegeryes
minutes_periodnumberyes
spend_periodnumberyes
high_risk_pctnumberyes
risk_distributionRiskBucket[]yes
calls_per_dayCallsPerDay[]yes
spend_per_daySpendPerDay[]yes
calls_by_countryCountryCount[]yes
recent_high_riskCallOut[]yes
balancenumberyes
planDashboardPlanyes
cycle_minutes_usednumberyes
active_callsintegeryes
CustomerOut
FieldTypeRequired
iduuidyes
emailstringyes
companystring or nullyes
phonestring or nullno
tax_idstring or nullno
countrystring or nullno
provincestring or nullno
rolestringyes
statusstringyes
must_change_passwordbooleandefault false
balancenumberyes
plan_codestringyes
portsintegeryes
plan_started_attimestamp or nullyes
plan_renews_attimestamp or nullyes
cycle_minutes_usednumberyes
webhook_urlstring or nullyes
created_attimestampyes
twofa_enabledbooleandefault false
dialer_enabledbooleanno
ai_modestringdefault "power"
data_regionstringdefault "ca"
media_regionstringdefault "ca"
impersonated_bystring or nullno
pilotPilotStatus or nullno
profileCustomerProfileOut or nullno
terms_versionstring or nullno
terms_current_versionstringno
CustomerProfileOut
FieldTypeRequired
switch_vendorstring or nullno
expected_volumestring or nullno
contact_rolestring or nullno
regionstring or nullno
referral_sourcestring or nullno
phonestring or nullno
profile_completed_attimestamp or nullno
CustomerUserInvite
FieldTypeRequired
emailemailyes
namestring or nullno
CustomerUserInvited
FieldTypeRequired
userCustomerUserOutyes
welcome_emailWelcomeEmailStatus or nullno
CustomerUserList
FieldTypeRequired
itemsCustomerUserOut[]yes
max_usersintegerdefault 10
CustomerUserOut
FieldTypeRequired
iduuidyes
emailstringyes
namestring or nullyes
rolestringyes
is_activebooleanyes
must_change_passwordbooleandefault false
last_login_attimestamp or nullyes
last_login_ipstring or nullno
created_attimestampyes
CustomerUserUpdate
FieldTypeRequired
namestring or nullno
is_activeboolean or nullno
DashboardPlan
FieldTypeRequired
codestringyes
namestringyes
portsintegeryes
included_minutesinteger or nullyes
renews_attimestamp or nullyes
DestinationCreate
FieldTypeRequired
hoststringyes
portintegerdefault 5060
transport"udp" | "tcp" | "tls"default "udp"
is_defaultbooleandefault false
labelstring or nullno
kind"sip" | "voice_ai"default "sip"
providerstring or nullno
agent_idstring or nullno
configobject or nullno
tech_prefixstring or nullno
monitor_enabledboolean or nullno
processingstring or nullno
sample_rateinteger or nullno
sample_modestring or nullno
transfer_modestring or nullno
auth_usernamestring or nullno
auth_passwordstring or nullno
auth_realmstring or nullno
webhook_secretstring or nullno
provider_api_keystring or nullno
DestinationOut
FieldTypeRequired
iduuidyes
hoststringyes
portintegeryes
transportstringyes
is_defaultbooleanyes
labelstring or nullyes
kindstringyes
providerstring or nullyes
agent_idstring or nullyes
configobject or nullyes
tech_prefixstring or nullyes
has_credentialbooleandefault false
needs_credentialbooleandefault false
webhook_urlstring or nullno
has_webhook_secretbooleandefault false
has_provider_keybooleandefault false
needs_webhookbooleandefault false
webhook_last_event_attimestamp or nullno
webhook_last_statusstring or nullno
webhook_last_errorstring or nullno
monitor_enabledbooleandefault false
processingstringdefault "full"
sample_rateintegerdefault 1
sample_modestringdefault "analyse"
transfer_modestringdefault "platform"
monitor_supportedboolean or nullno
monitor_statusstringdefault "unknown"
monitor_last_check_attimestamp or nullno
monitor_last_change_attimestamp or nullno
monitor_rtt_msinteger or nullno
monitor_last_codeinteger or nullno
monitor_last_errorstring or nullno
created_attimestampyes
DestinationUpdate
FieldTypeRequired
hoststring or nullno
portinteger or nullno
transport"udp" | "tcp" | "tls" or nullno
is_defaultboolean or nullno
labelstring or nullno
kind"sip" | "voice_ai" or nullno
providerstring or nullno
agent_idstring or nullno
configobject or nullno
tech_prefixstring or nullno
monitor_enabledboolean or nullno
processingstring or nullno
sample_rateinteger or nullno
sample_modestring or nullno
transfer_modestring or nullno
auth_usernamestring or nullno
auth_passwordstring or nullno
auth_realmstring or nullno
clear_credentialboolean or nullno
webhook_secretstring or nullno
provider_api_keystring or nullno
clear_webhook_secretboolean or nullno
clear_provider_keyboolean or nullno
rotate_webhook_tokenboolean or nullno
DtmfEventOut
FieldTypeRequired
tnumberyes
digitstringyes
channelstringdefault "caller"
msinteger or nullno
sourcestring or nullno
EntityCount
FieldTypeRequired
entitystringyes
countintegeryes
HealthOut
FieldTypeRequired
statusstringyes
dbbooleanyes
versionstringyes
InspectCall
FieldTypeRequired
iduuidyes
statusstringyes
anistring or nullyes
dialedstring or nullyes
external_idstring or nullyes
external_namestring or nullyes
sub_customerstring or nullno
dest_hoststringyes
dest_portintegeryes
dest_transportstringyes
dest_kindstringyes
dest_providerstring or nullno
routed_destination_labelstring or nullno
route_prefixstring or nullyes
media_nodestring or nullyes
started_attimestampyes
answered_attimestamp or nullyes
elapsed_secintegeryes
max_call_secondsinteger or nullyes
remaining_secinteger or nullyes
src_ipstringyes
ended_attimestamp or nullno
duration_secinteger or nullno
billsecinteger or nullno
sip_codeinteger or nullno
end_reasonstring or nullno
hangup_bystring or nullno
q850_causeinteger or nullno
q850_textstring or nullno
InspectLeg
FieldTypeRequired
endpointstring or nullno
packetsintegerdefault 0
bytesintegerdefault 0
errorsintegerdefault 0
last_packetinteger or nullno
ssrcinteger or nullno
lostinteger or nullno
loss_pctnumber or nullno
jitter_msnumber or nullno
rtt_msnumber or nullno
mosnumber or nullno
InspectMedia
FieldTypeRequired
sampled_attimestampyes
legsobjectyes
InspectPipeline
FieldTypeRequired
transcript_statusstringyes
analysis_statusstringyes
processingstringdefault "full"
sampledbooleandefault true
processing_errorstring or nullno
InspectQuality
FieldTypeRequired
mosnumber or nullno
jitter_msnumber or nullno
packet_loss_pctnumber or nullno
legsobject or nullno
InspectSignalling
FieldTypeRequired
pdd_msinteger or nullno
answer_delay_msinteger or nullno
early_mediaboolean or nullno
codecstring or nullno
InspectVerdict
FieldTypeRequired
titlestring or nullno
probabilityintegeryes
categorystring or nullno
recommendationstringyes
summarystring or nullno
IpCreate
FieldTypeRequired
cidrstringyes
labelstring or nullno
dial_prefixstring or nullno
destination_iduuid or nullno
enabledbooleandefault true
IpOut
FieldTypeRequired
iduuidyes
cidrstringyes
labelstring or nullyes
dial_prefixstring or nullno
destination_iduuid or nullyes
enabledbooleanyes
created_attimestampyes
IpUpdate
FieldTypeRequired
labelstring or nullno
dial_prefixstring or nullno
destination_iduuid or nullno
enabledboolean or nullno
KeywordCount
FieldTypeRequired
keywordstringyes
countintegeryes
LeadCreate
FieldTypeRequired
namestringyes
emailemailyes
companystring or nullno
platformstring or nullno
volumestring or nullno
messagestring or nullno
pagestring or nullno
attributionobject or nullno
websitestring or nullno
LedgerList
FieldTypeRequired
totalintegeryes
limitintegeryes
offsetintegeryes
itemsLedgerOut[]yes
LedgerOut
FieldTypeRequired
iduuidyes
typestringyes
amountnumberyes
balance_afternumberyes
call_iduuid or nullyes
descriptionstring or nullyes
waived_amountnumberdefault 0
created_attimestampyes
LiveCall
FieldTypeRequired
iduuidyes
statusstringyes
anistring or nullyes
dialedstring or nullyes
external_idstring or nullyes
external_namestring or nullyes
sub_customerstring or nullno
dest_hoststringyes
dest_portintegeryes
dest_transportstringyes
dest_kindstringyes
dest_providerstring or nullno
routed_destination_labelstring or nullno
route_prefixstring or nullyes
media_nodestring or nullyes
started_attimestampyes
answered_attimestamp or nullyes
elapsed_secintegeryes
max_call_secondsinteger or nullyes
remaining_secinteger or nullyes
LiveCallsOut
FieldTypeRequired
itemsLiveCall[]yes
active_countintegeryes
portsintegeryes
ports_in_useintegeryes
LoginRequest
FieldTypeRequired
emailemailyes
passwordstringyes
MediaTokenOut
FieldTypeRequired
urlstringyes
expires_inintegeryes
NetworkInfoOut
FieldTypeRequired
ingress_hoststringyes
ingress_portintegerdefault 5060
transportsstring[]default ["udp","tcp"]
PasskeyEnrollLoginRequest
FieldTypeRequired
enroll_tokenstringyes
credentialobjectyes
namestring or nullno
PasskeyLoginRequest
FieldTypeRequired
login_tokenstringyes
assertionobjectyes
PasskeyOut
FieldTypeRequired
iduuidyes
namestringyes
transportsstring[] or nullno
created_attimestampyes
last_used_attimestamp or nullyes
PasskeyRegisterBeginOut
FieldTypeRequired
optionsobjectyes
statestringyes
PasskeyRegisterComplete
FieldTypeRequired
credentialobjectyes
statestringyes
namestring or nullno
PasskeyRename
FieldTypeRequired
namestringyes
PaymentsPublicConfig
FieldTypeRequired
enabledbooleanyes
publishable_keystringyes
currencystringyes
preset_amountsinteger[]default [25,50,100,250]
min_custom_amountintegerdefault 10
PilotStatus
FieldTypeRequired
activebooleandefault false
started_attimestamp or nullno
ends_attimestamp or nullno
days_leftintegerdefault 0
minutes_limitinteger or nullno
minutes_usednumberdefault 0
exhaustedbooleandefault false
waived_totalnumberdefault 0
PlanChange
FieldTypeRequired
plan_codestringyes
PlanOut
FieldTypeRequired
codestringyes
namestringyes
monthly_feenumberyes
portsintegeryes
included_minutesinteger or nullyes
per_minute_ratenumberyes
min_billable_secondsintegeryes
activebooleanyes
descriptionstring or nullyes
PublicAiModeOut
FieldTypeRequired
modestringyes
analysis_fee_per_callnumberyes
PublicShareAnalysis
FieldTypeRequired
titlestring or nullno
probabilityinteger or nullno
categorystring or nullno
entitystring or nullno
red_flagsstring[] or nullno
tcpa_commentstring or nullno
summarystring or nullno
recommendationstring or nullno
PublicShareCall
FieldTypeRequired
dialedstring or nullno
anistring or nullno
directionstring or nullno
started_attimestamp or nullno
duration_secinteger or nullno
PublicSharePayload
FieldTypeRequired
shared_bystring or nullno
shared_attimestamp or nullno
labelstring or nullno
expires_attimestamp or nullno
callPublicShareCallyes
analysisPublicShareAnalysis or nullno
transcriptPublicShareTranscript or nullno
has_recordingbooleandefault false
PublicShareTranscript
FieldTypeRequired
textstringdefault ""
segmentsobject[] or nullno
RiskBucket
FieldTypeRequired
bucket"0-29" | "30-69" | "70-100"yes
countintegeryes
RoutingRuleCreate
FieldTypeRequired
prefixstringyes
destination_iduuidyes
enabledbooleandefault true
priorityintegerdefault 100
labelstring or nullno
RoutingRuleOut
FieldTypeRequired
iduuidyes
prefixstringyes
destination_iduuidyes
enabledbooleanyes
priorityintegeryes
labelstring or nullyes
created_attimestampyes
updated_attimestampyes
RoutingRuleUpdate
FieldTypeRequired
prefixstring or nullno
destination_iduuid or nullno
enabledboolean or nullno
priorityinteger or nullno
labelstring or nullno
SessionCustomer
FieldTypeRequired
iduuidyes
emailstringyes
companystring or nullyes
phonestring or nullno
rolestringyes
must_change_passwordbooleandefault false
dialer_enabledbooleanno
ai_modestringdefault "power"
statusstringyes
ShareCreate
FieldTypeRequired
expires_in_hoursinteger or nullno
labelstring or nullno
ShareMetaOut
FieldTypeRequired
existsbooleanyes
requires_passwordbooleandefault true
revokedbooleandefault false
expiredbooleandefault false
company_namestring or nullno
ShareUnlockOut
FieldTypeRequired
view_tokenstringyes
expires_inintegeryes
ShareUnlockRequest
FieldTypeRequired
passwordstringyes
SignupRequest
FieldTypeRequired
emailemailyes
passwordstringyes
companystring or nullno
full_namestring or nullno
attributionobject or nullno
accept_termsbooleandefault false
SignupResponse
FieldTypeRequired
customerCustomerOutyes
access_tokenstringyes
token_typestringdefault "bearer"
expires_inintegeryes
SipLogMessage
FieldTypeRequired
time_stamptimestampyes
directionstringyes
methodstringyes
statusstring or nullno
fromipstringyes
toipstringyes
fromtagstring or nullno
totagstring or nullno
first_linestringyes
headersobject or nullno
SipLogOut
FieldTypeRequired
call_iduuidyes
sip_call_idstringyes
messagesSipLogMessage[]yes
textstringyes
SpendPerDay
FieldTypeRequired
datestringyes
spendnumberyes
StatsOut
FieldTypeRequired
fromtimestamp or nullno
totimestamp or nullno
callsintegeryes
answered_callsintegeryes
minutesnumberyes
spendnumberyes
by_categoryobjectyes
by_recommendationobjectyes
avg_probabilitynumber or nullyes
TestCallCreate
FieldTypeRequired
numberstringyes
destination_iduuid or nullno
caller_idstring or nullno
secondsintegerdefault 30
speechstringdefault "route_test"
agent_destination_iduuid or nullno
instructionstring or nullno
TestCallOut
FieldTypeRequired
iduuidyes
statusstringyes
numberstringyes
caller_idstring or nullno
destination_iduuid or nullno
secondsintegeryes
speechstringyes
sip_call_idstringyes
call_iduuid or nullno
agent_destination_iduuid or nullno
instructionstring or nullno
agent_sip_call_idstring or nullno
agent_call_iduuid or nullno
answeredboolean or nullno
sip_codeinteger or nullno
sip_reasonstring or nullno
talk_secondsnumber or nullno
ended_bystring or nullno
errorstring or nullno
purposestringdefault "test"
created_bystring or nullno
confirmed_attimestamp or nullno
confirmed_bystring or nullno
confirm_urlstring or nullno
confirm_expires_attimestamp or nullno
created_attimestampyes
updated_attimestampyes
TicketCreate
FieldTypeRequired
kind"question" | "bug" | "feature" | "analysis" | "billing"default "question"
subjectstringyes
bodystringyes
call_iduuid or nullno
TicketDetail
FieldTypeRequired
iduuidyes
ticket_nointegeryes
customer_iduuidyes
kindstringyes
subjectstringyes
bodystringyes
call_iduuid or nullyes
statusstringyes
created_bystring or nullyes
closed_attimestamp or nullyes
created_attimestampyes
updated_attimestampyes
message_countintegerdefault 0
messagesTicketMessageOut[]default []
callCallOut or nullno
TicketList
FieldTypeRequired
totalintegeryes
limitintegeryes
offsetintegeryes
itemsTicketOut[]yes
TicketMessageCreate
FieldTypeRequired
bodystringyes
TicketMessageOut
FieldTypeRequired
iduuidyes
author_kindstringyes
author_labelstring or nullyes
bodystringyes
created_attimestampyes
TicketOut
FieldTypeRequired
iduuidyes
ticket_nointegeryes
customer_iduuidyes
kindstringyes
subjectstringyes
bodystringyes
call_iduuid or nullyes
statusstringyes
created_bystring or nullyes
closed_attimestamp or nullyes
created_attimestampyes
updated_attimestampyes
message_countintegerdefault 0
TicketStatusUpdate
FieldTypeRequired
status"open" | "answered" | "closed"yes
TokenResponse
FieldTypeRequired
access_tokenstringyes
token_typestringdefault "bearer"
expires_inintegeryes
customerSessionCustomer or nullno
TranscriptMeta
FieldTypeRequired
iduuidyes
providerstring or nullno
modelstring or nullno
locationstring or nullno
languagestring or nullyes
audio_secondsnumber or nullyes
costnumberyes
created_attimestampyes
TranscriptOut
FieldTypeRequired
iduuidyes
providerstring or nullno
modelstring or nullno
locationstring or nullno
languagestring or nullyes
textstringyes
segmentsobject[] or nullyes
audio_secondsnumber or nullyes
costnumberyes
created_attimestampyes
TransferQueued
FieldTypeRequired
statusstringyes
targetstringyes
modestringyes
TransferRequest
FieldTypeRequired
targetstringyes
WebhookOut
FieldTypeRequired
urlstring or nullyes
secret_setbooleanyes
WebhookTestOut
FieldTypeRequired
deliveredbooleanyes
status_codeinteger or nullno
errorstring or nullno
latency_msintegeryes
WebhookUpdate
FieldTypeRequired
urlstring or nullno
secretstring or nullno
WelcomeEmailStatus
FieldTypeRequired
sentbooleandefault false
errorstring or nullno
skipped_reasonstring or nullno

Generated from the platform's own API schema on 2026-10-02: 116 operations over 94 paths, and 121 objects. Operator-only endpoints are not part of this reference and never appear here.