Compatibility API (Twilio and Telnyx)
New code should use the native API (README.md). This section documents the Twilio- and Telnyx-compatible APIs, kept so that existing code migrates by changing its SDK base URL:
| Migrating from | SDK base URL | Guide |
|---|---|---|
Twilio REST (/2010-04-01/Accounts/{AccountSid}/...) |
https://api.contactivity.io/compat/twilio |
compat-migration.md |
| Telnyx Call Control v2 and TeXML | https://api.contactivity.io/compat/telnyx/v2 |
compat-migration.md |
The interactive reference is the Compatibility tab (spec
https://api.contactivity.io/docs/compat/openapi.yaml). Its
paths map to the compatible base URLs: /v1/voice/X is what /compat/twilio/2010-04-01/Accounts/{AccountSid}/X.json
reaches, and /v1/voice/call-control/X is what /compat/telnyx/v2/X reaches. Call them through the /compat
base URLs. The SDKs contactivity (Twilio) and contactivity-callcontrol (Telnyx), for Node and
Python, default to those base URLs.
Native equivalents:
| Compatibility | Native |
|---|---|
POST /Calls (form, PascalCase) |
POST /v1/projects/{project_id}/calls (JSON) |
POST /Calls/{CallSid} (Url / Twiml / Status) |
POST /calls/{call_id}/actions/redirect or /actions/hangup |
Call Control POST /calls/{id}/actions/{command} |
POST /calls/{call_id}/actions/{action}; renamed: coxml_redirect → redirect, playback_start/stop → play/stop_play, gather_stop → stop_gather, streaming_start/stop → stream_start/stop, suppression_start/stop → noise_suppression_start/stop, client_state_update → update_client_state; command_id → Idempotency-Key header |
Recordings, Transcriptions |
/recordings, /transcriptions |
Conferences, Participants |
/conferences, /conferences/{id}/participants |
Queues, Members |
/queues, /queues/{id}/members |
IncomingPhoneNumbers, AvailablePhoneNumbers, /api/v1/numbers |
/numbers, /available-numbers |
OutgoingCallerIds |
/verified-numbers |
Twilio error body {code, message, more_info, status}; Telnyx {errors: [...]} |
{error: {type, code, message, param, request_id, doc_url}} |
| Basic auth (AccountSid + token) | Authorization: Bearer ck_… |
Page tokens / page[number] |
limit + starting_after cursor |
The rest of this page is the compatibility reference.
Authentication
| API | Method |
|---|---|
| Compatibility | HTTP Basic: AccountSid (project id) as the username, the project's auth token or an API key secret as the password |
| Call Control | Authorization: Bearer <API key> |
PBX apps (/v1/projects/{project_id}/pbx-apps…) |
HTTP Basic as for the compatibility API (the username must be the {project_id} in the path), or the portal's user token (Authorization: Bearer <JWT>) |
API keys are created per project in the portal, can be limited to voice, and are stored as hashes. Requests over plain HTTP are refused.
Compatibility API
Requests are application/x-www-form-urlencoded, with Twilio's parameter names. Responses are JSON. The project comes from the credentials, so paths don't repeat the AccountSid. Moving from Twilio means changing the base URL from /2010-04-01/Accounts/{AccountSid} to /v1/voice and dropping the .json suffix. Code written against Twilio's REST URLs can instead keep them: migrating from Twilio, set your SDK base URL to https://api.contactivity.io/compat/twilio and the same handlers serve /compat/twilio/2010-04-01/Accounts/{AccountSid}/... (Telnyx: https://api.contactivity.io/compat/telnyx/v2). See compat-migration.md.
Calls
| Method and path | Purpose |
|---|---|
POST /Calls |
Create an outbound call |
GET /Calls |
List calls (filters: To, From, Status, StartTime>, StartTime<, ParentCallSid; paging PageSize, PageToken) |
GET /Calls/{CallSid} |
Fetch one call |
POST /Calls/{CallSid} |
Change a live call: new Url or Twiml, or Status=completed / canceled |
DELETE /Calls/{CallSid} |
Archive the call record (completed calls only); it then answers 404 and leaves lists |
POST /Calls parameters:
| Parameter | Required | Default | Notes |
|---|---|---|---|
To |
yes | — | E.164 number, sip: URI, or client:<name> |
From |
yes | — | A number the project owns or a verified number |
Url or Twiml |
one of them | — | Where to fetch CoXML on answer, or the CoXML itself (up to 4,000 characters). Plivo XML is accepted too, per the voice app's Markup setting (coxml, plivo, auto) |
Markup |
no | the app's setting | coxml, plivo or auto, for calls not tied to a voice app |
Method |
no | POST |
For Url |
FallbackUrl, FallbackMethod |
no | — | Used if Url fails |
StatusCallback |
no | — | Progress URL |
StatusCallbackEvent |
no | completed |
Space-separated: initiated ringing answered completed |
StatusCallbackMethod |
no | POST |
|
Timeout |
no | 60 |
Seconds to ring, 5–600 |
TimeLimit |
no | 14400 |
Maximum call length; the credit limit also applies |
Record |
no | false |
Record the whole call |
RecordingChannels |
no | mono |
mono, dual |
RecordingStatusCallback |
no | — | |
MachineDetection |
no | — | Enable or DetectMessageEnd. Detection runs on answer, before the first document is requested; AnsweredBy (human, machine_start, machine_end_beep, machine_end_silence, machine_end_other, fax, unknown) is sent with that request and the status callbacks, and returned in the call resource. Enable decides within about 4 s; DetectMessageEnd waits for the greeting's beep or silence (up to 30 s), so a message played next starts after the beep. See Answering machine detection. |
MachineDetectionTimeout |
no | 30 |
Seconds of analysis, 3–59; then machine_end_other or unknown |
MachineDetectionSpeechThreshold |
no | 2400 |
ms of speech that make a greeting a machine, 1000–6000 |
MachineDetectionSpeechEndThreshold |
no | 1200 |
ms of silence that end a greeting, 500–5000 |
MachineDetectionSilenceTimeout |
no | 5000 |
ms of initial silence before unknown, 2000–10000 |
AsyncAmd |
no | false |
true: the first document is requested at once (no AnsweredBy); the result is POSTed to AsyncAmdStatusCallback |
AsyncAmdStatusCallback |
no | — | Receives CallSid, AccountSid, AnsweredBy, MachineDetectionDuration (ms) |
AsyncAmdStatusCallbackMethod |
no | POST |
|
MachineDetectionEngine |
no | standard |
Contactivity extension: premium adds transcript-based classification (billed per call) |
SendDigits |
no | — | DTMF after answer |
CallerId |
no | — | Alias of From, for Twilio compatibility |
The call resource returned:
{
"sid": "CA5f2c8a1e7d4b4e0f9a1c2d3e4f5a6b7c",
"account_sid": "AC91ab…",
"parent_call_sid": null,
"to": "+13105550000",
"from": "+15551234567",
"status": "queued",
"direction": "outbound-api",
"start_time": null,
"end_time": null,
"duration": null,
"price": null,
"price_unit": "USD",
"answered_by": null,
"quality": null,
"date_created": "Thu, 09 Oct 2026 10:15:00 +0000",
"uri": "/v1/voice/Calls/CA5f2c…",
"subresource_uris": {
"recordings": "/v1/voice/Calls/CA5f2c…/Recordings"
}
}price is the call's price, filled in when the call ends.
Call quality
quality is our extension to the Twilio call resource (Twilio keeps this in Voice Insights): the media quality of this leg, null until the leg has ended or when it carried no audio. Each leg is its own call resource, so the quality of a <Dial> leg is on the child call (GET /Calls?ParentCallSid=…).
"quality": { "mos": 4.41, "jitter_ms": 1.5, "packet_loss_pct": 0.2, "packets": 1500, "source": "engine" }| Field | Meaning |
|---|---|
mos |
Mean opinion score, 1–5, of the audio Contactivity received from the far end of this leg. Shown as good (≥ 4), fair (≥ 3.6) or poor |
jitter_ms |
Inter-arrival jitter in ms (engine legs: the peak over the call) |
packet_loss_pct |
Packets missing from the RTP sequence, in percent of those expected |
rtt_ms |
Round-trip time in ms, when known (relayed calls with RTCP); absent for engine legs |
packets |
RTP packets received |
source |
engine (calls the voice engine handles) or relay (SIP calls relayed without the engine) |
Portal call logs show the quality of each leg.
Recordings
| Method and path | Purpose |
|---|---|
GET /Recordings |
List recordings (filters: CallSid, DateCreated>, DateCreated<) |
GET /Recordings/{RecordingSid} |
Recording details |
GET /Recordings/{RecordingSid}.wav or .mp3 |
Download: redirects to a signed API link (/v1/recording-files/…) valid for 10 minutes, which streams the decrypted audio |
DELETE /Recordings/{RecordingSid} |
Archive the recording (the file is kept); it then answers 404 and leaves lists |
GET /Calls/{CallSid}/Recordings |
Recordings of one call |
POST /Calls/{CallSid}/Recordings |
Start recording a live call (RecordingChannels, RecordingStatusCallback) |
POST /Calls/{CallSid}/Recordings/{RecordingSid} |
Status=paused, in-progress or stopped; with paused, PauseBehavior=skip (default: the paused audio is left out of the recording) or silence (silence is recorded) |
GET /Recordings/{RecordingSid}/Transcriptions |
Transcriptions of one recording (from <Record transcribe>) |
GET /Recordings/{RecordingSid}/Transcriptions/{TranscriptionSid}, DELETE same |
One transcription; archive it |
GET /Transcriptions, GET /Transcriptions/{TranscriptionSid}, DELETE /Transcriptions/{TranscriptionSid} |
All transcriptions of the project, newest first |
Dual-channel. RecordingChannels=dual (Calls API, POST /Calls/{CallSid}/Recordings), <Dial record="record-from-answer-dual"> / record-from-ringing-dual and Call Control record_start channels: "dual" record a stereo WAV: the caller (the call's own leg) on the left channel, the other party on the right. The recording's channels is 2 (Call Control channels: "dual"), and so is the callback's RecordingChannels. SIP trunk recordings are always dual. Transcription mixes both channels down to one track.
Encryption at rest. Every recording file (and its MP3 copy) is encrypted before it is stored, with a random 256-bit key per project: AES-256-GCM in 64 KiB chunks, each with its own nonce and tag, so tampering or truncation is detected on read. The project keys are stored wrapped by a master key held only in the API's environment (RECORDING_MASTER_KEY). Downloads always go through the API, which decrypts while it streams; signed links work as before. Deleting a project deletes its key. Recordings stored before encryption was turned on are served as they are.
Retention. Recordings, transcriptions, AI agent transcripts and call inspector logs are never erased. DELETE archives a recording or transcription (hidden, the file kept). Project retention settings (PUT /v1/projects/{id}/compliance) are accepted and ignored; GET returns them as null.
Transcription redaction. With the project's transcription_redaction, PII in transcription_text is replaced by tokens like [PHONE] before it is stored and sent to the callback.
A transcription is Twilio's Transcription resource: sid (TR…), recording_sid, status (in-progress, completed, failed), transcription_text, duration (audio seconds), price (negative, USD, per audio minute), price_unit, type (fast), date_created, date_updated, uri. API key scopes: recordings:read and recordings:write. Deleting a recording deletes its transcription. The portal reads a recording's transcript at GET /v1/projects/{project_id}/recordings/{RecordingSid}/transcription ({sid, recording_sid, status, text, language, provider, model, duration, billed_secs, price, error, created_at, updated_at}, 404 when the recording was not transcribed).
Conferences and participants
| Method and path | Purpose |
|---|---|
GET /Conferences |
List (filters: FriendlyName, Status) |
GET /Conferences/{ConferenceSid} |
Fetch |
POST /Conferences/{ConferenceSid} |
Status=completed ends it; AnnounceUrl plays CoXML to everyone |
GET /Conferences/{ConferenceSid}/Participants |
List participants |
POST /Conferences/{ConferenceSid}/Participants |
Dial a new participant into the conference (From, To, plus the <Conference> attributes; Coaching + CallSidToCoach join it as a coach) |
GET /Conferences/{ConferenceSid}/Participants/{CallSid} |
Fetch participant |
POST /Conferences/{ConferenceSid}/Participants/{CallSid} |
Muted, Hold, HoldUrl, AnnounceUrl, Coaching + CallSidToCoach (coach mode: only the coached participant hears this one; Coaching=false ends it) |
DELETE /Conferences/{ConferenceSid}/Participants/{CallSid} |
Remove participant |
{CallSid} in participant paths can also be the participant's label.
Queues and members
| Method and path | Purpose |
|---|---|
POST /Queues |
Create (FriendlyName, MaxSize, default 100) |
GET /Queues, GET /Queues/{QueueSid} |
List, fetch (with current_size, average_wait_time) |
POST /Queues/{QueueSid} |
Update MaxSize |
DELETE /Queues/{QueueSid} |
Archive (must be empty); it then refuses callers |
GET /Queues/{QueueSid}/Members |
Callers waiting |
POST /Queues/{QueueSid}/Members/Front or /{CallSid} |
Take a caller off the queue: Url gives the CoXML to run (usually <Dial> to an agent) |
Call Control API
Requests and responses are JSON. Every command accepts:
client_state: base64 string, echoed in every later webhook for this call;command_id: a repeated id within 60 seconds is ignored, so retries are safe.
Calls
| Method and path | Purpose |
|---|---|
POST /v1/voice/call-control/calls |
Dial a new call. Body: connection_id (the voice app), to, from, timeout_secs, time_limit_secs, answering_machine_detection, record (record-from-answer), client_state, webhook_url (overrides the app's) |
GET /v1/voice/call-control/calls/{call_control_id} |
Current state: is_alive, call_duration |
Response of POST /v1/voice/call-control/calls:
{
"data": {
"record_type": "call",
"call_control_id": "v3:…",
"call_leg_id": "4f8c…",
"call_session_id": "9a1d…",
"is_alive": false
}
}Actions: POST /v1/voice/call-control/calls/{call_control_id}/actions/{command}
| Command | Body fields | Resulting webhooks |
|---|---|---|
answer |
client_state, command_id |
call.answered |
hangup |
— | call.hangup |
reject |
cause: CALL_REJECTED or USER_BUSY |
call.hangup |
bridge |
call_control_id (the other call), park_after_unbridge (self: this call stays up, parked, when the bridge ends; by default it hangs up). The other call hangs up when this one does, unless its own bridge asked for self |
call.bridged |
transfer |
to, from, timeout_secs, answering_machine_detection, answering_machine_detection_config (as for dial, below; detection runs on the new leg once it answers, while it is bridged, and its events carry that leg's call_control_id and this call's call_session_id) |
call.initiated, call.bridged |
With answering_machine_detection (detect or detect_words), dialed calls send call.machine.detection.ended with result: human, machine, fax or not_sure. detect_beep and greeting_end also wait for the end of a machine's greeting and then send call.machine.greeting.ended (beep_detected, ended or not_sure). premium sends call.machine.premium.detection.ended (human_residence, human_business, machine, silence, fax_detected, not_sure, plus confidence 0–1) and, for machines, call.machine.premium.greeting.ended (beep_detected or no_beep). answering_machine_detection_config takes total_analysis_time_millis, after_greeting_silence_millis, greeting_duration_millis and initial_silence_millis (the Twilio thresholds above). Detection runs before the next command is accepted.
| refer | sip_address | call.refer.started, call.refer.completed or .failed |
| speak | payload, payload_type (text or ssml), voice, language | call.speak.started, call.speak.ended |
| playback_start | audio_url, loop, overlay (true: mixed over the audio already playing, at once, not queued behind the running command; WAV only, played once; playback_stop stops it) | call.playback.started, call.playback.ended |
| playback_stop | stop (current or all) | call.playback.ended |
| gather | minimum_digits, maximum_digits, timeout_millis, terminating_digit, valid_digits, inter_digit_timeout_millis | call.gather.ended |
| gather_using_speak | gather fields + payload, voice, language, input (dtmf, speech, dtmf speech), hints | call.gather.ended (with digits or speech) |
| gather_using_audio | gather fields + audio_url | call.gather.ended |
| gather_stop | — | call.gather.ended (status cancelled) |
| record_start | format (wav, mp3; recordings are WAV for now, mp3 is accepted and recorded as WAV), channels (single, dual), play_beep (default false: a short tone as the recording starts), max_length (seconds, 0–14400, 0 = no limit: the recording is then stopped and saved), transcription (bool), transcription_language (default en-US), transcription_engine (accepted, ignored) | call.recording.saved (after stop and upload); with transcription, then call.recording.transcription.saved (recording_id, recording_transcription_id, status, transcription_text) |
| record_stop, record_pause, record_resume | — (a pause leaves the paused audio out of the recording) | — |
| send_dtmf | digits, duration_millis | — |
| enqueue | queue_name, max_wait_time_secs, max_size | call.enqueued, call.dequeued |
| leave_queue | — | call.dequeued |
| streaming_start | stream_url, stream_track (inbound_track, outbound_track, both_tracks), stream_bidirectional_mode (rtp: the server's media messages, PCMU, are played to the caller for as long as the stream runs, between and after other commands; mp3 is refused with 400, like other invalid parameters) | streaming.started, streaming.stopped, streaming.failed |
| streaming_stop | — | streaming.stopped |
| transcription_start | language (default en-US), transcription_tracks (inbound, outbound, both), interim_results (bool), transcription_engine (accepted, ignored) | call.transcription with transcription_data: transcript, confidence, is_final, transcription_track |
| transcription_stop | — | — |
| ai_agent_start | voice_app_id (an ai_agent app), parameters (object of strings) | call.ai_agent.started, call.ai_agent.ended (status, transfer_to, error); the agent app's agent.* webhooks |
| gather_using_ai | parameters (JSON schema of the fields to collect: properties, required; 1–20 properties), greeting, voice (voice id), language (default en-US), assistant (instructions, model), message_history ([{"role": "user" or "assistant", "content"}], up to 50: the conversation so far), timeout_secs (30–1800, default 120; ours); send_partial_results is accepted and ignored | call.ai_gather.ended with status (completed, partial, timeout, caller_hangup, error), result (the collected fields), message_history and error. Same agent as CoXML <AIGather>, billed as an AI agent |
| suppression_start | direction (inbound (default, the caller's audio), outbound (audio sent to the caller), both); noise_suppression_engine is ignored (one engine: RNNoise) | — |
| suppression_stop | — | — |
| coxml_redirect | url or coxml | (hands the call to CoXML; Call Control webhooks stop) |
Responses: 200 {"data": {"result": "ok"}}. A command for a call that has ended returns 422 with error call_has_ended.
Noise suppression (suppression_start) runs RNNoise in the media server on the chosen direction; everything downstream of it (the bridged party, recordings, streams, transcription, AI agents) gets the cleaned audio. A second suppression_start changes the direction; it ends with the call. Price: $0.002 per minute while it runs (placeholder; ai_rates part noise_suppression), rounded up to the billing increment, debited from the prepaid balance once per call at hangup (ledger kind noise_suppression, external id ns:<call sid>). It is billed the same way when started by CoXML <Start><NoiseSuppression> or an AI agent with noise_suppression set.
Conferences
| Method and path | Purpose |
|---|---|
POST /v1/voice/call-control/conferences |
Create from an existing call: call_control_id, name, beep_enabled (always (default), never, on_enter, on_exit: the tones when this call enters / leaves), start_conference_on_create (default true; false: the creating call hears hold music until a participant that starts the conference joins) |
GET /v1/voice/call-control/conferences, GET /v1/voice/call-control/conferences/{id} |
List, fetch |
GET /v1/voice/call-control/conferences/{id}/participants |
Participants |
POST /v1/voice/call-control/conferences/{id}/actions/{command} |
join (call_control_id, beep_enabled), leave, mute, unmute, hold, unhold, speak, play, record_start, record_stop, end |
Conference webhooks (Telnyx envelope and keys): conference.created (when the first participant enters) and conference.ended (reason: all_left, ended_via_api, host_left) go to the webhook of the conference's first Call Control participant, normally the call that created it, with that call's ids. conference.participant.joined / left go to each Call Control participant's own webhook, with its ids. All carry conference_id. A conference record_start sends conference.recording.saved (conference_id, recording_id, recording_urls, channels, format, recording_started_at / recording_ended_at; the call ids are null) to the conference's webhook after upload. They work the same when participants are on different engine nodes.
Answering machine detection
The engine listens to the called party's audio from answer (voice/src/amd.rs), 20 ms at a time:
- Greeting shape: a short greeting followed by silence (
MachineDetectionSpeechEndThreshold) is a person; speech reachingMachineDetectionSpeechThresholdis a machine, unless its cadence is a person's ("Hello? … Hello?": pauses most of the time). In between, many words in a row (a recording's cadence) mean a machine. - Beep: a single tone between 350 and 2000 Hz holding most of the audio's energy for 160 ms, found by a Goertzel scan; it survives line noise down to about 0 dB SNR. A beep after any greeting, even a short "Leave a message", makes the call a machine (
machine_end_beep, ormachine_startwithEnable). - Fax: CNG (1100 Hz, before anyone speaks) or CED (2100 Hz).
- Premium (
MachineDetectionEngine=premium, Call Controlpremium): the first 6 s of the greeting also go to speech-to-text. Voicemail phrases ("leave a message", "after the tone", "not available", "mailbox", "voicemail", "you've reached …") make a short greeting a machine; a business answering ("thank you for calling …, how can I help") keeps a long greeting a person (human_business). A decision waits at most 2.5 s for the transcript; without one the audio decision stands.
Price: standard detection is included in the call. Premium is $0.0075 per call that runs it (placeholder; Twilio prices AMD per call), debited from the prepaid balance once the detection ends (ai_rates part amd_premium, whose rate_per_min column holds the per-call price; ledger kind amd, external id amd:<call sid>).
Webhooks
Compatibility API
CoXML requests and status callbacks use form-encoded POSTs with Twilio's parameter names.
Call Control API
JSON POSTs to the voice app's webhook URL:
{
"data": {
"record_type": "event",
"id": "0ccc7b54-4df3-4bca-a65a-3da1ecc777f0",
"event_type": "call.answered",
"occurred_at": "2026-10-09T10:15:04.123Z",
"payload": {
"call_control_id": "v3:…",
"call_leg_id": "4f8c…",
"call_session_id": "9a1d…",
"connection_id": "app_42",
"client_state": "eyJzdGVwIjoxfQ==",
"from": "+15551234567",
"to": "+13105550000",
"direction": "outgoing",
"state": "answered"
}
},
"meta": { "attempt": 1, "delivered_to": "https://example.com/hooks" }
}Event types:
- Call:
call.initiated,call.answered,call.hangup(withhangup_cause,hangup_source,sip_hangup_cause),call.bridged,call.dtmf.received,call.gather.ended,call.speak.started/ended,call.playback.started/ended,call.recording.saved,call.machine.detection.ended,call.machine.greeting.ended,call.machine.premium.detection.ended,call.machine.premium.greeting.ended,call.refer.*,call.enqueued,call.dequeued,call.ai_agent.started/ended,call.ai_gather.ended,call.error. - Streaming:
streaming.started,streaming.stopped,streaming.failed. - Conference:
conference.created,conference.ended,conference.participant.joined,conference.participant.left,conference.recording.saved.
Signing (both APIs)
| Header | Algorithm |
|---|---|
X-Twilio-Signature |
HMAC-SHA1 (compatibility API only, for existing validators) |
webhook-id, webhook-timestamp, webhook-signature |
Ed25519 over {webhook-id}.{webhook-timestamp}.{raw body} (Standard Webhooks). The public key is shown in the portal. Reject timestamps older than 5 minutes |
Delivery
- Timeout 10 seconds per attempt. Any
2xxcounts as delivered. - Retries for status callbacks and Call Control events: 1 s, 5 s, 30 s, 2 min, 10 min, then the failover URL if one is set.
- Events can arrive out of order or more than once. Use
data.id(Call Control) orSequenceNumber(status callbacks) to sort and deduplicate. - CoXML document fetches are not retried (the call can't wait); they go to the fallback URL instead.
Errors
JSON error body for both APIs:
{ "code": 21211, "message": "The 'To' number +1555 is not a valid phone number.", "more_info": "https://docs.contactivity.io/errors/21211", "status": 400 }| HTTP | When |
|---|---|
| 400 | Invalid parameter |
| 401 | Missing or wrong credentials |
| 402 | Not enough credit to start the call |
| 403 | Caller ID not owned, number not in the project, feature not enabled |
| 404 | Unknown resource |
| 409 | Call already controlled by the other API |
| 422 | Command not valid in the call's current state |
| 429 | Rate limit or the account's calls-per-second limit exceeded (Retry-After header) |
| 503 | Platform temporarily unable to place calls |
Rate limits
| Limit | Default |
|---|---|
| API requests per project | 100 per second |
POST /Calls and POST /v1/voice/call-control/calls |
The account's calls-per-second limit |
| Simultaneous calls | The account's session limit |

