Update Agent
Updates an existing agent's configuration in Ultravox and synchronizes the corresponding local agent_mappings record. Supports partial updates -- only the fields provided in the request body are updated. Local-only fields (client assignment, campaign assignment, default direction) are stored in the local database without touching the Ultravox API.
Endpoint
| Property | Value |
|---|---|
| Function Name | agents-update |
| HTTP Method | PATCH |
| Authentication | Supabase JWT (Bearer token) |
| Required Role | agency_owner or agency_admin |
Request
Headers
Authorization: Bearer <supabase_jwt_token>
Content-Type: application/json
Body
| Field | Type | Required | Description |
|---|---|---|---|
agent_id | string | Yes | The Ultravox agent ID to update. |
name | string | No | New display name. Sanitized for Ultravox (alphanumeric, underscores, hyphens; max 64 chars). |
system_prompt | string | No | Updated system prompt. |
voice | string | No | Updated voice identifier. |
language_hint | string | No | Updated language hint. |
temperature | number | No | Updated LLM temperature. |
first_speaker_text | string | No | Updated first speaker text. Set to a falsy value to clear. |
recording_enabled | boolean | No | Whether call recording is enabled. |
max_duration_seconds | number | No | Updated max call duration in seconds. |
tools | any[] | No | Updated tool definitions array. |
client_id | string | null | No | Client to assign (local only). Set to null to clear. |
campaign_id | string | null | No | Campaign to assign (local only). Set to null to clear. |
default_direction | "inbound" | "outbound" | null | No | Default call direction (local only). Set to null to clear. |
Response
Success (200)
{
"success": true,
"agent": {
"ultravox_agent_id": "uv-agent-abc123",
"name": "Updated_Agent",
"call_template": {
"systemPrompt": "Updated prompt...",
"voice": "terrence",
"temperature": 0.5,
"languageHint": "en",
"recordingEnabled": true
}
},
"mapping": {
"id": "uuid-of-mapping",
"client_id": "uuid-of-client",
"campaign_id": "uuid-of-campaign",
"last_synced_at": "2025-01-16T14:00:00Z"
}
}
If only local fields were updated (no Ultravox API call was needed) and the agent details were not already cached, the agent object contains only ultravox_agent_id. In that case, the function fetches the full agent details from Ultravox to include in the response.
If the local mapping does not exist, it is automatically created with managed_by_virsyn set to false (indicating an imported agent).
Error Responses
| Status | Condition |
|---|---|
| 400 | agent_id is missing from the request body |
| 400 | client_id is invalid or does not belong to the agency |
| 400 | campaign_id is invalid or does not exist |
| 400 | Ultravox API key is not configured for the agency |
| 401 | Missing or invalid authorization header |
| 403 | User is not associated with an agency |
| 403 | User role is not agency_owner or agency_admin |
| 404 | Agent not found in Ultravox |
| 405 | HTTP method is not PATCH |
| 500 | Failed to retrieve API credentials |
| 500 | Unexpected server error |
| 502 | Ultravox API returned a non-404 error during the update |
Behavior
- Authenticates the user via Supabase JWT and verifies they belong to an agency with the
agency_owneroragency_adminrole. - Validates the required
agent_idfield and optionalclient_id/campaign_idrelational fields. - Retrieves the agency's Ultravox API key by calling the
get_agency_credentialsRPC function. - Separates request fields into Ultravox fields (name, system_prompt, voice, language_hint, temperature, recording_enabled, max_duration_seconds, first_speaker_text, tools) and local-only fields (client_id, campaign_id, default_direction).
- If any Ultravox fields are provided, builds a partial update payload and sends a
PATCHrequest tohttps://api.ultravox.ai/api/agents/{agent_id}. - Sanitizes the
namefield for Ultravox constraints if provided (same rules as create). - Constructs a local mapping update payload containing all provided fields plus
updated_attimestamp. - If the Ultravox update succeeds, sets
last_synced_atand clearssync_errorin the local mapping. - Checks for an existing local mapping. If one exists, updates it. If not, creates a new mapping with
managed_by_virsynset tofalse. - If no Ultravox update was needed (only local fields changed), fetches the full agent details from Ultravox via a separate
GETrequest for the response.
Database Tables
| Table | Operation | Description |
|---|---|---|
users | Read | Fetches user profile to determine agency_id and role |
clients | Read | Validates client_id belongs to the agency (if provided) |
campaigns | Read | Validates campaign_id exists (if provided) |
agent_mappings | Read | Checks for existing mapping |
agent_mappings | Update | Updates the existing mapping record |
agent_mappings | Insert | Creates a new mapping if none exists (for imported agents) |
External APIs
| API | Method | Endpoint | Description |
|---|---|---|---|
| Ultravox | PATCH | /api/agents/{agent_id} | Partially updates the agent in Ultravox |
| Ultravox | GET | /api/agents/{agent_id} | Fetches full agent details (when only local fields were updated) |
Related Functions
- Create Agent -- Create a new agent
- Get Agent -- Fetch a single agent with full details
- Delete Agent -- Delete an agent
- Assign Agent -- Assign agents to clients/campaigns (local only)