Documentation
API reference
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.
| Code | Means | What to do |
|---|---|---|
| 401 | Not authenticated | The token expired, the key is wrong or was revoked. Refresh or re-issue. |
| 403 | Forbidden | The credential is valid but not allowed here: a member on an owner-only route, or a suspended account. |
| 404 | Not found | No such record on your account. Another account's record is a 404, never a 403. |
| 409 | Conflict | The request contradicts what exists: a duplicate, or a state that does not allow it. |
| 422 | Validation error | A field is missing or out of range. The body names the field. |
| 429 | Too many requests | Back 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}
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"}'
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"}'
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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."}'
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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",...}
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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}}}'
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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"
| Method | Path | Does | Auth |
|---|---|---|---|
| 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 |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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",...}
| Method | Path | Does | Auth |
|---|---|---|---|
| GET | /health | Liveness of the service. No credentials needed. | None |
| Endpoint | Path and query | Request body | Returns | Errors |
|---|---|---|---|---|
| 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.
| Field | Type | Required |
|---|---|---|
| mode | string | yes |
| analysis_fee_per_call | number | yes |
| current | boolean | default false |
| Field | Type | Required |
|---|---|---|
| mode | string | yes |
| Field | Type | Required |
|---|---|---|
| name | string | yes |
| enabled | boolean | default true |
| min_probability | integer | default 70 |
| categories | string[] or null | no |
| recommendations | string[] or null | no |
| recipients | string[] or null | no |
| 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 | no |
| channel_ids | uuid[] or null | no |
| email_enabled | boolean | default true |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| name | string | yes |
| enabled | boolean | yes |
| min_probability | integer | yes |
| categories | string[] or null | yes |
| recommendations | string[] or null | yes |
| recipients | string[] or null | yes |
| throttle_minutes | integer | yes |
| include_transcript | boolean | yes |
| include_sip_log | boolean | yes |
| include_pcap | boolean | yes |
| include_recording | boolean | yes |
| trigger | string | default "fraud" |
| max_mos | number or null | no |
| channel_ids | uuid[] or null | no |
| email_enabled | boolean | default true |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| sent | boolean | yes |
| error | string or null | no |
| latency_ms | integer | yes |
| recipients | string[] | yes |
| channels | ChannelDeliveryOut[] | default [] |
| Field | Type | Required |
|---|---|---|
| name | string or null | no |
| enabled | boolean or null | no |
| min_probability | integer or null | no |
| categories | string[] or null | no |
| recommendations | string[] or null | no |
| recipients | string[] or null | no |
| throttle_minutes | integer or null | no |
| include_transcript | boolean or null | no |
| include_sip_log | boolean or null | no |
| include_pcap | boolean or null | no |
| include_recording | boolean or null | no |
| trigger | string or null | no |
| max_mos | number or string or null | no |
| channel_ids | uuid[] or null | no |
| email_enabled | boolean or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| provider | string or null | no |
| model | string or null | no |
| location | string or null | no |
| prompt_version | string | yes |
| title | string or null | yes |
| probability | integer | yes |
| category | string | yes |
| entity | string or null | yes |
| caller_identity | string or null | yes |
| red_flags | string[] or null | yes |
| language | string or null | yes |
| tcpa_comment | string or null | yes |
| summary | string or null | yes |
| recommendation | string | yes |
| keywords | string[] or null | yes |
| route_alert | object or null | no |
| input_tokens | integer | yes |
| output_tokens | integer | yes |
| cost | number | yes |
| latency_ms | integer | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| title | string or null | yes |
| probability | integer | yes |
| category | string | yes |
| recommendation | string | yes |
| red_flags | string[] or null | yes |
| entity | string or null | no |
| keywords | string[] or null | no |
| Field | Type | Required |
|---|---|---|
| job_id | uuid | yes |
| analysis_status | string | yes |
| Field | Type | Required |
|---|---|---|
| total | integer | yes |
| limit | integer | yes |
| offset | integer | yes |
| items | AniControlOut[] | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| ani | string | yes |
| action | string | yes |
| divert_destination_id | uuid or null | yes |
| reason | string or null | yes |
| expires_at | timestamp or null | yes |
| released_at | timestamp or null | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| name | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| name | string | yes |
| prefix | string | yes |
| last_used_at | timestamp or null | yes |
| revoked_at | timestamp or null | yes |
| created_at | timestamp | yes |
| key | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| name | string | yes |
| prefix | string | yes |
| last_used_at | timestamp or null | yes |
| revoked_at | timestamp or null | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| signup_enabled | boolean | yes |
| password_min_length | integer | default 12 |
| access_token_ttl_sec | integer | yes |
| session_idle_timeout_min | integer | default 0 |
| Field | Type | Required |
|---|---|---|
| name | string | yes |
| 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 | no |
| duration_hours | integer or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| name | string | yes |
| enabled | boolean | yes |
| min_probability | integer | yes |
| recommendations | string[] or null | yes |
| action | string | yes |
| divert_destination_id | uuid or null | yes |
| duration_hours | integer or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| name | string or null | no |
| enabled | boolean or null | no |
| min_probability | integer or null | no |
| recommendations | string[] or null | no |
| action | "block" | "divert" or null | no |
| divert_destination_id | uuid or null | no |
| duration_hours | integer or null | no |
| clear_duration | boolean | default false |
| Field | Type | Required |
|---|---|---|
| balance | number | yes |
| plan | string | yes |
| plan_name | string | yes |
| ports | integer | yes |
| active_calls | integer | yes |
| cycle_minutes_used | number | yes |
| included_minutes | integer or null | yes |
| per_minute_rate | number | yes |
| plan_renews_at | timestamp or null | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| sip_call_id | string | yes |
| customer_id | uuid | yes |
| origin | string | default "sip" |
| src_ip | string | yes |
| ani | string or null | yes |
| dialed | string or null | yes |
| dest_country | string or null | no |
| dest_host | string | yes |
| dest_port | integer | yes |
| dest_transport | string | yes |
| media_ip | string or null | yes |
| external_id | string or null | no |
| external_name | string or null | no |
| sub_customer | string or null | no |
| dial_prefix | string or null | no |
| routed_destination_id | uuid or null | no |
| routed_destination_label | string or null | no |
| route_prefix | string or null | no |
| dest_kind | string | default "sip" |
| dest_tech_prefix | string or null | no |
| dest_provider | string or null | no |
| agent_seconds | integer or null | no |
| agent_rate_applied | number or null | no |
| ai_mode | string or null | no |
| mos | number or null | no |
| jitter_ms | number or null | no |
| packet_loss_pct | number or null | no |
| qos | object or null | no |
| codec | string or null | no |
| pdd_ms | integer or null | no |
| answer_delay_ms | integer or null | no |
| early_media | boolean or null | no |
| hangup_by | string or null | no |
| q850_cause | integer or null | no |
| q850_text | string or null | no |
| direction | string | yes |
| status | string | yes |
| sip_code | integer or null | yes |
| end_reason | string or null | yes |
| started_at | timestamp | yes |
| answered_at | timestamp or null | yes |
| ended_at | timestamp or null | yes |
| duration_sec | integer or null | yes |
| billsec | integer or null | yes |
| charged_amount | number | yes |
| rate_applied | number or null | yes |
| recording_wav_path | string or null | yes |
| recording_available | boolean | default false |
| transcript_status | string | yes |
| analysis_status | string | yes |
| processing | string | default "full" |
| sampled | boolean | default true |
| transfer_target | string or null | no |
| transfer_status | string or null | no |
| transfer_code | integer or null | no |
| transfer_at | timestamp or null | no |
| transfer_mode | string or null | no |
| transfer_call_id | uuid or null | no |
| dtmf | DtmfEventOut[] or null | no |
| processing_error | string or null | yes |
| created_at | timestamp | yes |
| analysis | AnalysisOut or null | no |
| has_route_alert | boolean | default false |
| recording_pcap_paths | string[] or null | yes |
| captured_headers | object or null | no |
| case_id | uuid or null | no |
| routed_to_label | string or null | no |
| transcript | TranscriptMeta or null | no |
| transcript_summary | string or null | no |
| Field | Type | Required |
|---|---|---|
| call | InspectCall | yes |
| live | boolean | yes |
| ladder | SipLogMessage[] | yes |
| signalling | InspectSignalling | yes |
| media | InspectMedia or null | no |
| quality | InspectQuality or null | no |
| pipeline | InspectPipeline | yes |
| verdict | InspectVerdict or null | no |
| sampled_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| total | integer | yes |
| limit | integer | yes |
| offset | integer | yes |
| items | CallOut[] | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| sip_call_id | string | yes |
| customer_id | uuid | yes |
| origin | string | default "sip" |
| src_ip | string | yes |
| ani | string or null | yes |
| dialed | string or null | yes |
| dest_country | string or null | no |
| dest_host | string | yes |
| dest_port | integer | yes |
| dest_transport | string | yes |
| media_ip | string or null | yes |
| external_id | string or null | no |
| external_name | string or null | no |
| sub_customer | string or null | no |
| dial_prefix | string or null | no |
| routed_destination_id | uuid or null | no |
| routed_destination_label | string or null | no |
| route_prefix | string or null | no |
| dest_kind | string | default "sip" |
| dest_tech_prefix | string or null | no |
| dest_provider | string or null | no |
| agent_seconds | integer or null | no |
| agent_rate_applied | number or null | no |
| ai_mode | string or null | no |
| mos | number or null | no |
| jitter_ms | number or null | no |
| packet_loss_pct | number or null | no |
| qos | object or null | no |
| codec | string or null | no |
| pdd_ms | integer or null | no |
| answer_delay_ms | integer or null | no |
| early_media | boolean or null | no |
| hangup_by | string or null | no |
| q850_cause | integer or null | no |
| q850_text | string or null | no |
| direction | string | yes |
| status | string | yes |
| sip_code | integer or null | yes |
| end_reason | string or null | yes |
| started_at | timestamp | yes |
| answered_at | timestamp or null | yes |
| ended_at | timestamp or null | yes |
| duration_sec | integer or null | yes |
| billsec | integer or null | yes |
| charged_amount | number | yes |
| rate_applied | number or null | yes |
| recording_wav_path | string or null | yes |
| recording_available | boolean | default false |
| transcript_status | string | yes |
| analysis_status | string | yes |
| processing | string | default "full" |
| sampled | boolean | default true |
| transfer_target | string or null | no |
| transfer_status | string or null | no |
| transfer_code | integer or null | no |
| transfer_at | timestamp or null | no |
| transfer_mode | string or null | no |
| transfer_call_id | uuid or null | no |
| dtmf | DtmfEventOut[] or null | no |
| processing_error | string or null | yes |
| created_at | timestamp | yes |
| analysis | AnalysisSummary or null | no |
| has_route_alert | boolean | default false |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| call_id | uuid | yes |
| url | string | yes |
| label | string or null | yes |
| created_by | string or null | yes |
| created_at | timestamp | yes |
| expires_at | timestamp or null | yes |
| revoked_at | timestamp or null | yes |
| view_count | integer | yes |
| last_viewed_at | timestamp or null | yes |
| active | boolean | yes |
| password | string | yes |
| Field | Type | Required |
|---|---|---|
| items | CallShareOut[] | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| call_id | uuid | yes |
| url | string | yes |
| label | string or null | yes |
| created_by | string or null | yes |
| created_at | timestamp | yes |
| expires_at | timestamp or null | yes |
| revoked_at | timestamp or null | yes |
| view_count | integer | yes |
| last_viewed_at | timestamp or null | yes |
| active | boolean | yes |
| Field | Type | Required |
|---|---|---|
| date | string | yes |
| calls | integer | yes |
| high_risk | integer | yes |
| Field | Type | Required |
|---|---|---|
| body | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| author_kind | string | yes |
| author_label | string or null | yes |
| body | string | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| title | string | yes |
| description | string or null | no |
| severity | "low" | "medium" | "high" | "critical" | default "medium" |
| call_id | uuid or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| case_no | integer | yes |
| customer_id | uuid | yes |
| call_id | uuid or null | yes |
| title | string | yes |
| description | string or null | yes |
| status | string | yes |
| severity | string | yes |
| created_by | string or null | yes |
| assigned_to | uuid or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| assigned_to_label | string or null | no |
| comment_count | integer | default 0 |
| comments | CaseCommentOut[] | default [] |
| call | CallOut or null | no |
| Field | Type | Required |
|---|---|---|
| total | integer | yes |
| limit | integer | yes |
| offset | integer | yes |
| items | CaseOut[] | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| case_no | integer | yes |
| customer_id | uuid | yes |
| call_id | uuid or null | yes |
| title | string | yes |
| description | string or null | yes |
| status | string | yes |
| severity | string | yes |
| created_by | string or null | yes |
| assigned_to | uuid or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| assigned_to_label | string or null | no |
| comment_count | integer | default 0 |
| Field | Type | Required |
|---|---|---|
| title | string or null | no |
| description | string or null | no |
| status | "open" | "in_review" | "resolved" | "dismissed" or null | no |
| severity | "low" | "medium" | "high" | "critical" or null | no |
| assigned_to | uuid or null | no |
| clear_assigned_to | boolean | default false |
| Field | Type | Required |
|---|---|---|
| current_password | string | yes |
| new_password | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| kind | string | yes |
| label | string | yes |
| sent | boolean | yes |
| error | string or null | no |
| latency_ms | integer | default 0 |
| Field | Type | Required |
|---|---|---|
| amount | number or string | yes |
| Field | Type | Required |
|---|---|---|
| session_id | string | yes |
| url | string | yes |
| Field | Type | Required |
|---|---|---|
| code | string or null | yes |
| name | string | yes |
| iso | boolean | yes |
| count | integer | yes |
| Field | Type | Required |
|---|---|---|
| days | integer | yes |
| from | timestamp | yes |
| to | timestamp | yes |
| calls_today | integer | yes |
| calls_period | integer | yes |
| minutes_period | number | yes |
| spend_period | number | yes |
| high_risk_pct | number | yes |
| risk_distribution | RiskBucket[] | yes |
| calls_per_day | CallsPerDay[] | yes |
| spend_per_day | SpendPerDay[] | yes |
| calls_by_country | CountryCount[] | yes |
| recent_high_risk | CallOut[] | yes |
| balance | number | yes |
| plan | DashboardPlan | yes |
| cycle_minutes_used | number | yes |
| active_calls | integer | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| string | yes | |
| company | string or null | yes |
| phone | string or null | no |
| tax_id | string or null | no |
| country | string or null | no |
| province | string or null | no |
| role | string | yes |
| status | string | yes |
| must_change_password | boolean | default false |
| balance | number | yes |
| plan_code | string | yes |
| ports | integer | yes |
| plan_started_at | timestamp or null | yes |
| plan_renews_at | timestamp or null | yes |
| cycle_minutes_used | number | yes |
| webhook_url | string or null | yes |
| created_at | timestamp | yes |
| twofa_enabled | boolean | default false |
| dialer_enabled | boolean | no |
| ai_mode | string | default "power" |
| data_region | string | default "ca" |
| media_region | string | default "ca" |
| impersonated_by | string or null | no |
| pilot | PilotStatus or null | no |
| profile | CustomerProfileOut or null | no |
| terms_version | string or null | no |
| terms_current_version | string | no |
| Field | Type | Required |
|---|---|---|
| switch_vendor | string or null | no |
| expected_volume | string or null | no |
| contact_role | string or null | no |
| region | string or null | no |
| referral_source | string or null | no |
| phone | string or null | no |
| profile_completed_at | timestamp or null | no |
| Field | Type | Required |
|---|---|---|
| yes | ||
| name | string or null | no |
| Field | Type | Required |
|---|---|---|
| user | CustomerUserOut | yes |
| welcome_email | WelcomeEmailStatus or null | no |
| Field | Type | Required |
|---|---|---|
| items | CustomerUserOut[] | yes |
| max_users | integer | default 10 |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| string | yes | |
| name | string or null | yes |
| role | string | yes |
| is_active | boolean | yes |
| must_change_password | boolean | default false |
| last_login_at | timestamp or null | yes |
| last_login_ip | string or null | no |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| name | string or null | no |
| is_active | boolean or null | no |
| Field | Type | Required |
|---|---|---|
| code | string | yes |
| name | string | yes |
| ports | integer | yes |
| included_minutes | integer or null | yes |
| renews_at | timestamp or null | yes |
| Field | Type | Required |
|---|---|---|
| host | string | yes |
| port | integer | default 5060 |
| transport | "udp" | "tcp" | "tls" | default "udp" |
| is_default | boolean | default false |
| label | string or null | no |
| kind | "sip" | "voice_ai" | default "sip" |
| provider | string or null | no |
| agent_id | string or null | no |
| config | object or null | no |
| tech_prefix | string or null | no |
| monitor_enabled | boolean or null | no |
| processing | string or null | no |
| sample_rate | integer or null | no |
| sample_mode | string or null | no |
| transfer_mode | string or null | no |
| auth_username | string or null | no |
| auth_password | string or null | no |
| auth_realm | string or null | no |
| webhook_secret | string or null | no |
| provider_api_key | string or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| host | string | yes |
| port | integer | yes |
| transport | string | yes |
| is_default | boolean | yes |
| label | string or null | yes |
| kind | string | yes |
| provider | string or null | yes |
| agent_id | string or null | yes |
| config | object or null | yes |
| tech_prefix | string or null | yes |
| has_credential | boolean | default false |
| needs_credential | boolean | default false |
| webhook_url | string or null | no |
| has_webhook_secret | boolean | default false |
| has_provider_key | boolean | default false |
| needs_webhook | boolean | default false |
| webhook_last_event_at | timestamp or null | no |
| webhook_last_status | string or null | no |
| webhook_last_error | string or null | no |
| monitor_enabled | boolean | default false |
| processing | string | default "full" |
| sample_rate | integer | default 1 |
| sample_mode | string | default "analyse" |
| transfer_mode | string | default "platform" |
| monitor_supported | boolean or null | no |
| monitor_status | string | default "unknown" |
| monitor_last_check_at | timestamp or null | no |
| monitor_last_change_at | timestamp or null | no |
| monitor_rtt_ms | integer or null | no |
| monitor_last_code | integer or null | no |
| monitor_last_error | string or null | no |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| host | string or null | no |
| port | integer or null | no |
| transport | "udp" | "tcp" | "tls" or null | no |
| is_default | boolean or null | no |
| label | string or null | no |
| kind | "sip" | "voice_ai" or null | no |
| provider | string or null | no |
| agent_id | string or null | no |
| config | object or null | no |
| tech_prefix | string or null | no |
| monitor_enabled | boolean or null | no |
| processing | string or null | no |
| sample_rate | integer or null | no |
| sample_mode | string or null | no |
| transfer_mode | string or null | no |
| auth_username | string or null | no |
| auth_password | string or null | no |
| auth_realm | string or null | no |
| clear_credential | boolean or null | no |
| webhook_secret | string or null | no |
| provider_api_key | string or null | no |
| clear_webhook_secret | boolean or null | no |
| clear_provider_key | boolean or null | no |
| rotate_webhook_token | boolean or null | no |
| Field | Type | Required |
|---|---|---|
| t | number | yes |
| digit | string | yes |
| channel | string | default "caller" |
| ms | integer or null | no |
| source | string or null | no |
| Field | Type | Required |
|---|---|---|
| entity | string | yes |
| count | integer | yes |
| Field | Type | Required |
|---|---|---|
| status | string | yes |
| db | boolean | yes |
| version | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| status | string | yes |
| ani | string or null | yes |
| dialed | string or null | yes |
| external_id | string or null | yes |
| external_name | string or null | yes |
| sub_customer | string or null | no |
| dest_host | string | yes |
| dest_port | integer | yes |
| dest_transport | string | yes |
| dest_kind | string | yes |
| dest_provider | string or null | no |
| routed_destination_label | string or null | no |
| route_prefix | string or null | yes |
| media_node | string or null | yes |
| started_at | timestamp | yes |
| answered_at | timestamp or null | yes |
| elapsed_sec | integer | yes |
| max_call_seconds | integer or null | yes |
| remaining_sec | integer or null | yes |
| src_ip | string | yes |
| ended_at | timestamp or null | no |
| duration_sec | integer or null | no |
| billsec | integer or null | no |
| sip_code | integer or null | no |
| end_reason | string or null | no |
| hangup_by | string or null | no |
| q850_cause | integer or null | no |
| q850_text | string or null | no |
| Field | Type | Required |
|---|---|---|
| endpoint | string or null | no |
| packets | integer | default 0 |
| bytes | integer | default 0 |
| errors | integer | default 0 |
| last_packet | integer or null | no |
| ssrc | integer or null | no |
| lost | integer or null | no |
| loss_pct | number or null | no |
| jitter_ms | number or null | no |
| rtt_ms | number or null | no |
| mos | number or null | no |
| Field | Type | Required |
|---|---|---|
| sampled_at | timestamp | yes |
| legs | object | yes |
| Field | Type | Required |
|---|---|---|
| transcript_status | string | yes |
| analysis_status | string | yes |
| processing | string | default "full" |
| sampled | boolean | default true |
| processing_error | string or null | no |
| Field | Type | Required |
|---|---|---|
| mos | number or null | no |
| jitter_ms | number or null | no |
| packet_loss_pct | number or null | no |
| legs | object or null | no |
| Field | Type | Required |
|---|---|---|
| pdd_ms | integer or null | no |
| answer_delay_ms | integer or null | no |
| early_media | boolean or null | no |
| codec | string or null | no |
| Field | Type | Required |
|---|---|---|
| title | string or null | no |
| probability | integer | yes |
| category | string or null | no |
| recommendation | string | yes |
| summary | string or null | no |
| Field | Type | Required |
|---|---|---|
| cidr | string | yes |
| label | string or null | no |
| dial_prefix | string or null | no |
| destination_id | uuid or null | no |
| enabled | boolean | default true |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| cidr | string | yes |
| label | string or null | yes |
| dial_prefix | string or null | no |
| destination_id | uuid or null | yes |
| enabled | boolean | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| label | string or null | no |
| dial_prefix | string or null | no |
| destination_id | uuid or null | no |
| enabled | boolean or null | no |
| Field | Type | Required |
|---|---|---|
| keyword | string | yes |
| count | integer | yes |
| Field | Type | Required |
|---|---|---|
| name | string | yes |
| yes | ||
| company | string or null | no |
| platform | string or null | no |
| volume | string or null | no |
| message | string or null | no |
| page | string or null | no |
| attribution | object or null | no |
| website | string or null | no |
| Field | Type | Required |
|---|---|---|
| total | integer | yes |
| limit | integer | yes |
| offset | integer | yes |
| items | LedgerOut[] | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| type | string | yes |
| amount | number | yes |
| balance_after | number | yes |
| call_id | uuid or null | yes |
| description | string or null | yes |
| waived_amount | number | default 0 |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| status | string | yes |
| ani | string or null | yes |
| dialed | string or null | yes |
| external_id | string or null | yes |
| external_name | string or null | yes |
| sub_customer | string or null | no |
| dest_host | string | yes |
| dest_port | integer | yes |
| dest_transport | string | yes |
| dest_kind | string | yes |
| dest_provider | string or null | no |
| routed_destination_label | string or null | no |
| route_prefix | string or null | yes |
| media_node | string or null | yes |
| started_at | timestamp | yes |
| answered_at | timestamp or null | yes |
| elapsed_sec | integer | yes |
| max_call_seconds | integer or null | yes |
| remaining_sec | integer or null | yes |
| Field | Type | Required |
|---|---|---|
| items | LiveCall[] | yes |
| active_count | integer | yes |
| ports | integer | yes |
| ports_in_use | integer | yes |
| Field | Type | Required |
|---|---|---|
| yes | ||
| password | string | yes |
| Field | Type | Required |
|---|---|---|
| url | string | yes |
| expires_in | integer | yes |
| Field | Type | Required |
|---|---|---|
| ingress_host | string | yes |
| ingress_port | integer | default 5060 |
| transports | string[] | default ["udp","tcp"] |
| Field | Type | Required |
|---|---|---|
| enroll_token | string | yes |
| credential | object | yes |
| name | string or null | no |
| Field | Type | Required |
|---|---|---|
| login_token | string | yes |
| assertion | object | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| name | string | yes |
| transports | string[] or null | no |
| created_at | timestamp | yes |
| last_used_at | timestamp or null | yes |
| Field | Type | Required |
|---|---|---|
| options | object | yes |
| state | string | yes |
| Field | Type | Required |
|---|---|---|
| credential | object | yes |
| state | string | yes |
| name | string or null | no |
| Field | Type | Required |
|---|---|---|
| name | string | yes |
| Field | Type | Required |
|---|---|---|
| enabled | boolean | yes |
| publishable_key | string | yes |
| currency | string | yes |
| preset_amounts | integer[] | default [25,50,100,250] |
| min_custom_amount | integer | default 10 |
| Field | Type | Required |
|---|---|---|
| active | boolean | default false |
| started_at | timestamp or null | no |
| ends_at | timestamp or null | no |
| days_left | integer | default 0 |
| minutes_limit | integer or null | no |
| minutes_used | number | default 0 |
| exhausted | boolean | default false |
| waived_total | number | default 0 |
| Field | Type | Required |
|---|---|---|
| plan_code | string | yes |
| Field | Type | Required |
|---|---|---|
| code | string | yes |
| name | string | yes |
| monthly_fee | number | yes |
| ports | integer | yes |
| included_minutes | integer or null | yes |
| per_minute_rate | number | yes |
| min_billable_seconds | integer | yes |
| active | boolean | yes |
| description | string or null | yes |
| Field | Type | Required |
|---|---|---|
| mode | string | yes |
| analysis_fee_per_call | number | yes |
| Field | Type | Required |
|---|---|---|
| title | string or null | no |
| probability | integer or null | no |
| category | string or null | no |
| entity | string or null | no |
| red_flags | string[] or null | no |
| tcpa_comment | string or null | no |
| summary | string or null | no |
| recommendation | string or null | no |
| Field | Type | Required |
|---|---|---|
| dialed | string or null | no |
| ani | string or null | no |
| direction | string or null | no |
| started_at | timestamp or null | no |
| duration_sec | integer or null | no |
| Field | Type | Required |
|---|---|---|
| shared_by | string or null | no |
| shared_at | timestamp or null | no |
| label | string or null | no |
| expires_at | timestamp or null | no |
| call | PublicShareCall | yes |
| analysis | PublicShareAnalysis or null | no |
| transcript | PublicShareTranscript or null | no |
| has_recording | boolean | default false |
| Field | Type | Required |
|---|---|---|
| text | string | default "" |
| segments | object[] or null | no |
| Field | Type | Required |
|---|---|---|
| bucket | "0-29" | "30-69" | "70-100" | yes |
| count | integer | yes |
| Field | Type | Required |
|---|---|---|
| prefix | string | yes |
| destination_id | uuid | yes |
| enabled | boolean | default true |
| priority | integer | default 100 |
| label | string or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| prefix | string | yes |
| destination_id | uuid | yes |
| enabled | boolean | yes |
| priority | integer | yes |
| label | string or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| prefix | string or null | no |
| destination_id | uuid or null | no |
| enabled | boolean or null | no |
| priority | integer or null | no |
| label | string or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| string | yes | |
| company | string or null | yes |
| phone | string or null | no |
| role | string | yes |
| must_change_password | boolean | default false |
| dialer_enabled | boolean | no |
| ai_mode | string | default "power" |
| status | string | yes |
| Field | Type | Required |
|---|---|---|
| expires_in_hours | integer or null | no |
| label | string or null | no |
| Field | Type | Required |
|---|---|---|
| exists | boolean | yes |
| requires_password | boolean | default true |
| revoked | boolean | default false |
| expired | boolean | default false |
| company_name | string or null | no |
| Field | Type | Required |
|---|---|---|
| view_token | string | yes |
| expires_in | integer | yes |
| Field | Type | Required |
|---|---|---|
| password | string | yes |
| Field | Type | Required |
|---|---|---|
| yes | ||
| password | string | yes |
| company | string or null | no |
| full_name | string or null | no |
| attribution | object or null | no |
| accept_terms | boolean | default false |
| Field | Type | Required |
|---|---|---|
| customer | CustomerOut | yes |
| access_token | string | yes |
| token_type | string | default "bearer" |
| expires_in | integer | yes |
| Field | Type | Required |
|---|---|---|
| time_stamp | timestamp | yes |
| direction | string | yes |
| method | string | yes |
| status | string or null | no |
| fromip | string | yes |
| toip | string | yes |
| fromtag | string or null | no |
| totag | string or null | no |
| first_line | string | yes |
| headers | object or null | no |
| Field | Type | Required |
|---|---|---|
| call_id | uuid | yes |
| sip_call_id | string | yes |
| messages | SipLogMessage[] | yes |
| text | string | yes |
| Field | Type | Required |
|---|---|---|
| date | string | yes |
| spend | number | yes |
| Field | Type | Required |
|---|---|---|
| from | timestamp or null | no |
| to | timestamp or null | no |
| calls | integer | yes |
| answered_calls | integer | yes |
| minutes | number | yes |
| spend | number | yes |
| by_category | object | yes |
| by_recommendation | object | yes |
| avg_probability | number or null | yes |
| Field | Type | Required |
|---|---|---|
| number | string | yes |
| destination_id | uuid or null | no |
| caller_id | string or null | no |
| seconds | integer | default 30 |
| speech | string | default "route_test" |
| agent_destination_id | uuid or null | no |
| instruction | string or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| status | string | yes |
| number | string | yes |
| caller_id | string or null | no |
| destination_id | uuid or null | no |
| seconds | integer | yes |
| speech | string | yes |
| sip_call_id | string | yes |
| call_id | uuid or null | no |
| agent_destination_id | uuid or null | no |
| instruction | string or null | no |
| agent_sip_call_id | string or null | no |
| agent_call_id | uuid or null | no |
| answered | boolean or null | no |
| sip_code | integer or null | no |
| sip_reason | string or null | no |
| talk_seconds | number or null | no |
| ended_by | string or null | no |
| error | string or null | no |
| purpose | string | default "test" |
| created_by | string or null | no |
| confirmed_at | timestamp or null | no |
| confirmed_by | string or null | no |
| confirm_url | string or null | no |
| confirm_expires_at | timestamp or null | no |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| kind | "question" | "bug" | "feature" | "analysis" | "billing" | default "question" |
| subject | string | yes |
| body | string | yes |
| call_id | uuid or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| ticket_no | integer | yes |
| customer_id | uuid | yes |
| kind | string | yes |
| subject | string | yes |
| body | string | yes |
| call_id | uuid or null | yes |
| status | string | yes |
| created_by | string or null | yes |
| closed_at | timestamp or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| message_count | integer | default 0 |
| messages | TicketMessageOut[] | default [] |
| call | CallOut or null | no |
| Field | Type | Required |
|---|---|---|
| total | integer | yes |
| limit | integer | yes |
| offset | integer | yes |
| items | TicketOut[] | yes |
| Field | Type | Required |
|---|---|---|
| body | string | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| author_kind | string | yes |
| author_label | string or null | yes |
| body | string | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| ticket_no | integer | yes |
| customer_id | uuid | yes |
| kind | string | yes |
| subject | string | yes |
| body | string | yes |
| call_id | uuid or null | yes |
| status | string | yes |
| created_by | string or null | yes |
| closed_at | timestamp or null | yes |
| created_at | timestamp | yes |
| updated_at | timestamp | yes |
| message_count | integer | default 0 |
| Field | Type | Required |
|---|---|---|
| status | "open" | "answered" | "closed" | yes |
| Field | Type | Required |
|---|---|---|
| access_token | string | yes |
| token_type | string | default "bearer" |
| expires_in | integer | yes |
| customer | SessionCustomer or null | no |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| provider | string or null | no |
| model | string or null | no |
| location | string or null | no |
| language | string or null | yes |
| audio_seconds | number or null | yes |
| cost | number | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| id | uuid | yes |
| provider | string or null | no |
| model | string or null | no |
| location | string or null | no |
| language | string or null | yes |
| text | string | yes |
| segments | object[] or null | yes |
| audio_seconds | number or null | yes |
| cost | number | yes |
| created_at | timestamp | yes |
| Field | Type | Required |
|---|---|---|
| status | string | yes |
| target | string | yes |
| mode | string | yes |
| Field | Type | Required |
|---|---|---|
| target | string | yes |
| Field | Type | Required |
|---|---|---|
| url | string or null | yes |
| secret_set | boolean | yes |
| Field | Type | Required |
|---|---|---|
| delivered | boolean | yes |
| status_code | integer or null | no |
| error | string or null | no |
| latency_ms | integer | yes |
| Field | Type | Required |
|---|---|---|
| url | string or null | no |
| secret | string or null | no |
| Field | Type | Required |
|---|---|---|
| sent | boolean | default false |
| error | string or null | no |
| skipped_reason | string or null | no |
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.