Get Call Recording
Fetches a fresh signed URL for a call's audio recording from the Ultravox API. The caller must be an authenticated agency user, and the call must belong to their agency and have a recording available.
Endpoint
| Property | Value |
|---|---|
| Function Name | get-call-recording |
| HTTP Method | GET |
| Authentication | Supabase JWT (Bearer token in Authorization header) |
| Required Role | Any authenticated agency user (ownership validated by matching agency_id) |
Request
Headers
| Header | Required | Description |
|---|---|---|
Authorization | Yes | Bearer <supabase_jwt> |
Query Parameters
| Field | Type | Required | Description |
|---|---|---|---|
call_id | string (UUID) | Yes | The internal call ID (not the Ultravox call ID) |
GET /functions/v1/get-call-recording?call_id=550e8400-e29b-41d4-a716-446655440000
Response
Success (200)
{
"recording_url": "https://storage.example.com/recordings/call-abc123.wav?signature=..."
}
The recording_url is a time-limited signed URL that can be used to stream or download the recording.
Error Responses
| Status | Condition |
|---|---|
| 400 | call_id query parameter is missing |
| 400 | Ultravox API key is not configured for the agency |
| 401 | Missing or invalid Authorization header / JWT token |
| 403 | Authenticated user is not associated with an agency |
| 404 | Call not found, does not belong to the user's agency, or has_recording is false |
| 404 | Recording not available from Ultravox (no redirect or valid response) |
| 500 | Failed to retrieve agency credentials or unexpected server error |
Behavior
- Handles CORS preflight (
OPTIONS) requests. - Validates the JWT token via
supabase.auth.getUser(). - Looks up the user's
agency_idfrom theuserstable. - Fetches the call record from the
callstable and verifies:- The call exists.
- The call's
agency_idmatches the user's agency. - The call's
has_recordingflag istrue.
- Retrieves the agency's decrypted Ultravox API key via the
get_agency_credentialsRPC. - Makes a request to the Ultravox recording endpoint with
redirect: 'manual':- If a
302redirect is returned, extracts the signed URL from theLocationheader. - If a
200response is returned, constructs the direct recording URL. - Otherwise, returns a
404indicating the recording is not available.
- If a
Database Tables / RPCs
| Table / RPC | Operation | Description |
|---|---|---|
users | Read | Fetches agency_id for the authenticated user |
calls | Read | Fetches ultravox_call_id, agency_id, and has_recording for ownership and availability verification |
get_agency_credentials (RPC) | Read | Retrieves the decrypted Ultravox API key for the agency |
External APIs
| API | Method | Endpoint | Description |
|---|---|---|---|
| Ultravox | GET | /api/calls/{ultravox_call_id}/recording | Retrieves a signed URL for the call recording (returns 302 redirect or direct audio) |
Related Functions
process-enrichment-queue-- Fetches transcripts and checks recording availability during enrichmentwebhook-ingest-- Ingests call events that eventually create the call records queried here