VoiceML / Recording

Capture call audio to your own storage or your own recorder.

VoiceML offers two independent recording paths. <Record>, recorded <Dial> / <Conference>, and the Recordings REST API upload WAV files to your Amazon S3 bucket. <Start><Siprec> and the Siprec REST API fork live media in parallel to your Session Recording Server over standard SIPREC (RFC 7866). Use either, both, or neither — each is configured separately on your account.

Free trial Compatibility matrix

Two recording paths, fully independent

Method What it does Where audio goes
Amazon S3 recordings Captures call audio as WAV files via <Record>, recorded <Dial> / <Conference>, or the Recordings REST API. Your own S3 bucket
SIPREC recording Forks live call media in parallel to your Session Recording Server (SRS) via <Start><Siprec> or the Siprec REST API. Your SIPREC-compatible recorder

Both methods are bring your own. VoiceTel does not store recordings on shared platform storage. Until you configure a destination, calls are not recorded and nothing is kept on our side.

Amazon S3 recordings

Store call recordings in your own AWS account. VoiceML uploads each recording to your S3 bucket using credentials you provide. You pay AWS directly — there is no VoiceTel markup on storage.

Enable S3 recording

Configure your destination from the Account page in the VoiceML portal (section Amazon recordings):

  1. Open Account and scroll to Amazon recordings.
  2. Enter your bucket details and IAM credentials (see table below).
  3. Save. New recordings upload to your bucket on the next recorded call.
Field Example Notes
Bucket name acme-voiceml-recordings S3 bucket in your AWS account
Region us-east-1 Must match the bucket's region
Object key prefix prod/recordings Optional path prefix
Access key ID AKIA… IAM user with bucket access
Secret access key (write-only) Leave blank to keep the saved secret
KMS key ID arn:aws:kms:us-east-1:123…:key/… Optional — per-object encryption

The secret access key is write-only in the portal: leave it blank to keep the existing value, or paste a new value to replace it.

Object key layout

Each recording is stored as:

<prefix>/<AccountSid>/<RecordingSid>.wav

For example, with prefix prod/recordings:

prod/recordings/AC<your-account-sid>/RE<recording-sid>.wav

AWS setup checklist

Before saving your portal settings:

  1. Create an S3 bucket in your AWS account (private — block public access).
  2. Create an IAM user scoped to that bucket only.
  3. Attach a minimum policy allowing upload, download, and delete on objects in the bucket:
{
  "Version": "2012-10-17",
  "Statement": [{
    "Sid": "VoiceMLRecordings",
    "Effect": "Allow",
    "Action": ["s3:PutObject", "s3:GetObject", "s3:DeleteObject"],
    "Resource": "arn:aws:s3:::your-bucket-name/*"
  }]
}
  1. Generate an access key for that IAM user and enter it in the portal.

Optional: enable bucket encryption (SSE-S3 or SSE-KMS) and a lifecycle policy to expire old recordings after your retention period.

When S3 recording applies

S3 recording is used by:

  • The <Record> verb
  • <Dial record="record-from-answer"> (and other non-do-not-record values)
  • <Conference record="record-from-start"> (and similar)
  • POST /Calls/{CallSid}/Recordings on the REST API

If your S3 destination is not configured, these verbs skip recording and the call continues normally — no audio is captured and no copy is kept on VoiceTel infrastructure.

Using <Record>

The <Record> verb captures audio from the live call into a WAV file and uploads it to your S3 bucket.

Quick start

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Record action="/handle-recording" method="POST"
            maxLength="120" playBeep="true" />
</Response>

When recording finishes, VoiceML posts to your action URL with Twilio-compatible form fields:

Field Meaning
RecordingSidUnique recording identifier (RE…)
RecordingUrlURL to fetch the WAV via the VoiceML Recordings API
RecordingDurationLength in seconds
DigitsDTMF key that ended the recording, hangup, or empty

Common attributes

Attribute Default Purpose
maxLength3600Maximum recording length in seconds
timeout5Seconds of silence before recording ends
finishOnKey#DTMF key that stops recording
playBeeptruePlay a beep before recording starts
trimtrim-silenceStrip leading/trailing silence
recordingStatusCallback(none)Webhook for lifecycle events (in-progress, completed, absent)
transcribefalseRun speech-to-text after recording (requires STT configured — see the speech recognition guide)
transcribeCallback(none)URL POSTed with the transcript when transcribe="true"

Voicemail-style flow

When action is omitted, VoiceML re-fetches the current document after the recording finishes:

<Response>
    <Say>Please leave a message after the tone.</Say>
    <Record maxLength="120" transcribe="true"
            transcribeCallback="/voicemail-transcript" />
    <Say>We did not receive a recording. Goodbye.</Say>
</Response>

Recording bridged and conference calls

<Dial>

