agents:manage scope. Reading agents, voices, the default agent and your numbers only needs calls:read.
Creating an agent
name, system_prompt and opening_line are required. Everything else has a default: the agent is turned on, places calls (direction: "outbound"), speaks Hindi or Hinglish, and uses the google engine with its default voice.
The API checks every value and refuses what the dashboard would quietly repair. An engine or voice it does not know is
422 with the valid options in details, never replaced by a default voice; a number out of range is 400, never clamped:
speech_cache_mode is shown on every agent but set by our support team only.
Editing an agent
PATCH changes only the fields you send. Everything else keeps its stored value, including the voice engine, the action rules and the speech cache. Send null to clear a field that can be empty (language, max_call_minutes, pace, booking_page_id…), and [] to empty a list.
tts_model needs a voice of the new engine in the same request, because the engines share no voices.
Avoiding lost updates
Two systems editing the same agent can overwrite each other’s changes. Send the agent’supdated_at from your last read as an If-Match header (or as expected_updated_at in the body): when the agent changed since, the request is refused with 409 version_conflict (details.current_updated_at) and nothing is saved. Read it again, re-apply your change and retry. Without the header the last write wins, as before.
Turning an agent off
POST /v1/agents/{id}/disable turns the agent off and cancels every call still waiting for it, whatever started it: API calls, workflows, bulk campaigns or a counsellor’s AI call button. Each canceled call carries the reason, and the response says how many (waiting_calls_canceled). Calls already ringing finish normally.
The response warns you when the agent is your default agent (calls that rely on the default are canceled until you choose another) or answers an inbound number (callers hear that the assistant is unavailable until you move the number).
POST /v1/agents/{id}/enable turns it back on. Calls canceled while it was off are not restored; start them again.
Cancelling applies to an agent that exists and is turned off. When a waiting call’s agent cannot be found at all — it was deleted, or your default agent setting names an agent that does not exist — API calls are canceled, but workflow, bulk and manual calls still dial with a generic voice, as they always have. Set a default agent that exists to avoid that.
Voices
GET /v1/voices lists every engine with its voices and what a connected minute costs:
gender matters for Hindi: the agent conjugates first-person verbs to match it. deepgram speaks English only; an agent in any other language cannot use it (422 voice_language_mismatch). pricing is null if prices could not be read at that moment.
The default agent
Workflow, bulk and manual AI calls that do not name an agent use your account’s default agent.outbound or both). Only this one setting changes; the rest of your AI calling settings are kept. If someone has the AI Calling settings page open in the dashboard while you change it, saving that page afterwards can put the old default back; read it again with GET if in doubt.
API calls always name their agent with agent_id and are not affected by the default.
Inbound numbers
On Vacademy Voice, a call to one of your numbers plays the number’s IVR menu, and an AI agent step in that menu hands the caller to an agent.GET /v1/numbers shows, per number, which agent answers and how:
PUT /v1/numbers/{id}/agent with {"agent_id": …} points the number’s AI step at another agent. To keep it safe, the API only does this when the change is unambiguous: the number plays a menu with exactly one AI agent step and no other number plays the same menu. Anything else is 409 number_routing_complex with details.reason (no_menu, menu_without_ai_agent, menu_with_several_ai_agents or menu_shared); change those in the dashboard’s IVR builder. The agent must be turned on and answer calls (direction inbound or both).
Deleting an agent
DELETE /v1/agents/{id} deletes an agent nothing uses any more. While something still relies on it, it is refused with 409 agent_in_use and a list of the places, so nothing silently falls back to another voice: