Skip to main content
POST

Request Body

Required Fields

string
required
Display name of the agent (1-255 characters)
string
required
Organization ID to create the agent in (UUID format)

Agent Configuration

string
Description of what the agent does
string
Initial message the agent says when call starts. This is spoken immediately when a call connects.Example: "Hello! Thank you for calling Acme Corp. How can I help you today?"
string
Greeting spoken when this agent places an outbound call. Overridden by a per-call greeting; if empty, the agent auto-generates an opener from the call context (falling back to greetingMessage).Example: "Hi, this is Ava calling from Acme Corp."
string
System prompt defining agent behavior and personality. This guides the AI’s responses throughout the conversation.Example: "You are a helpful customer support agent for Acme Corp. Be friendly, professional, and concise. If you don't know an answer, offer to transfer the call to a human agent."
string
default:"simple"
Type of agent configuration.Supported values:
  • simple - Basic agent with standard configuration
  • advanced - Agent with additional features enabled
  • custom - Fully customizable agent configuration
  • appointment_scheduler - Agent optimized for scheduling appointments
  • receptionist - Receptionist agent for call routing and transfers
  • message_taker - Agent that takes messages and routes to directory extensions
  • blank_slate - Inbound agent started from a basic prompt, with no template behaviour
  • outbound - Agent that places calls rather than answering them
  • opentable_reservation - Restaurant agent that checks OpenTable availability and texts a booking link (see OpenTable Reservations)
  • translator - AI interpreter for a call between two people who do not share a language (English with Spanish, or English with French). Requires interpreterConfig (see Translator Agent)
object
Restaurant settings for an opentable_reservation agent. Ignored by every other agent type.Every field is optional — a half-configured agent still answers calls and degrades honestly rather than failing. See OpenTable Reservations for what each setting changes on a live call.Restaurant identity
  • restaurant_url (string) — the restaurant’s OpenTable page, e.g. https://www.opentable.com/r/your-restaurant
  • restaurant_id (string) — the numeric OpenTable ID, as text. Required before the agent can check availability
  • restaurant_name (string) — used on the phone and in the text message
  • restaurant_country, restaurant_macro, restaurant_neighborhood (string) — informational, returned when the URL is resolved
  • timezone (string) — IANA identifier, e.g. America/New_York. Every spoken date and time is resolved in it
Hours
  • service_windows (array) — up to 21 entries of { day, opens, closes }, where day is mon–sun and the times are 24-hour HH:MM. A day with no window is closed. A window whose closes is at or before its opens runs past midnight
  • last_seating_offset_minutes (integer) — how long before closing the last table goes out. Defaults to 30
Limits
  • min_party_size (integer) — defaults to 1
  • max_party_size (integer) — defaults to 8. Larger parties are routed to the events team
  • max_advance_days (integer) — defaults to 60
  • min_advance_hours (integer) — minimum notice. 0 (the default) allows same-day booking at any time
  • blackout_dates (array of YYYY-MM-DD) — one-off closures
  • constraint_violation_message (string) — what the caller hears when a request breaks one of these
Conversation
  • default_vague_time (HH:MM) — what “dinner time” resolves to. Defaults to 19:00
  • count_kids_in_party_size (boolean) — defaults to true
  • after_hours_greeting (string) — replaces the built-in closed-right-now greeting
  • escalation_keywords (array of string) — triggers an immediate handoff offer. Defaults to manager, complaint, sick, allergic reaction, urgent. Matching is on whole words, and the last word may be plural or inflected, so complaint also fires on “complaints”
  • private_dining_keywords (array of string) — routes a private-dining or event enquiry to the events team instead of the reservation flow. Defaults to private dining, private room, private party, private event, buyout, wedding, rehearsal dinner, corporate event, holiday party
Handoff
  • events_contact_number (string) — the events team’s number, which the agent can text rather than dial
