Create an agent
Creates an agent. The row is stored immediately and returned with 201 in about 1-2 seconds;
provisioning with the voice engine continues in the background for about 30-45
seconds. Meanwhile operations that need the provider (GET /api/agents/{agentId}/signed-url,
tools, workflow, knowledge, MCP servers) answer 409 AGENT_PROVISIONING with Retry-After: 5.
Edits sent with PATCH /api/agents/{agentId} during that window are picked up by provisioning.
Only name, voiceId and language are required. Runtime tuning you omit is seeded from the
objective (category), and when analysis is omitted a default set of success criteria and
extraction fields for that objective is stored. When firstMessage is empty a greeting is built
from the agent name and the workspace’s business name.
objectionHandlers reaches the agent (2026-09-15). The answers you write are rendered into
the agent’s instructions on every prompt build, whatever the agent’s category, and override the
generic objective playbook where they differ. The limits are small because the instructions are
read on every turn — 5 objections, 100 characters for the objection, 200 for the answer — and a
body over them is refused rather than trimmed.
Retired fields (2026-09-15). escalationRules and skills are no longer part of the agent
contract. Sending either one — with any value, null and [] included — is refused with
400 VALIDATION_FAILED, and neither is returned by any agent endpoint any more. Omit them.
Use the hand-over tool (needs_human / request_help) instead of escalationRules, and
department instead of skills.
Checks run in this order, and the first failure answers: role and plan agent cap, body validation,
workspace still exists, reserved qa_ criterion ids, fraud screening of the prompt, first message
and objection handlers, cloned-voice plan check, dial policy for transferPhoneNumber, template
access, and a final atomic agent-cap check at insert time.
With ?async=true only the role, plan cap and body validation run in the request; the call answers
202 with a job id and everything else runs in a worker. Poll GET /api/agents/jobs/{jobId}
(kept for one hour) for the result or the error.
Side effects. Calls an LLM to screen the prompt for fraud (a blocked prompt is recorded as a fraud flag on the workspace). Inserts the agent and version 1 of its change history, then enqueues the voice-engine provisioning job, which creates the voice agent and attaches the post-call webhook, tools and MCP gateway. Writes an audit entry. An in-app notification is posted when provisioning finishes or fails.
Idempotency. Not idempotent. Retrying after a timeout creates a second agent (and a second voice
agent) and consumes another slot of the plan’s agent cap. Check GET /api/agents?search= before
retrying.
Webhook events. agent.created ({ agent_id, name, category, language, template_id, channels }, never the agent’s instructions) once, as soon as the row is saved, and audit.log_recorded (when subscribed). See Webhooks.
Access
- Required scope:
write. Signed-in users need the owner, admin or member role; viewers get403 Insufficient permissions. - Rate limit: Agent mutations — 10 requests/min per workspace, shared with every agent, A/B variant, tool and knowledge write; the request also counts against the General API limit. See Rate limits.
- Plan: Agent cap by plan — Starter 2, Growth 5, Business 12, Enterprise unlimited, plus purchased agent add-ons; a workspace without an active plan or trial cannot create agents. Custom cloned voices require Enterprise.
Authentication
Workspace API key: jl_ followed by 64 lowercase hex characters, created by the workspace owner in the
dashboard (Settings → API Keys) and sent as Authorization: Bearer jl_.... The plaintext is shown once,
at creation; Jelliu stores only a SHA-256 hash. A workspace can hold up to 25 active keys.
Operations restricted to admins or owners reject keys without the full scope with 403, and say so in
their description. No key, whatever its scope, can mint or revoke API keys or rotate a webhook secret —
that requires a signed-in owner session. A revoked key stops authenticating within about 10 seconds.
See Authentication.
Query parameters
Send true to queue the creation and receive a job id (202) instead of the agent. Only the
literal string true is recognised; any other value (1, yes) is ignored and the creation
runs synchronously.
Request
Display name of the agent, also used in the generated greeting. 1-100 characters.
Voice id (see the voices endpoints). A custom cloned voice requires the Enterprise
plan (403 BILLING_ERROR otherwise).
Main language of the agent: es (Spanish), es-CO (Colombia), es-MX (Mexico), es-AR
(Argentina), es-neutral (neutral Latin American Spanish), en, en-US, pt, pt-BR. Common
labels are also accepted case-insensitively and normalised (for example Español (LATAM) →
es-neutral, Portuguese → pt, México → es-MX); anything else is rejected with 400.
Channels the agent may answer on. Omitted = every channel. At least one. The list is stored as sent and later edits replace it — it is never a delta.
Objective template (per-objective playbook layered under the workspace prompt). Must be a system
template or one owned by the workspace; otherwise 400.
The agent’s objective. It selects the base agent, default tuning and default analysis, and wins
over the template’s category. Omit to inherit the template’s category. Values: sales,
support, scheduling, surveys, collections, retention, notifications, interview
(candidate screening), language_assessment (scored spoken evaluation), personal (personal
assistant), general.
The workspace’s own prompt layer, placed on top of the platform and objective layers. Trimmed. Must be empty (the agent introduces itself generically and never invents a product) or 10-8000 characters. Screened for fraud. Catalogues and price lists belong in the knowledge base.
Opening line. Trimmed. When empty a greeting is generated from the agent name and the workspace’s
business name (for example Hola, le habla Sofía de Cafés del Huila. ¿Cómo está?). Screened for fraud.
Key/value strings stored with the agent (at most 50 entries; keys up to 100 characters, values up to 500). Stored and versioned; not currently applied to conversations.
Your business’s own answers to the objections it hears, as objection → answer. They are applied to conversations: every path that builds the agent’s instructions renders them into the client section, which overrides the generic objective playbook wherever the two differ. The render does not look at the category, so answers reach an agent of any objective.
At most 5 entries; an objection key is 1 to 100 characters and an answer 1 to 200. The
instructions are read on every turn of every conversation, which is why the limits are
small. Anything larger is refused, never trimmed, so you are never told text was saved
when half of it was dropped: 400 VALIDATION_FAILED with the reason in
error.details.fieldErrors.objectionHandlers (for example Máximo 5 objeciones). Empty
keys and empty answers are refused the same way.
Each answer is screened for fraud. Stored and versioned with the rest of the agent.
Hard cap on a voice call, in seconds (30-3600). Omitted = the objective’s cap. The objective’s cap also acts as a ceiling when the provider configuration is derived.
E.164 number the voice agent may transfer live calls to. The destination must be allowed by the
workspace dial policy (403 COMPLIANCE_BLOCKED otherwise).
Whether the agent opens by saying it is an AI. true/false is this agent’s decision and
overrides the country policy; omitted or null lets the country policy decide.
In-call hand-offs to other agents of the workspace (up to 10). Targets that do not exist or are not provisioned yet are skipped silently when the provider configuration is built.
Department used by inbound skill-based routing. Trimmed; blank is treated as absent.
Guardrails — topics the agent refuses to discuss. Pushed to the voice provider’s guardrails.
PII redaction and data retention. On create the defaults below are stored even when the block is omitted; on update nothing is defaulted.
Post-call analysis run by the voice provider on the transcript. successEvaluation criteria decide
whether a conversation succeeded (they drive outcomes and conversion metrics); dataCollection
fields are extracted from the transcript. Criterion ids starting with qa_ are reserved for
platform quality evaluation and a NEW one is rejected with 400 (ids already stored keep saving).
Lets the voice model use expressive delivery (audio tags such as laughter or emphasis).
How numbers, dates and symbols are turned into speakable text: engine (the voice engine
normalises before speech) or system_prompt (the model is instructed to write them out).
The value this field used before 2026-09-15 is still accepted as a synonym of engine; responses
always return engine. Any other value returns 400 VALIDATION_FAILED with
Valor no válido. Valores permitidos: engine, system_prompt.
Voice only — seconds of silence before the agent takes the turn (1-10). Omitted = the objective’s value.
How eagerly the voice agent takes the turn: patient, normal, eager. The legacy spellings
low, medium and high are still accepted. Omitted = the objective’s value.
Speech rate, 0.7-1.2 (1 = the voice’s natural speed). Stored and sent to the voice, but the current voice model (Eleven v4 Turbo) does not apply it: pace is set by the voice and the conversation. Omitted = the objective’s value.
Voice stability, 0-1. Lower is more expressive, higher more consistent. Omitted = the objective’s value.
How closely synthesis adheres to the original voice, 0-1.
Response
An agent as returned by GET /api/agents, GET /api/agents/{agentId} and POST /api/agents.
Stored columns are snake_case (see AgentRowBase); the fields the API adds on top of them
(channels, objective, analysis, safety, privacy, mcpEnabled, toolkitAccessEnforced,
total_calls, conversion_rate, calls_today, avg_sentiment) are listed below, and the raw
JSON columns they come from (supported_channels, analysis_config, safety_config,
privacy_config) are not returned. analysis, safety and privacy are omitted when nothing is
stored. GET /api/agents returns a projection (see that operation). The provider’s internal voice
agent id is never returned.
A newly created agent is provisioned with the voice provider in the background for about 30-45
seconds; operations that need it answer 409 AGENT_PROVISIONING meanwhile.