Record the bridged portion of an outbound call:

<Response>
    <Dial record="record-from-answer"
          recordingStatusCallback="https://app.example/recording-status">
        <Number>+18005551234</Number>
    </Dial>
</Response>
record value Behavior
do-not-recordNo recording (default)
record-from-answerStart when the called party answers
record-from-ringingStart when ringing begins
record-from-answer-dualDual-channel recording from answer

Use recordingTrack="inbound", outbound, or both to select which leg is captured.

<Conference>

Record a conference room:

<Response>
    <Dial>
        <Conference record="record-from-start"
                    recordingStatusCallback="https://app.example/conf-recording">
            Support Queue
        </Conference>
    </Dial>
</Response>

S3 must be configured on your account for <Dial> and <Conference> recording to produce files.

Fetch and manage recordings

Download a recording

After a recording completes, fetch the WAV from the URL in RecordingUrl (or via the REST API):

GET /2010-04-01/Accounts/{AccountSid}/Recordings/{RecordingSid}.wav

Authenticate with your account SID and API key. The response redirects to a short-lived download URL for the object in your S3 bucket.

REST API

Method Path Purpose
GET/RecordingsList recordings for your account
GET/Recordings/{Sid}Fetch recording metadata
GET/Recordings/{Sid}.wavDownload the WAV
DELETE/Recordings/{Sid}Delete the recording (S3 object and metadata)
POST/Calls/{CallSid}/RecordingsStart recording on a live call
POST/Calls/{CallSid}/Recordings/{Sid}Pause or resume (where supported)

Recording metadata includes status, duration, date_created, and the public uri for the resource.

SIPREC recording

SIPREC (RFC 7866) sends a parallel copy of the call's media to your own Session Recording Server while the call continues normally. Use SIPREC when you already operate an enterprise recorder (compliance archive, quality monitoring, WORM storage, etc.) and want VoiceML to act as the Session Recording Client (SRC).

SIPREC is independent of Amazon S3 recording:

  • S3 captures WAV files through VoiceML verbs.
  • SIPREC streams live media to your SRS in real time.
  • You can run both on the same call if your compliance design requires it.

There is no platform-default SRS. A call that references an unknown, disabled, or unconfigured connector records nothing via SIPREC (the call itself is unaffected).

Configure SIPREC connectors

A connector gives your SRS a name that VoiceML and the REST API can reference. Each connector points at one SRS SIP URI.

Portal setup

  1. Open Account in the VoiceML portal.
  2. In SIPREC recording, click Manage SIPREC connectors.
  3. Click Add a connector and fill in:
Field Example Notes
Connector nameprimary-srsReferenced by connectorName in voice markup — unique per account, no spaces
Friendly nameCompliance recorderOptional label for your team
SRS SIP URIsip:srs.example.com:5070;transport=tcpYour recorder's SIP endpoint
EnabledCheckedDisabled connectors record nothing
  1. Save. The connector is available on the next call.

SRS SIP URI format: use a standard SIP or SIPS URI with the host, port, and transport your recorder expects. Examples:

sip:10.0.1.50:5060
sip:recorder.example.com:5070;transport=tcp
sips:recorder.example.com:5061;transport=tls

Obtain the exact URI from your recorder vendor's documentation (see compatible Session Recording Servers below). Your SRS must be reachable from VoiceTel over the network paths your deployment uses.

Ensure your SRS firewall and security groups allow inbound SIP (and RTP) from VoiceTel's media and signaling addresses.

Using <Start><Siprec>

Start SIPREC on a live call, then continue with other voice-markup verbs:

<?xml version="1.0" encoding="UTF-8"?>
<Response>
    <Start>
        <Siprec connectorName="primary-srs"
                name="compliance-trail"
                track="both_tracks"
                statusCallback="https://app.example/siprec-status"
                statusCallbackMethod="POST">
            <Parameter name="tenant" value="acme-prod"/>
            <Parameter name="department" value="support"/>
        </Siprec>
    </Start>
    <Dial><Number>+18005551234</Number></Dial>
    <Stop><Siprec/></Stop>
</Response>

Attributes

Attribute Required Purpose
connectorNameYesNames the connector you registered in the portal
nameNoIdentifier for logs and callbacks
trackNoinbound_track, outbound_track, or both_tracks (default)
statusCallbackNoWebhook for SIPREC lifecycle events
statusCallbackMethodNoGET or POST (default POST)

<Parameter name="…" value="…"/> children pass metadata through to the SIPREC session. They appear on status callbacks as Parameter.<name> form fields.

Behavior notes

  • One active SIPREC session per call. A second <Start><Siprec> replaces the first.
  • <Stop><Siprec/> ends the fork; otherwise it ends when the call hangs up.
  • connectorName is required. An empty or unknown name fails without starting a recording session.

REST API