Where a transfer DIALS is not part of reservation_config. Per-reason destinations are configured with the agent’s ordinary transfer_rules, the same field every agent type uses — write a rule per situation and the agent follows it. With transfer_rules empty the agent does not offer a transfer at all; it offers to take a message instead.Messaging
  • sms_line_type_check (boolean) — check the destination can receive SMS before sending. Defaults to true
  • sms_template_id (string) — which pre-approved template renders the message. One of booking_default, booking_brief, booking_with_restaurant. Bodies are not editable; see below
  • sms_provider (string) — twilio or netsapiens. Which carrier sends this Organization’s messages. Assigned by the Partner, not chosen per restaurant; when unset, the agent sends over whichever carrier is connected to it
  • sms_sender_extension (string) — the PBX extension NetSapiens sends from. Ignored by Twilio
  • email_fallback_enabled, callback_scheduling_enabled (boolean) — which fallbacks the agent may offer when a text cannot get through
Accepted but not yet acted on. These fields validate and store, and the API will keep accepting them, but nothing reads them on a live call yet: handoff_timeout_seconds, voicemail_fallback_enabled, voicemail_destination, sms_sender_display_name, tcpa_consent_script_variant. Setting them changes nothing today.
max_party_size must be greater than or equal to min_party_size, or the request is rejected with a validation error.
SMS message bodies cannot be authored freely. Twilio’s A2P 10DLC registration requires sample content that matches real sends, so one campaign only stays valid across every restaurant under a Partner if the copy is shared. sms_template_id selects from the pre-approved library; a value that is not in the library is rejected at send time rather than silently replaced with different copy.
object
Interpreter settings for a translator agent. Required when agentType is translator. Validated and stored whenever sent, on any agent type. It only has an effect on a translator agent. The keys inside the object are snake_case, but the stored value is not exactly what you sent: it is normalised first (scripts and names trimmed, empty names and unrecognised keys dropped). See Translator Agent for what each setting changes on a live call.
  • party_a_language (string, required) — en-US, es-US or fr-FR. Party A is the person greeted first
  • party_b_language (string, required) — the other language of the pair. The pair must be en-US with es-US, or en-US with fr-FR, in either order
  • opening_scripts (object, required) — one entry per pair language, keyed by language code, read word for word when the agent joins the call. Party A’s plays first
  • closing_scripts (object, required) — same shape, read once after both people say goodbye
  • business_name (string) — replaces {{business_name}} in the scripts
  • client_name (string) — replaces {{client_name}} in the scripts
  • register (string, required) — verbatim keeps the speaker’s wording, including fillers and hedges; plain renders the same meaning in plain language. The wizards default to verbatim; the API has no default
  • speaker_identification (string, optional) — how the saved transcript labels who said each line: language, voice or both. Omitted means language, and language is stored as an omitted key. It only changes the transcript labels, never what the interpreter says. voice and both add a small speech-to-text charge per minute. See Translator Agent
The Dashboard and Connect apply these rules, and the agent runtime re-checks the settings rules (every row except voice_provider, required and speaker_identification) when a call starts. The agent never rejects a call over speaker_identification: it treats an unrecognised value as language. If the stored settings break any other rule when a call starts (for example, because they were written before a rule existed), the agent ends the call without speaking; it never falls back to answering as an ordinary agent. Each rule has a stable code:A request that breaks a rule is rejected with 400 in the same format as every other validation error on this endpoint: "error": "Invalid request data", and one entry in details per problem. Errors for interpreterConfig rules have a path starting with "interpreterConfig", for example ["interpreterConfig", "opening_scripts", "fr-FR"] — required (the object missing, or null on a translator) has this same ["interpreterConfig"] path. voice_provider is the one exception — it validates ttsModel, not interpreterConfig, so it is reported at ["ttsModel"] instead. Each entry’s message contains the code from the table.Template defaults. When agentType is translator, every field the request does not set gets the same default the wizards write, and language is set to Party A’s language:
  • ttsModel cartesia, with the sonic-3 voice model. A translator’s Cartesia voice model is always in the sonic-3 family (sonic-3 or sonic-3.6): if voiceSettings.model is missing or outside that family (for example the retired sonic-2 or sonic-3.5, or any other value), the API sets it to sonic-3 rather than rejecting the request, and a missing voice_id gets the template voice
  • model gpt-4.1, voiceModel gpt-4o-realtime-preview and sttModel deepgram
  • end-of-speech timing: voiceSettings.min_endpointing_delay 0.1, max_endpointing_delay 2.0, vad_min_silence_duration 0.55
  • background and thinking sounds off
  • echo detection, automated-caller detection and call detection off
  • transfers, warm transfer, knowledge base and the email tool off
  • no tools
  • recording off (enableRecording: false)
  • stored with detached: true, so Connect treats the agent as already detached from its template and shows the full editor
