Skip to main content
Version: 0.9.19

Diagnose recording storage and processing

Use this procedure when a test call has missing recording outputs, remains in processing, fails playback, or is retained longer than expected.

Availability: You need a team role that can open the affected app's settings and conversation, and operator access to the API and recording-job logs. Inspecting the bucket requires separate access in your storage account. Do not share real transcripts, keypad values, credentials or unrelated call content when reporting a failure.

Trace the recording stages​

In words: the published selection and call-frequency check determine whether recording is requested. The available data and protection rules determine what can be retained. Upload and processing must succeed before objects exist in the bucket; playback and expiry have their own checks.

1. Confirm the published selection​

Record the release, app, team, conversation and time. Compare the published app settings with the intended recording selection. A saved draft is not sufficient.

For configuration integrations, inspect the effective combination of recordingOutputs and the compatibility field recordingEnabled. A nonempty valid explicit list wins. An empty or absent list with recordingEnabled: true resolves to all recording outputs; clearing only the list is not a reliable API-level way to disable recording. The UI's clear-selection action sets both fields consistently.

2. Check whether this call was selected​

With frequency 1, every eligible call is selected. For values above 1, the SIP runtime increments an app-scoped Redis counter and selects calls when the counter is divisible by the frequency. This is an app-level counter, not a percentage guarantee or a separate counter for every phone number.

Inspect recording_frequency_check for the app and call. If the counter check fails, the runtime logs RecordingFrequencyCheckError and allows recording rather than treating the error as a skip. Selection still does not prove successful retention.

3. Match outputs to available data​

ObservationCheck next
Transcript-only selection has no audio playerExpected; verify the selected transcript object separately
A selected turn transcript is absentCheck the release, output selection and processing result. From 0.9.18, a side with no turn activity has no file
A turn transcript exists with empty itemsCheck the release; 0.9.17-patch2 can write an empty side document, while 0.9.18 omits it
A selected audio output is absentCheck that the relevant source stage/turn audio existed and was eligible for retention
Protected intervals are missing from retained outputCheck the runtime storage-protection policy separately from app selection and PII log display

Use the recording output reference to interpret common JSON fields and object references. Integration-specific metadata is outside that shared reference. Do not reconstruct object keys from an assumed folder pattern or treat a declared JSON reference as proof that the object exists.

4. Check destination, upload and processing​

Confirm the team's current bucket, region and assumed-role configuration, as documented in Team recording storage. Inspect the upload result and any subsequent recording job before repeatedly changing app selections. Some outputs need post-call processing; a requested artefact is not a completed artefact.

A recent destination change is especially relevant: earlier objects are not automatically moved, while normal playback/deletion looks in the current team bucket. Coordinate recovery with the operator who owns the previous destination rather than deleting or recreating data.

Separate processing, lookup and browser playback​

Availability: from 0.9.18, recording retrieval honors the server's proxy settings and the Web UI retries a failed lookup. Neither changes the recording processor, so a missing recording-processed.mp3 remains a processing question.

  1. Correlate the affected conversation and selected output with the processing job, its result, and the exact bucket and object key. Check whether the full-call MP3 exists. A processing status, JSON reference or successful list response does not prove the object exists. Use the output reference for file roles.
  2. Open the conversation in the Web UI. When a lookup fails, the UI retries once automatically. If that also fails, it shows Couldn't load recordings with a Retry button. This differs from an empty list (MP3 not found yet) and from Processing failed.
  3. Search the API logs for Recording retrieval failed. The stage field names the failing step: resolve-credentials, assume-role, create-s3-client, list-objects or presign-urls. The entry also records bucket, region, prefix, usesAssumeRole, elapsedMs and the AWS error name, code, HTTP status and request ID.
  4. Check the lookup order against the stored keys. Delphi looks in the date-partitioned prefix recordings/<team>/<app>/YYYY/MM/DD/ first, then the flat timestamped prefix, then the legacy call-ID prefix. It stops at the first prefix that contains a full-call MP3.
  5. Check the credential source on the affected host. With an EC2 instance profile, confirm that instance metadata is reachable. When the team uses an assumed role, Delphi requests STS credentials for 15 minutes.
  6. Check the proxy rules. S3 and STS requests use the server's HTTPS_PROXY and NO_PROXY settings, and NO_PROXY accepts CIDR ranges. A working S3 proxy does not prove that credentials resolve through metadata.
  7. When the lookup succeeds, the API returns signed URLs that are valid for 15 minutes. Play the recording in the user's browser and confirm that audio plays. Signing does not fetch the object.

When you escalate, include the Delphi release and API image digest, conversation ID, job ID, sanitized object key, the log entry's stage and AWS error code, and the browser playback result for the same call. Omit credentials, signed URLs and real call content.

5. Verify retention independently​

Inspect the effective bucket lifecycle and the delphi-recordings-ttl rule described in Team recording storage. Check the enabled state, recordings/ prefix and expiration value. A successful Team settings save can coexist with a failed lifecycle update.

After correcting configuration, repeat a controlled call and verify the expected new objects, processing result and playback where applicable. Record the version, selected outputs, frequency decision, job outcome and destination identity. Do not claim that a corrected setting migrated or deleted earlier recordings.