Recording and transcript storage
When an app selects one or more recording artefacts and its team has an S3 recording bucket configured, Delphi stores only those artefacts for playback and investigation. An empty selection is recording off. Choose Full call transcript alone to keep Delphi transcript JSON without audio.
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-artefact multi-select controls whether audio and/or transcript JSON are retained. Leave the list empty to retain nothing. Select only transcript artefacts for transcript-only storage.
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-artefact list in Flow Settings includes the outputs that must be retained.