The on/off settings a translator does not use are always stored off, even when the request sends them on: ragEnabled, transferEnabled, warmTransferEnabled, webTransferEnabled, emailToolEnabled, echoDetection, detectAutomatedCallers, callDetection, screenshareEnabled, and background_audio_enabled, thinking_sounds_enabled and response_filler_enabled inside config (its other keys are kept). A Mobile_Call_Detection tool in extensions.tools is dropped; other tools are kept.Send any other field to override its default. Each field is defaulted as a whole object or array, not merged key by key: sending a partial voiceSettings (for example only voice_id) skips the entire default, so include the three timing keys above if you send voiceSettings at all (a missing or non-sonic-3-family voice model is still set to sonic-3 for you, as described above). A ttsModel other than cartesia is rejected with voice_provider.
The agent says the opening scripts to both people on every call, and they are its disclosure that the people are speaking through an AI interpreter. Keep that disclosure when you write your own scripts.
string
default:"active"
Activation status of the agent. Defaults to active when omitted, so most callers can leave this out.Supported values:
  • active - Agent is live and can take calls
  • inactive - Agent is disabled and will not take calls
  • cancelled - Agent has been cancelled
  • pending - Agent is awaiting activation
Any other value (for example draft) is rejected with a 400. The same values can be changed later via Update Agent.

AI/Voice Model Configuration

string
default:"gpt-4.1"
AI model used for the agent’s language processing. See List LLM Models for the full list with descriptions.Supported values:
  • gpt-4.1 - OpenAI GPT-4.1 (default, recommended, can never be locked out)
  • gpt-4o - OpenAI GPT-4o
  • gpt-4o-mini - OpenAI GPT-4o Mini
  • gpt-4.1-mini - OpenAI GPT-4.1 Mini (faster, more cost-effective)
  • gpt-4.1-nano - OpenAI GPT-4.1 Nano (smallest, fastest)
  • grok-3-fast - xAI Grok-3 Fast
  • moonshotai/Kimi-K2.6 - Moonshot AI Kimi K2.6 (served via Telnyx)
  • claude-sonnet-4-6 - Anthropic Claude Sonnet
  • google/gemma-4-31b-it - Google Gemma 4 31B, served via LiveKit Inference
A Partner or Reseller can lock individual models for an organization via Feature Administration. Requesting a model that is locked is rejected with 403 forbidden. Call List LLM Models with organization_id to get the exact set of models the target organization may currently use.
string
default:"gpt-4o-realtime-preview"
Voice model for real-time speech processing
string
default:"deepgram"
Speech-to-text model.Supported values:
  • deepgram - Deepgram STTv2 with flux-general-en model (recommended)
string
default:"cartesia"
Text-to-speech model.Supported values:
  • cartesia - Cartesia TTS (high quality, supports custom voices)
  • minimax - MiniMax TTS (multilingual support)
  • inworld - Inworld TTS (set voiceSettings.voice_id to a full Inworld voice string, e.g. Inworld.TTS2.Ashley)
When Feature Administration is enabled, a provider locked for the target organization is rejected with 403 forbidden. cartesia can never be locked, so omitting this field is never refused on that ground.
object
Voice configuration settings. Structure varies based on ttsModel.
Default when omitted: For a Cartesia agent (the default ttsModel), omitting voiceSettings creates the agent with the standard voice f786b574-daa5-4673-aa0c-cbe3e8534c02 (Katie – Friendly Fixer) on the sonic-3 model. For a MiniMax agent, omitting voiceSettings leaves it unset.
For Cartesia (ttsModel: "cartesia"):
Cartesia voices also accept two optional fields:
A custom (cloned) voice_id runs on the sonic-3 family (sonic-3 or sonic-3.6). An omitted model counts as sonic-3, and a retired sonic-2 or sonic-3.5 is saved as sonic-3.
English Cartesia voices accept a model override (e.g. sonic-3.6; sonic-3 is the default for new agents) but not a language override. Non-English voices (e.g. Spanish) require both a model and a matching language:
For MiniMax (ttsModel: "minimax"):
Advanced Voice Timing (optional, applies to all TTS models):Example with advanced timing:

