Recording output reference
Use this reference to interpret recording objects and investigate missing output. Recording is a shared Delphi capability. This reference describes the common fields produced by Delphi 0.9.17-patch2 and the reviewed Next baseline. It is intentionally not an exhaustive JSON schema: integration-specific metadata and application-defined nested values may also be present. Those fields are not renamed or redefined here; use your assigned integration reference when you need its exact contract.
Artifact selection, processing and successful storage are separate conditions. A selected output is not evidence that its object exists. A stored processing status is a snapshot, not a live status endpoint.
Availability
Your application must select the relevant recording outputs and have a configured, accessible recording destination. This reference does not grant access to recordings: use your team's authorized storage access. Documentation access and recording access are separate permissions. Reading this common reference does not require a customer-specific documentation module. Optional integration metadata can be null even when its field is present.
To choose outputs, use recording selection. To configure the destination and retention, use team recording storage. For an end-to-end investigation, use recording diagnostics.
File roles and creation conditions
| Artifact | Writer | Condition / limit |
|---|---|---|
call-transcript.json | TelPhi recording uploader | Selected independently by the recording output plan; upload failure is caught/logged, so selection does not guarantee an object |
transcript-stt-input.json | Tasker audio-recording processor | Selected STT transcript output and at least one segment activity across the job; its filtered items may be empty |
transcript-tts-output.json | Same Tasker processor | Selected TTS transcript output and at least one segment activity across the job; its filtered items may be empty |
No standalone .txt transcript writer was found in these inspected paths. Other subsystems may produce additional files.
Normal prefixes use recordings/{teamId}/{appId}/{folder}, where folder combines
a formatted start timestamp, sanitized conversation ID and optional customer
integration ID. Identifier sanitization replaces disallowed characters and
truncates to 160 characters. Missing start time uses the current time. Failed or
missing conversation lookup uses a legacy call-ID prefix. Consumers should use
recorded object keys, not reconstruct them from this description.
Call document fields
| Field | Meaning / condition |
|---|---|
schemaVersion | Literal 1 |
generatedAt | ISO timestamp when the document is built |
storageProtection.sensitiveInfoOnStorageObserved | Whether the recorder observed sensitive-storage redaction |
storageProtection.storageRedacted, .redactionReason | Present for protected storage; true and sensitiveInfoOnStorage |
call.conversationId, .callId | Conversation-row IDs with channel/call input fallbacks |
call.traceId | Conversation trace identifier or null |
call.teamId, .appId | Recording configuration team; conversation app with configuration fallback |
call.callerNumber | In-memory PII snapshot when supplied, otherwise conversation value/null |
call.endReason | Recorded conversation end reason or null |
call.startTime, .endTime | ISO timestamp from recorded milliseconds, or null |
call.durationSeconds | Recorded duration, otherwise computed from available start/end times, otherwise null |
call.flowDefinitionId, .flowVersion | Conversation flow identifiers/version, or null |
recording.bucket, .region | Selected recording destination values |
recording.s3Prefix, .transcriptS3Key | Actual prefix and full call-document key |
recording.recordingStatus | Snapshot: PROCESSING when stages are present, otherwise conversation status/null; not a live processing status |
recording.recordingFile | Conversation recording-file value/null at serialization time |
recording.stages | Uploaded stage descriptors supplied to the writer; empty when call JSON is written without persisted audio stages |
transcript | Sanitized transcript combined with recorded DTMF entries and sorted by timestamp |
dtmfEvents | DTMF sidecar array; field details below |
nodeHistory, actionsLog, finalContext, systemContext | Runtime data with additional sensitive-storage sanitization; not fixed complete object schemas here |
Stage descriptor fields are stage, s3Key, codec, sampleRate, bitDepth,
channels, byteCount and optional segments. Segment fields declared by the
writer type are startMs, byteOffset, byteLength, optional endMs, durationMs,
turnId, side, transcript, timestamp, provider, model, storageRedacted
and redactionReason. Optional/undefined members are not guaranteed JSON keys.
These descriptors identify the uploaded stages; their presence alone does not
verify media duration, channel layout or successful playback.
BigInts anywhere in this call payload serialize as strings. Runtime transcript, context, node and action values may contain arbitrary application data. Their nested shape depends on the application; the field list below does not define a closed schema for those runtime values.
Turn document and item fields
Both turn documents emit schemaVersion: 1, generatedAt, call and items.
The common call fields are conversationId and callId; integration metadata
may also be present.
The STT file keeps client-side items; the TTS file keeps bot-side items.
| Item field | Meaning / condition |
|---|---|
turnId | Nonblank segment turn-ID string, preserved unchanged, or null |
side | Display value Client or Bot |
speaker | Lowercase side client or bot |
timestamp | Segment timestamp, matching transcript ts/timestamp, or call-start plus segment offset; may be null |
startMs | Segment start offset |
endMs | Finite segment end, otherwise start plus available activity duration, otherwise null |
durationMs | Activity duration; may be null |
text | Segment transcript with matched transcript fallback; null for protected storage |
audio | Map of formats to relative object paths; may be empty |
s3Audio | Map of formats to full S3 object keys; may be empty |
mediaFormat | Activity media format |
provider, model | Segment metadata or null |
stage | Activity stage |
nodeId | Nonblank node-ID string from the matched transcript entry, preserved unchanged, or null |
storageRedacted, redactionReason | Added for protected items; true and the segment reason/fallback sensitiveInfoOnStorage |
Items are sorted by timestamp when both timestamps exist, otherwise by startMs.
Matching transcript fallback is sequential within each user/assistant role; do not
describe it as a verified semantic alignment of transcript and audio. The processor
supports raw/MP3 format outputs, but maps and actual objects depend on selection
and successful processing. A URL or object existence is not implied by a JSON key.
Redaction and DTMF boundaries
DTMF sidecars emit digit, startMs, durationMs, timestamp. Protected events
replace digit with null and add storageRedacted: true and the redaction reason.
startMs is the offset in milliseconds from when the call recorder started, or
from the call channel's start when no audio recorder runs. durationMs is the
keypress duration reported by telephony; when none is reported, Delphi stores
200. timestamp is the ISO 8601 UTC time of the key press. Repeated presses of
the same digit less than 80 ms apart are stored once. An unprotected event looks like this:
{"digit": "1", "startMs": 12037, "durationMs": 260, "timestamp": "2026-09-16T06:11:55.211Z"}
The transcript's DTMF entry uses nodeId: dtmf, role: user, source: dtmf, ts
and text DTMF <digit> or [Redacted], with protection markers when applicable.
Marked transcript entries are re-sanitized even when an in-memory PII snapshot is used. For a protected call, context fields become redaction markers. Node history retains selected structural/timing/usage fields, with transition/error payloads marked; action entries retain selected structural identifiers and markers. This is not a claim that every field in the entire call document is anonymized.
Logging PII controls must not be equated with storage redaction: the writer can prefer an in-memory caller/transcript snapshot when the database row is redacted. Source behavior is not a compliance or data-retention guarantee.
Investigate a missing or unexpected transcript
- Identify the conversation, product version and selected output artifact. Check the exact object key recorded for that conversation rather than reconstructing a prefix from its identifiers.
- For
call-transcript.json, inspect the recording uploader's result and errors. For either turn transcript, also check processing results and whether segment activities existed. An emptyitemsarray can be valid after side filtering. - If the JSON exists but audio cannot be fetched, distinguish an empty audio map, a missing object and denied storage access. A key in JSON is not a signed URL or proof of object existence.
- If text or DTMF is redacted, inspect the associated storage-protection markers. Changing a logging option does not restore redacted stored content.
- Preserve the conversation identifier, artifact key, product version and sanitized error details for investigation. Do not include production transcript text, credentials or caller numbers in a support example.
This reference describes writer behavior. It does not establish delivery latency, retention guarantees, complete nested application schemas or media interoperability.