S3 recording output
When an app has at least one recording artefact selected, Delphi stores those objects in the team's recording bucket. Flow Designer lets you choose any subset of the outputs below; an empty selection retains nothing. This page explains the objects below each recorded conversation prefix and which ones integrations can rely on.
Conversation prefix
New recordings use this S3 key prefix:
recordings/{teamId}/{appId}/{ISO-timestamp}_{conversationId}[_{tobiConversationId}]/
| Component | Meaning |
|---|---|
{teamId} | Team that owns the recording. |
{appId} | App that handled the call. |
{ISO-timestamp} | Call-start time, with characters made safe for an S3 key. |
{conversationId} | Delphi conversation ID. |
{tobiConversationId} | TOBi conversation ID. This suffix is present only when supplied. |
Older recordings can use a recording ID or call ID in the final prefix component. Delphi still checks those legacy locations when retrieving recordings.
Objects stored for a call
A fully processed call can contain the following supported outputs. Objects are created only when
the app selected that artefact and the call contains the corresponding recording stage or turn
data. RFC4733 / SIP INFO keypad events are reconstructed into call-transcript.json and the two
full-call MP3s; they are not added to STT/TTS turn artefacts.
recordings/{teamId}/{appId}/{timestamp}_{conversationId}[_{tobiConversationId}]/
├── call-transcript.json
├── transcript-stt-input.json
├── transcript-tts-output.json
├── recording-processed.mp3
├── recording-raw.mp3
├── stt-input/
│ ├── 0001_client.raw
│ ├── 0002_client.raw
│ └── ...
└── tts-output/
├── 0001_bot.raw
├── 0002_bot.raw
└── ...
| Object | When present | Contents |
|---|---|---|
call-transcript.json | Recording metadata is uploaded. | Call identifiers and context, recording status, source-stage codec metadata, the complete recording-side transcript snapshot, node history, actions, and final context. |
transcript-stt-input.json | Turn artefacts are generated. | Caller turns in chronological order, including transcript text, timing, provider/model metadata, and references to matching objects under stt-input/. |
transcript-tts-output.json | Turn artefacts are generated. | Bot turns in chronological order, including synthesized text, timing, provider/model metadata, and references to matching objects under tts-output/. |
recording-processed.mp3 | Caller audio after preprocessing exists. | Call-level mix using caller audio after audio preprocessing. With bot audio, the caller is the left channel and the bot is the right channel. |
recording-raw.mp3 | Caller audio before preprocessing exists, or only bot audio does. | Call-level mix using caller audio before audio preprocessing. With bot audio, the caller is the left channel and the bot is the right channel. |
stt-input/NNNN_client.raw | An unprotected caller turn contains audio. | One headerless caller-audio excerpt per STT turn. |
tts-output/NNNN_bot.raw | An unprotected bot turn contains audio. | One headerless bot-audio excerpt per TTS turn. |
The caller and bot sequence numbers are independent, zero-padded, and start at 0001. Use the
audio or s3Audio references in the matching transcript JSON as the source of truth instead of
constructing object keys from the sequence number.
The three commonly confused audio objects
pre-audioproc.raw
This is the temporary caller-to-AI source track captured before audio preprocessing such as
denoising. It is headerless audio, not a WAV file. Its codec, sample rate, bit depth, channel count,
and byte count are recorded under the pre-audioproc stage in call-transcript.json.
outbound.raw
This is the temporary AI-to-caller source track: the bot audio Delphi sent towards the caller. It is
also headerless audio. Its decoding parameters are recorded under the outbound stage in
call-transcript.json.
recording-raw.mp3
This is the supported, playable MP3 generated from the pre-audio-processing caller track and the bot track. When both tracks exist it is stereo:
- left channel: caller audio before preprocessing;
- right channel: bot audio sent to the caller.
If only one side exists, Delphi produces a mono MP3. “Raw” in this filename describes which caller track was selected; the object itself is an encoded MP3, not raw headerless audio.
Temporary processing objects
At call completion, Voice uploads the following source objects so the Ops Tasker can generate the MP3 recordings and per-turn artefacts:
| Object | Contents |
|---|---|
pre-audioproc.raw | Caller audio before audio preprocessing. |
post-audioproc.raw | Caller audio after audio preprocessing. |
outbound.raw | Bot audio sent towards the caller. |
These objects are processing inputs, not supported final outputs. A separate retryable cleanup job
deletes them after recording processing succeeds. They can remain visible while the recording has
status PROCESSING, after a failed or incomplete processing/cleanup job, or in recordings created
by a release that did not yet clean up source objects.
.raw objectsUse the MP3 recordings and the audio references in the transcript JSON files. Temporary source objects can disappear after processing or a later cleanup retry.
Raw audio format
All .raw objects are headerless audio byte streams. They do not contain a RIFF/WAV header, so the
filename alone is not enough to decode them.
- Call-level source parameters are in the matching
recording.stagesentry incall-transcript.json. - Turn-level parameters are in the item's
mediaFormatfield intranscript-stt-input.jsonortranscript-tts-output.json. - Examples include
raw/lpcm16_16for signed 16-bit little-endian PCM at 16 kHz,raw/alaw_8for A-law at 8 kHz, andraw/mulaw_8for μ-law at 8 kHz.
WAV is not a persisted recording-output format.
Transcript JSON roles
The three current JSON documents serve different purposes:
| Document | Scope | Use it for |
|---|---|---|
call-transcript.json | Call | Call context, complete transcript snapshot, recording status, and the metadata required to interpret source audio. |
transcript-stt-input.json | Turn | Caller/STT turns and their per-turn audio references. |
transcript-tts-output.json | Turn | Bot/TTS turns and their per-turn audio references. |
All three use UTF-8 JSON, ISO 8601 UTC timestamps, and a top-level schemaVersion. Consumers should
ignore unknown fields so compatible metadata can be added later.
transcript-full.json is a legacy object. It duplicated the combined caller and bot turn data now
split between transcript-stt-input.json and transcript-tts-output.json; new recordings do not
produce it. It can still be present in recordings created by older releases.
DTMF reconstruction
Delphi prefers RFC4733 telephone-event and accepts SIP INFO as a fallback. Those transports do
not put an audible tone in the recorded PCM, so keypad presses are silent unless reconstructed.
When the matching artefact is selected:
call-transcript.jsoninserts sidecar-onlyDTMF 5lines and a top-leveldtmfEventsarray.recording-processed.mp3andrecording-raw.mp3overlay ITU-T Q.23 tones on the caller channel.
STT/TTS transcript JSON and per-turn stt-input/ / tts-output/ files stay speech-only.
Storage protection and retention
When TOBi marks an interval with sensitiveInfoOnStorage, Delphi replaces the corresponding source
audio with codec-correct silence, redacts its transcript item, and does not generate a per-turn audio
object for that interval. The JSON item remains in sequence with storageRedacted: true and
redactionReason: "sensitiveInfoOnStorage".
This storage control is separate from ENABLE_PII_LOGGING. When app recording is on, the S3
recording sidecar retains the full transcript unless storage protection applies. See
Recording and transcript retention.
All supported outputs expire according to the recording bucket's S3 lifecycle policy. The default configured through TelWeb is 180 days.