Call Features

boolean
default:"false"
Whether SIP call transfer is enabled. When enabled, the agent can transfer calls to:
  • SIP extensions: Format sip:extension@hostname
  • US phone numbers: Automatically formatted to tel:+1XXXXXXXXXX
boolean
default:"false"
Whether the agent can send emails during or after calls
string
Instructions for the agent on how and when to use the email tool
boolean
default:"false"
Mobile calls detection: look up whether the caller’s number is a mobile phone before the call starts. This is not answering machine detection — see amdConfig under Outbound Calling.
boolean
default:"true"
Let a caller on the web-embedded agent be transferred. Only takes effect when transferEnabled is true; otherwise stored as false.
boolean
default:"false"
Whether to enable echo detection during calls
boolean
default:"false"
Enable call recording. Recordings are saved to cloud storage and accessible via the Call Logs API.
Include a link to the call recording in the post-call summary notification. This is a sub-option of call recording — it requires enableRecording: true. Sending true without recording enabled returns a 400. Note: the link is delivered via the call-summary email, so it is only actually sent when the agent also has an email recipient configured and a recording was produced; otherwise the flag is stored but has no effect.
string
Rules and conditions for call transfers. Describes when and where the agent should transfer calls.Example: "Transfer to +15551234567 if the caller asks for billing support. Transfer to +15559876543 for technical issues."
array
Array of email addresses used for notifications and the email tool.Example: ["[email protected]", "[email protected]"]
string | null
UUID of the email server to use for this agent. Must belong to the same account. If omitted or null, the account’s default email server is used.Use the List Email Servers endpoint to retrieve available IDs.
boolean
default:"false"
Whether this agent can ask a web-embedded caller to share their screen and reason about what it sees. See Screenshare. Ignored for SIP/PSTN calls, which have no browser to share.Turning it on also requires the organization to have opted in to Screenshare, which is off by default and which this field does not control — an agent can be created with screenshareEnabled: true in an organization that has not opted in, and no call will start a share until it does.Returns 403 forbidden when:
  • Screenshare is locked for the organization via Feature Administration,
  • the agent’s model (this request’s value, or the default gpt-4.1 if omitted) cannot read images, or
  • the organization is flagged Healthcare, which can never opt in to Screenshare.

Localization

string
default:"en-US"
Agent language for speech recognition and responses.Supported values:
  • en-US - English (US)
  • es-US - Spanish (US)
  • multi - Multilingual (English, Spanish, French, German, Hindi, Russian, Portuguese, Japanese, Italian, Dutch)
string
default:"America/New_York"
Agent timezone in IANA format. Used for date/time operations and calendar scheduling.Example: "America/New_York", "Europe/London", "Asia/Tokyo"

Knowledge Base

Array of URLs the agent can reference for knowledge. The content at these URLs is ingested and made available to the agent during conversations.This is a legacy field and is not the RAG Knowledge Base — for vector search use ragEnabled and knowledgeBaseId below.Example: ["https://example.com/faq", "https://example.com/pricing"]

RAG Knowledge Base

Attach an organization-level Knowledge Base as part of the create request, so you do not need a follow-up Update Agent call.
boolean
Enable live vector search during calls. Requires knowledgeBaseId — an agent with no knowledge base does not retrieve regardless of this flag. Returns 403 forbidden when Knowledge Base is not enabled for the target organization.
string | null
Knowledge base the agent searches. It must belong to the same organization the agent is being created in; a knowledge base from another organization is rejected.Use List Knowledge Bases to retrieve available IDs.
object
RAG retrieval configuration. Unknown keys are rejected.
Omitting these fields leaves the defaults in place: rag_enabled is false, knowledge_base_id is null, and rag_config is { "top_k": 5, "rewrite_query": false }.