Start or stop SIPREC on a live call without voice markup:

# Start (connector must exist and be enabled)
curl -X POST "https://voiceml.voicetel.com/2010-04-01/Accounts/AC…/Calls/CA…/Siprec" \
  -u "AC…:your_api_key" \
  --data-urlencode "ConnectorName=primary-srs"

# Stop
curl -X POST "https://voiceml.voicetel.com/2010-04-01/Accounts/AC…/Calls/CA…/Siprec/SR…" \
  -u "AC…:your_api_key" \
  --data-urlencode "Status=stopped"

Compatible Session Recording Servers

VoiceML implements SIPREC as a Session Recording Client and sends recording sessions to your SRS. Any recorder that accepts standard SIPREC INVITEs can work, subject to your network and codec requirements.

The table below lists widely deployed platforms customers connect to VoiceML. For each one, configure the recorder first, obtain its SRS SIP URI, then enter that URI in your VoiceML connector.

Platform Typical use Configuration resources
OrecX Oreka Open-source and commercial SIPREC recorder; popular with VoIP providers OrecX SIPREC overview · Oreka Administrator Manual
NICE CXone / NICE inContact Enterprise compliance and contact-center recording NICE CXone SIPREC integration (Avaya/SBC)
Verint Financial Compliance Regulated-industry voice capture and archiving Verint capture overview
VoIPmonitor Network monitoring and SIPREC-based capture VoIPmonitor SIPREC setup
Oracle Session Border Controller Carrier/enterprise SBC deployments (SRS destination configuration) Configuring SIPREC on Oracle SBC
Ribbon SBC environments Service-provider SBC SIPREC deployments Ribbon SBC SIPREC support

Example connector entries

After your vendor provides the SRS endpoint, register it in the portal:

Vendor Connector name Example SRS SIP URI
OrecX Orekaoreka-primarysip:10.0.1.12:5090;transport=tcp
VoIPmonitorvoipmonitor-prodsip:monitor.example.com:5099
NICE (via your SBC)nice-compliancesip:44.227.106.81:5061;transport=tls

Replace host, port, and transport with values from your vendor's deployment guide. NICE, Verint, and similar enterprise platforms often require TLS (sips:), specific ports, and allowlisting of VoiceTel's signaling addresses — follow the vendor checklist before going live.

Metadata parameters

Many enterprise recorders expect custom SIPREC metadata (tenant ID, agent ID, call type). Pass these as <Parameter> children on <Siprec>:

<Siprec connectorName="nice-compliance">
    <Parameter name="siteId" value="NYC-01"/>
    <Parameter name="recordType" value="compliance"/>
</Siprec>

Consult your recorder vendor for supported parameter names.

Migrating from Twilio

VoiceML uses the same voice markup and REST shapes Twilio documents:

Twilio feature VoiceML equivalent
<Record> + RecordingUrl Same attributes and callback fields; WAV stored in your S3 bucket instead of Twilio storage
<Dial record="…"> Same; requires S3 configuration on your account
<Start><Siprec connectorName="…"> Same verb; register connectors in the VoiceML portal instead of the Twilio Marketplace
POST /Calls/{Sid}/Siprec Same REST shape

On Twilio, recordings and SIPREC often run on Twilio-managed storage or connectors. On VoiceML, you configure your own S3 bucket and your own SRS endpoints — billing and data residency follow your AWS and recorder agreements.

Troubleshooting

Amazon S3 recordings

Symptom What to check
Calls never produce recordingsConfirm Amazon recordings is saved on the Account page with bucket, region, access key, and secret. Without a valid destination, recording verbs skip silently.
Recording metadata exists but download failsVerify the IAM policy includes s3:GetObject and s3:PutObject. Check bucket name and region match the portal settings.
Upload errors after key rotationUpdate the access key in the portal and save. Test on a new call.
Wrong S3 pathObject keys use <prefix>/<AccountSid>/<RecordingSid>.wav — adjust the prefix field if needed.

SIPREC

Symptom What to check
SIPREC never startsconnectorName must match a connector registered on SIPREC connectors. The connector must be Enabled.
Recorder shows no sessionsConfirm the SRS SIP URI, port, and transport (tcp / tls) match the vendor guide. Check firewall rules allow VoiceTel to reach the SRS.
Wrong or missing metadataAdd <Parameter> children with names your recorder expects.
Changed connector didn't applyConnector changes take effect on the next call (or next <Start><Siprec> on a live call).
Need both S3 and SIPRECConfigure both independently — S3 on the Account page, SIPREC on the connectors page. They do not conflict.

General

Symptom What to check
transcribe="true" but no transcriptConfigure a speech-to-text provider on the Account page — see the speech recognition guide.
Recording callback missing fieldsAn empty S3 recording produces empty RecordingSid / RecordingUrl on the action callback — configure S3 first.