Two routers
| Router | Prefix | Auth | Lookup key |
|---|---|---|---|
| Admin | /api/v1/recordings/{session_id} | require_admin (JWT) | session_id |
| Public | /api/v1/public/recordings/{token} | none (token is the secret) | recording_access_token |
recording_access_token minted during results ingestion. CRMs receive https://{host}/api/v1/public/recordings/{token} (built by build_public_recording_url in the call service) instead of a raw signed URL.
Resolving the recording key
Both routes load the call doc (projectingrecording_key, recording_url) and derive the storage key via _recording_key_from_call: prefer the stored recording_key, else take the last path segment of recording_url. A missing call → 404; an undeterminable key → 404.
Streaming with fallback
_stream_recording_key tries object storage first, then falls back to the originating fleet host:
- Object storage — if system settings
miniohas endpoint/access/secret/bucket, stream the object viaboto3(get_object, 8 KB chunks,Content-Disposition: inline). ANoSuchKey/404falls through; other storage errors are logged and also fall through. - Fleet fallback — iterate
cxbcore_fleetURLs andGET {base}/recordings/{key}withX-CXBCore-Secret. The first200wins;404s and request errors move to the next host. This covers deployments where recordings live on the originating fleet’s local MinIO.
404.
Storage helpers
The recording service also provides URL helpers used elsewhere (e.g. CRM push fallback and dashboard enrichment):| Helper | Purpose |
|---|---|
generate_signed_url | Presigned get_object URL (default 24h). |
generate_temporary_public_url | Short-lived presigned URL (minutes). |
extract_s3_key_from_url | Recover the storage key from a Spaces or legacy MinIO URL. |
enrich_call_with_accessible_url | Replace a stored URL with a fresh signed URL for playback. |
_region_from_endpoint / _endpoint_url | Infer S3 region (Spaces) and normalise the endpoint scheme. |
Operational checks
| Symptom | First place to check |
|---|---|
Public link 404 | Token mismatch, or no recording_key/recording_url on the call. |
| Storage path silently skipped | minio settings incomplete (endpoint/access/secret/bucket). |
| Fleet fallback never hits | cxbcore_fleet empty, or X-CXBCore-Secret mismatch with fleet. |
Spaces AccessDenied for CRM | CRM was sent a signed URL with query string instead of the token URL. |
| Wrong region on Spaces | _region_from_endpoint inference vs the configured endpoint. |
Related docs
Results ingestion
Where the recording token is minted.
CRM push
How the stable URL is sent to CRMs.
CXB Core post-call
How CXB Core uploads recordings and reports keys.