Business (Google Place)

string
Google Place ID linking the agent to a Google Business Profile listing. The platform fetches the listing’s details (hours, location, phone, website, services, ratings) shortly after creation, and the agent uses them as verified facts when answering callers.Example: "ChIJVS6XxJPFU4gRoE8c8ql2lCQ"

Warm Transfer

boolean
Enable warm transfer routing for this agent.
string
What the AI says to the human agent on the consult leg of a warm transfer, separate from the rules for when to transfer. Blank uses the built-in briefing. See Warm Transfer.
string
Plain-language rules for when and where to warm transfer. Example: "If the caller asks for billing, confirm first and warm transfer to pbx:1234."
string
Public URL of the hold-music file played during warm transfer. The easiest way to set this is Upload Hold Music, which saves the URL for you. Leave empty for built-in hold music.
boolean
Whether the original caller’s number is passed to the transfer destination. Defaults to true.

Pronunciations

array
Custom pronunciation rules for specific words and names, using IPA (International Phonetic Alphabet) format. The agent’s TTS engine will use these rules to pronounce words correctly.
Custom pronunciations are supported on Inworld voices, Cartesia voices using the sonic-3 or sonic-3.6 model, and MiniMax voices on English agents only. They are not supported on Cartesia sonic-2, nor on MiniMax when language is es-US or fr-FR — MiniMax accepts pronunciation phonemes for English only and mis-renders Spanish and French. Set ttsModel to minimax or inworld, or to cartesia with voiceSettings.model set explicitly to sonic-3 or sonic-3.6 (an omitted model does not count); otherwise a non-empty pronunciations array is rejected with 400. Send an empty array [] to clear rules on any voice.You store each pronunciation once and it works on any supported voice, provided it was generated with Apply — the phonemes must be IPA in Cartesia’s <<…>> form. Hand-typed free-text phonemes work on Cartesia only and are silently ignored on MiniMax and Inworld, and rules generated for a Spanish or French voice are ignored on MiniMax. Multi-word entries such as New York work on Cartesia but are ignored on MiniMax and Inworld, whose syntax covers a single word each.Each entry also accepts an optional lang (en | es | fr) recording which language the phonemes were written for. It decides whether MiniMax can speak the row — MiniMax accepts English phonemes only. Omit it and the agent’s language is used as the fallback.
Each entry is an object with:
  • word — The word or name (1–100 characters)
  • phonetic (optional) — A plain-English respelling of how the word should sound (e.g., jay-kob-sen). Used by the dashboard’s “Apply” helper to generate the IPA phonemes; not used directly by the agent.
  • phonemes — The IPA phoneme string (e.g., <<ˈ|dʒ|eɪ|k|ə|b|s|ə|n>>)
  • lang (optional) — en | es | fr. Which language the phonemes were written for, recorded when they are generated. Decides whether MiniMax can speak the row (MiniMax accepts English phonemes only); omit it and the agent’s language is used as the fallback.
Example:

Outbound Calling

