Recording and transcript storage
When an app has Recording on and its team has an S3 recording bucket configured, Delphi stores call audio and related speech artefacts for playback and investigation.
The three JSON documents
Each processed recording uses these three JSON documents:
recordings/{teamId}/{appId}/{timestamp}_{conversationId}[_{tobiConversationId}]/
├── call-transcript.json
├── transcript-stt-input.json
└── transcript-tts-output.json
| Document | Contents |
|---|---|
call-transcript.json | Call-level identity, timing, recording metadata, source stages, and the conversation snapshot. |
transcript-stt-input.json | Caller turns in chronological order, with references to matching STT input audio. |
transcript-tts-output.json | Bot turns in chronological order, with references to matching TTS output audio. |
transcript-full.json is no longer produced because it duplicated the combined contents of the
STT and TTS turn documents. Recordings created by older Delphi versions can still contain that
legacy fourth file.
All three documents are UTF-8 JSON with content type application/json, ISO 8601 UTC timestamps,
and a top-level schemaVersion. Consumers should ignore unknown fields so compatible fields can be
added without changing the schema version.
Complete recording layout
The final output for a successfully processed call can contain:
recordings/{teamId}/{appId}/{timestamp}_{conversationId}[_{tobiConversationId}]/
├── call-transcript.json
├── transcript-stt-input.json
├── transcript-tts-output.json
├── recording-processed.mp3 # optional processed call mix
├── recording-raw.mp3 # optional pre-processed call mix
├── stt-input/ # optional caller-turn audio
│ ├── 0001_client.raw
│ └── ...
└── tts-output/ # optional bot-turn audio
├── 0001_bot.raw
└── ...
The STT and TTS sequence numbers are independent, zero-padded, and start at 0001. Follow the
audio or s3Audio references in the JSON instead of inferring which files exist from the folder
listing. Audio and turn artefacts are optional because their presence depends on the call, flow,
recording configuration, and storage-protection state.
Audio formats
recording-processed.mp3andrecording-raw.mp3are call-level MP3 outputs.- Turn-level
.rawfiles are headerless audio bytes, not WAV files. Decode them using the matching item'smediaFormat, for exampleraw/lpcm16_16,raw/alaw_8, orraw/mulaw_8. - A configured per-turn MP3 output is referenced with an
mp3key. WAV is not a persisted recording-output format.
call-transcript.json
TelPhi writes this call-level document before asynchronous audio processing finishes. Its
recording.recordingStatus can therefore be PROCESSING, and recording.recordingFile can still
be null at upload time.
{
"schemaVersion": 1,
"generatedAt": "2026-07-15T10:15:30.000Z",
"storageProtection": {
"sensitiveInfoOnStorageObserved": false
},
"call": {
"conversationId": "conversation-123",
"callId": "call-123",
"tobiConversationId": "tobi-123",
"traceId": "trace-123",
"teamId": "team-123",
"appId": "app-123",
"callerNumber": "+49123456789",
"endReason": "hangup",
"startTime": "2026-07-15T10:15:00.000Z",
"endTime": "2026-07-15T10:15:30.000Z",
"durationSeconds": 30,
"flowDefinitionId": "flow-123",
"flowVersion": 4
},
"recording": {
"bucket": "recording-bucket",
"region": "eu-central-1",
"s3Prefix": "recordings/team-123/app-123/example",
"transcriptS3Key": "recordings/team-123/app-123/example/call-transcript.json",
"recordingStatus": "PROCESSING",
"recordingFile": null,
"stages": []
},
"transcript": [],
"nodeHistory": [],
"actionsLog": [],
"finalContext": {},
"systemContext": {}
}
The transcript, nodeHistory, actionsLog, finalContext, and systemContext values are
conversation snapshots. The recording.stages array describes the available source tracks and
their captured turn segments. A stage is pre-audioproc, post-audioproc, or outbound.
STT and TTS turn documents
transcript-stt-input.json contains only caller (client) turns.
transcript-tts-output.json contains only bot turns. They share this envelope and item format:
{
"schemaVersion": 1,
"generatedAt": "2026-07-15T10:15:31.000Z",
"call": {
"conversationId": "conversation-123",
"callId": "call-123",
"tobiConversationId": "tobi-123"
},
"items": [
{
"turnId": "stt-1",
"side": "Client",
"speaker": "client",
"timestamp": "2026-07-15T10:15:01.200Z",
"startMs": 1200,
"endMs": 2200,
"durationMs": 1000,
"text": "Hello",
"audio": {
"raw": "stt-input/0001_client.raw"
},
"s3Audio": {
"raw": "recordings/team-123/app-123/example/stt-input/0001_client.raw"
},
"mediaFormat": "raw/lpcm16_16",
"provider": "azure_stt",
"model": null,
"stage": "post-audioproc",
"nodeId": "voice-agent"
}
]
}
Turn item fields
| Field | Meaning |
|---|---|
turnId | Provider or pipeline turn identifier. |
side | Display label: Client or Bot. |
speaker | Stable value: client or bot. |
timestamp | Absolute turn start time, when available. |
startMs | Turn start relative to recorder initialisation. |
endMs | Turn end relative to recorder initialisation, or null. |
durationMs | Captured or derived turn duration, or null. |
text | STT result or the text supplied to TTS; null when unavailable or protected. |
audio | Relative turn-audio paths keyed by raw and, when generated, mp3. |
s3Audio | Full S3 object keys for the same audio. |
mediaFormat | Raw encoding and rate, such as raw/lpcm16_16. |
provider | STT or TTS provider identifier, or null. |
model | Provider model or deployment identifier, or null. |
stage | Source stage used for the segment. |
nodeId | Matching flow node, or null. |
storageRedacted | true when storage was suppressed for this turn. |
redactionReason | sensitiveInfoOnStorage for a TOBi-protected turn. |
Items remain in chronological order. Optional source metadata uses null; audio keys are omitted
when that output was not generated.
Storage protection and retention
- The app Recording toggle controls whether audio and full transcript text are retained. There is no separate “transcripts only” switch.
ENABLE_PII_LOGGINGdoes not disable S3 transcript retention. It controls redaction in Postgres, SigNoz, and traces.- Managed TOBi can set
sensitiveInfoOnStoragefor protected intervals. A protected turn remains in sequence but has no text or audio references and includesstorageRedacted: trueandredactionReason: "sensitiveInfoOnStorage". - Team S3 lifecycle configuration determines how long the objects remain in the bucket.
See Conversations → Recording and transcript retention and TOBi managed LLM.
Operator prerequisites
- Platform call recording is enabled for the deployment.
- The team recording bucket, region, and role are configured under Settings → Team.
- The app Recording toggle is enabled for flows that must retain audio and transcripts.