Recordings
A recording is a WAV file captured by <Dial record="...">, <Record> or a recorded <Conference> in your markup. You can pause, resume or stop recording on a live call, and download a finished recording with your API key. Connect does not transcribe recordings.
API stabilityConnect is live. The API is v0.x, so field names may change before v1. Base URL: https://connect.telvox.dev/api.
How recordings are made
Recording is set in the markup your webhook returns. There is no REST call that starts a recording.
<Dial>records the conversation. Pick the mode with itsrecordattribute (table below).<Record>records the caller on their own, for voicemail. It takesmaxLength(default 60 seconds),finishOnKey(default #),playBeep(default false) and anactionURL, then carries on to the next verb.<Conference>records the room withrecord="record-from-start".- A number can also have a recording policy set in the dashboard. A locked policy blocks pause and stop on that number's calls.
<Response>
<Dial record="record-from-answer"
recordingStatusCallback="https://your.app/voice/rec-status"
recordingStatusCallbackEvent="in-progress completed absent">
<Number>+919876500199</Number>
</Dial>
</Response>| Dial record | Type | Description |
|---|---|---|
| record-from-answer | default | Record the conversation from the moment the call is answered. This is what Dial does when you leave record out. |
| record-from-ringing | mode | Start recording while the far end is still ringing. |
| record-from-answer-dual | mode | Two-channel recording, one party per channel. Needs a SIP trunk with dual-channel recording switched on; otherwise you get one mixed file and RecordingFallbackReason says why. |
| record-from-ringing-dual | mode | As above, starting from ringing. |
| do-not-record | mode | Do not record this Dial. |
Pause, resume or stop
Control recording on a live call, for example to pause while a caller reads out a card number. Send a POST with no body. Nothing is written while recording is paused.
/api/calls/{callSid}/recording/pausePause recording on a live call.
/api/calls/{callSid}/recording/resumeStart recording again after a pause.
/api/calls/{callSid}/recording/stopStop recording for the rest of the call.
curl -X POST https://connect.telvox.dev/api/calls/CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5/recording/pause \
-H "Authorization: Bearer $TELVOX_API_KEY" \
-H "Accept: application/json"{
"ok": true,
"call_sid": "CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5",
"action": "pause",
"status": "paused",
"session_id": null
}| Code | Meaning |
|---|---|
| 200 OK | The engine accepted the command. status is paused, recording (after resume) or stopped. |
| 404 Not Found | The call SID is not on your account. |
| 409 Conflict | Pause and stop only. The number's recording policy is locked, so recording cannot be turned off. Resume is always allowed. |
| 502 Bad Gateway | The call engine rejected the command. The body has error, engine_status and engine_body. |
| 503 Service Unavailable | Recording controls are switched off. |
Download a recording
Use the recording's name: the RecordingName in the recording callback, the last part of its RecordingUrl, or the recording_url field on a fetched call. Names use letters, digits, -, _ and .. You can only fetch your own recordings.
/api/recordings/{recordingName}/infoRecording details as JSON, without downloading the audio.
| Property | Type | Description |
|---|---|---|
| recording_name | string | The recording's name, as sent in RecordingName and at the end of RecordingUrl. |
| call_sid | string | The call this recording belongs to. |
| duration | integer | Length in seconds, taken from the call record. |
| mime_type | string | Always "audio/wav". |
| download_url | string | Where to GET the audio, with your API key. |
{
"recording_name": "cpaas-channel-CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5-1719912345678",
"call_sid": "CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5",
"duration": 47,
"mime_type": "audio/wav",
"download_url": "https://connect.telvox.dev/api/recordings/cpaas-channel-CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5-1719912345678"
}/api/recordings/{recordingName}The audio as audio/wav. Add ?download=1 to receive it as an attachment instead of inline.
# metadata
curl https://connect.telvox.dev/api/recordings/$RECORDING_NAME/info \
-H "Authorization: Bearer $TELVOX_API_KEY"
# audio (WAV); add ?download=1 to receive it as an attachment
curl -o call.wav https://connect.telvox.dev/api/recordings/$RECORDING_NAME \
-H "Authorization: Bearer $TELVOX_API_KEY"HTTP/1.1 200 OK
Content-Type: audio/wav
Content-Disposition: inline; filename="cpaas-channel-CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5-1719912345678.wav"
X-CPaaS-Call-Sid: CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5
X-CPaaS-Recording-Duration: 47
<WAV bytes>Both endpoints return 404 with {"message": "Recording not found"} if the recording is not on your account, and the audio endpoint also returns 404 if the file is no longer on the server. Fetch works on the recording stored on the call record; if a call produced more than one file, a second name can return 404.
Recording status callbacks
Set recordingStatusCallback on <Dial>, <Conference> or <Record>. Connect sends JSON with a 5 second timeout. Callbacks are not retried and not signed, so put a long random token in the URL and check it. See webhooks & callbacks.
| Attribute | Type | Description |
|---|---|---|
| recordingStatusCallback | string | The URL Connect sends recording status callbacks to. |
| recordingStatusCallbackMethod | enum | POST (default) or GET. |
| recordingStatusCallbackEvent | string | Space-separated list of statuses to send: in-progress, completed, absent, failed. Default completed. |
Status values
| RecordingStatus | Type | Description |
|---|---|---|
| in-progress | status | Recording has started. |
| completed | status | The WAV file is stored and can be downloaded. |
| absent | status | Recording was asked for but no file was made. The call itself may still have gone fine. |
| failed | status | The recording could not be finished or stored. |
Callback payload
{
"RecordingStatus": "completed",
"RecordingSource": "bridge",
"RecordingName": "cpaas-bridge-3f6b2c1e-8d4a-4e7b-9c2f-1a5d7e9b0c4d-1719912351234",
"RecordingUrl": "https://connect.telvox.dev/api/recordings/cpaas-bridge-3f6b2c1e-8d4a-4e7b-9c2f-1a5d7e9b0c4d-1719912351234",
"RecordingDuration": 47,
"RecordingCompletedAt": "2026-06-22T17:05:01.000Z",
"CallSid": "CA7Q2M9X4K1B8N3T6R0W5Y2Z9C1V4H7JL5"
}| Field | Type | Description |
|---|---|---|
| RecordingStatus | enum | in-progress, completed, absent or failed. |
| RecordingName | string | The recording's name. Use it with the fetch endpoints above. |
| RecordingUrl | string | https://connect.telvox.dev/api/recordings/{name}. GET it with your API key. |
| RecordingDuration | integer | Length in seconds. On completed. |
| RecordingSource | enum | bridge (a Dial or conference), channel (one leg, such as Record or a number's recording policy) or mixmonitor-dual (two-channel). |
| RecordingSessionId | string | Identifies this recording session. |
| RecordingStartedAt, RecordingCompletedAt | string | ISO 8601 start and finish times. |
| RecordingRequestedMode, RecordingActualMode | string | The record mode you asked for and the one Connect used. |
| RecordingRequestedTrack, RecordingActualTrack | string | The track you asked for (inbound, outbound or both) and the one recorded. |
| RecordingFallbackReason | string | Set when a requested mode or track could not be honoured, for example a -dual mode on a trunk without dual-channel recording. |
| RecordingChannels | integer | 2 for a dual-channel recording. |
| CallSid | string | The call being recorded. |
| ConferenceSid | string | The conference room name, for conference recordings. |
| ErrorMessage | string | Why it went wrong. On absent or failed. |
Fields with no value are left out. The name format depends on how the recording was made, so treat it as an opaque string.