These fields apply to agents that place calls. See Outbound Calls.
string
A fixed line spoken word for word before the outbound greeting — for warnings or advisories that the AI must never rephrase. Leave it empty and the agent starts from its greeting or instructions.
boolean | object
default:"false"
Answering Machine Detection. true enables it with the defaults, false disables it, an object tunes it. Unrelated to callDetection.Unknown keys are rejected. Partial objects are fine; unset keys use the defaults. GET /v1/agents/{id} returns this as amd_config.
string
Spoken after the beep when detection reaches a voicemail box and on_machine is leave_voicemail. Empty means hang up without leaving a message.
string
Pre-recorded voicemail audio, played instead of speaking voicemailMessage when set. If it cannot be fetched on the call, the text is spoken instead.
boolean | object
default:"false"
IVR Menu Navigation. true enables it with the defaults, an object tunes it: enabled, target_intent (reach_human, reach_department, custom), target_department (max 200), spoken_keywords (up to 20 strings), max_attempts (1–10), max_duration_ms (up to 600000), fallback_action (press_zero, hang_up, wait_for_human), hold_max_wait_ms (up to 1800000).Requires detection: a request that would leave navigation on while amdConfig is off is refused with 400, in either direction — send both fields to change them together. dtmf_transport is not accepted (the DTMF method is a trunk-level setting). Returned by GET as ivr_navigation.
string | null
The retry policy every call this agent places follows, unless the trigger request sends its own retry_policy_id. Must belong to the account.
object | null
Compliance controls for this agent. null or omitted means none: nothing is required and nothing is refused. Unknown keys are rejected.
  • require_consent_basis (boolean) — every trigger must send a consent_basis or is refused with 400 consent_required
  • calling_windows (object) — start_local and end_local as 24-hour HH:MM on the callee’s clock (end exclusive, no wrapping midnight), timezone_source (callee_npanxx, agent_timezone, explicit) and timezone (required for explicit)
  • abandon_rate_alert_threshold (number 0–1) — the abandon rate above which GET /v1/metrics flags this agent. Defaults to 0.03
Distinct from a retry policy’s contact_policy, which holds per-number attempt caps. Returned by GET as contact_policy.

Advanced Configuration

object
General configuration object for additional settings.Example:
object
Extensions configuration for webhooks and MCP servers.Structure:
Webhook fields:Webhook conditions:
  • before_call - Execute before the agent answers (pre-fetch caller info)
  • during_call - Execute while call is active (create tickets, real-time lookups)
  • after_call - Execute after call ends (log to CRM, send summaries)
Parameters: Leave the value empty for fields you want the AI to extract from the conversation. Provide default values for fallbacks.
Listings Search tool (type: "listings_search"). Lets the agent search a listings page during a call; see Listings Search. An agent can have one.
All parameters values are strings. Keys you leave out take their defaults. The stored tool always carries all ten keys, and name, friendlyName and condition are always stored as shown above, so a GET returns the tool in this full form.Adding or changing the source means adding the tool, changing its canonical listings_url, or turning fetch_detail_pages from "false" to "true" on an AppFolio page. Only that needs attested_by, sets a new attested_at, and is checked against the Listings Search gate (403). Any public https:// listings page can be saved this way once attested; a non-AppFolio page needs no extra step. Re-sending the tool unchanged (a different URL casing, a trailing / or a query string on an AppFolio address counts as unchanged) keeps the stored attested_by and attested_at whatever you send, but the tool is still validated against the rules below.enabled: false is refused: to switch Listings Search off, remove the tool. Another tool in extensions.tools whose function name is search_listings or send_listing_link is refused too, because Listings Search registers those names.An invalid tool is rejected with 400 Invalid request data, and details names the problem:On create, a listings_search tool always counts as adding the source: attested_by is required and the Listings Search gate applies.

MCP Servers Request Body

Each entry in the mcp_servers array inside extensions is validated at write time. The request shape is different from the stored shape returned by GET. Validated request fields for each mcp_servers entry:
Pre-answer lookup on an MCP connection
After saving, the platform transforms each entry to the stored MCPConnection format: name → connection_name, url → mcp_endpoint_url, auth_headers array → header object, and assigns a generated id. See Get Agent — Stored MCP Connection Shape for the full list of stored fields.
The Get Agent response returns the stored shape with snake_case keys: id, connection_name, mcp_endpoint_url, transport_type (lowercase sse or http), and optional tools entries with name and description only. Do not paste a GET mcp_servers array into a create or update body without transforming it to match the request fields above.The schema is strict — any unrecognized field in an mcp_servers entry (for example, fields from the stored GET shape such as connection_name, mcp_endpoint_url, or id) will be rejected with a 400 error. Only url, name, transport_type, auth_headers, initialization_options, allowed_tool_names, and pre_answer_calls are accepted.
MCP servers are auto-tested on save. When you include extensions.mcp_servers, the API tests each server (opening the transport and listing tools). Reachable servers are stored with a fingerprint and discovered tools, and appear with a green Connected badge in the Portal (agent → Integrations → MCP). Servers that are unreachable at save time are still stored, but without a fingerprint — they appear with a yellow Not tested badge, and the response includes a non-fatal warnings array:
To validate a configuration before creating an agent, use Test MCP Connection.
The integrations field cannot be set on create. After creating the agent, configure integrations (ModMed, Google/Outlook Calendar, NetSapiens) via the Dashboard or with the integrations field on Update Agent. Twilio is connected once per organization in the Dashboard or Connect (Twilio); Update Agent accepts only the agent’s twilio.fromNumber. Integration secrets are write-only — they never appear in API responses, including this endpoint’s response. MCP servers can be configured in the Dashboard under agent Integrations, or via extensions.mcp_servers on this endpoint and on Update Agent.

