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
| Property | Value |
|---|---|
| Function Name | voices-sync |
| HTTP Method | POST |
| Authentication | Supabase JWT (Bearer token) or Supabase apikey header (for cron jobs) |
| Required Role | Any 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
| Status | Condition |
|---|---|
| 400 | No Ultravox API key available (no agency has a configured key) |
| 401 | Missing or invalid authorization header (user flow) |
| 403 | User is not an agency user (user flow) |
| 405 | HTTP method is not POST |
| 500 | Failed to retrieve API credentials or failed to save voices to database |
| 502 | Ultravox API returned an error during voice fetch |
Behavior
- Determines the authentication mode:
- Cron job mode: If an
apikeyheader 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
- Cron job mode: If an
- Fetches all voices from Ultravox with pagination via
GET https://api.ultravox.ai/api/voices?limit=100, followingnextlinks until all pages are retrieved - Maps each voice to a database record with fields:
id(UltravoxvoiceIdas primary key),name,description,language_label,primary_language,ownership,billing_style,provider,preview_url,definition, andlast_synced_at - Performs a bulk upsert into the
ultravox_voicestable usingidas 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
| Table | Operation | Purpose |
|---|---|---|
users | Read | Resolve agency membership (user flow only) |
agencies | Read | Find an agency with a configured API key (cron flow only) |
ultravox_voices | Write (upsert) | Insert new voices or update existing ones |
RPC Functions Called
| Function | Purpose |
|---|---|
get_agency_credentials | Retrieve the Ultravox API key for the selected agency |
External APIs Called
| API | Method | Endpoint | Purpose |
|---|---|---|---|
| Ultravox | GET | /api/voices?limit=100 | Fetch all voices (paginated) |
Related Functions
- List Voices -- View the locally cached voices after syncing