Skip to main content

Sync Voices

Fetches all voices from the Ultravox API and upserts them into the ultravox_voices table. Unlike tools, voices are global and shared across all agencies. This function can be triggered by an authenticated agency user or by a cron job using the Supabase API key.

Endpoint

PropertyValue
Function Namevoices-sync
HTTP MethodPOST
AuthenticationSupabase JWT (Bearer token) or Supabase apikey header (for cron jobs)
Required RoleAny authenticated agency user, or service-level API key

Request

Headers

For authenticated user requests:

Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json

For cron job / service requests:

apikey: <supabase_anon_or_service_key>
Content-Type: application/json

Body

No request body is required.

Response

Success (200)

{
"success": true,
"message": "Synced 42 voices from Ultravox",
"stats": {
"synced": 42
}
}

When no voices are found in Ultravox:

{
"success": true,
"message": "No voices found in Ultravox",
"stats": {
"synced": 0
}
}

Error Responses

StatusCondition
400No Ultravox API key available (no agency has a configured key)
401Missing or invalid authorization header (user flow)
403User is not an agency user (user flow)
405HTTP method is not POST
500Failed to retrieve API credentials or failed to save voices to database
502Ultravox API returned an error during voice fetch

Behavior

  • Determines the authentication mode:
    • Cron job mode: If an apikey header is present without a user JWT, selects any agency that has a configured Ultravox API key and uses its decrypted key
    • User mode: Authenticates via Supabase JWT, verifies the user belongs to an agency, and uses their agency's Ultravox API key
  • Fetches all voices from Ultravox with pagination via GET https://api.ultravox.ai/api/voices?limit=100, following next links until all pages are retrieved
  • Maps each voice to a database record with fields: id (Ultravox voiceId as primary key), name, description, language_label, primary_language, ownership, billing_style, provider, preview_url, definition, and last_synced_at
  • Performs a bulk upsert into the ultravox_voices table using id as the conflict key, updating all fields on conflict
  • Does not delete old voices (voices are rarely removed from Ultravox)
  • Returns the count of synced voices

Database Tables Read/Written

TableOperationPurpose
usersReadResolve agency membership (user flow only)
agenciesReadFind an agency with a configured API key (cron flow only)
ultravox_voicesWrite (upsert)Insert new voices or update existing ones

RPC Functions Called

FunctionPurpose
get_agency_credentialsRetrieve the Ultravox API key for the selected agency

External APIs Called

APIMethodEndpointPurpose
UltravoxGET/api/voices?limit=100Fetch all voices (paginated)
  • List Voices -- View the locally cached voices after syncing