Built-in Agent Functions

When created, every agent automatically has access to these functions that the AI can call during conversations:
Additional functions are added based on enabled integrations (Google Calendar, Outlook, ModMed), configured webhook tools in extensions.tools, and MCP servers in extensions.mcp_servers.

Feature Administration gating

When Feature Administration is enabled, agent creation is validated against the feature gates of the target organization — including locks inherited from its reseller or partner. The API returns 403 forbidden when the request:
  • sets warmTransferEnabled: true while Warm Transfer is locked;
  • names a ttsModel that is locked for the organization. cartesia is never gated — it cannot be locked, and it is the value assigned when ttsModel is omitted, so a create that does not ask for a specific provider is never refused on this ground;
  • selects a cloned voice in voiceSettings.voice_id while Custom Voices is locked;
  • sets a non-empty googlePlaceId while Business Listing (Google Places) is locked;
  • sets agentType to receptionist, appointment_scheduler, message_taker, blank_slate, outbound, opentable_reservation or translator while the matching Template is locked;
  • sets screenshareEnabled: true while Screenshare is locked for the organization;
  • includes the ns_reset_password tool in extensions.tools while NS Password Reset is locked;
  • includes a listings_search tool in extensions.tools while Listings Search is locked. The error is Feature(s) not available for this organization: listings_search, and it is returned even when the tool is also invalid;
  • includes a UCaaS function in extensions.tools while that function — or the Netsapiens integration itself — is locked. Each function has its own gate: A Chat Notification tool is recognised by more than its name: any tool with type: "notification" counts if its name begins ns_chat/NS_Chat, if it carries a {"key": "type", "value": "ns_chat"} parameter, or if its notification parameter contains "type": "ns_chat". Those are the same shapes the agent runtime accepts, so a payload that would start a chat is gated whatever it is called. Netsapiens is checked as well as the function’s own feature, so withdrawing the integration blocks all seven at once; when both are locked the error names the integration.
    You can seed extensions.tools by copying them from an existing agent’s GET response: tools[].type accepts the internal types a GET returns, including the netsapiens type these UCaaS tools carry. Two exceptions are rejected with 400: a payment tool — enable it afterwards with PUT /v1/agents/{agentId}/payments/tool — and tool parameters that are not an array of {"key": ..., "value": ...} strings. That includes the Zendesk and Freshdesk template tools (a parameters object; numeric values with a type key), which can only be sent back exactly as GET returned them on Update Agent, {"name": ..., "value": ...} parameters, and flow-builder custom function tools.
Omitting a field, or sending it as null, is never blocked — so you can always create an agent without the locked capability.
The Screenshare model check is independent of Feature Administration. Setting screenshareEnabled: true on an agent whose model cannot read images returns the same 403 forbidden whether or not Feature Administration is enabled for the organization, and whether or not Screenshare itself is locked — see screenshareEnabled above.
The Screenshare Healthcare refusal is independent of Feature Administration too. A Healthcare-flagged organization can never opt in to Screenshare, so arming an agent there returns 403 forbidden whether or not Feature Administration is enabled and whether or not Screenshare itself is locked.
agentType values of simple, advanced and custom are never gated by a template lock. They do not identify a single template: simple is the stored type for the Support Agent (CRM) templates and is also the default when agentType is omitted, so a request using it cannot be attributed to one template and is treated as not having chosen a template at all. Callers that never used a template are therefore unaffected by any template lock.