Agents
An agent is the AI persona that places and answers calls, replies on WhatsApp and email, and chats on your website. It carries everything that decides how a conversation goes: its objective (category), voice and language, the prompt you write, the first thing it says, the channels it may answer on, the post-call analysis it runs, and the tools and conversation graph it can use. Campaigns, phone numbers, widgets and inboxes all point at an agent.
Every agent belongs to one workspace. The API reads and writes the same agents you see under Agents in the dashboard.
How it works
Creating an agent is a two-phase operation. Jelliu validates and screens your request, stores the agent and answers right away; the voice runtime for the agent is then provisioned in the background, which typically takes 30 to 45 seconds. Until that finishes, endpoints that need the runtime answer 409 AGENT_PROVISIONING.
What happens on POST /api/agents, in order:
- The body is validated. The system prompt, first message and objection handlers are screened for fraud; a blocked prompt fails with
403 COMPLIANCE_BLOCKEDbefore anything is stored. - Plan gates run: the agent cap for your plan, cloned voices (Enterprise only), and the dial policy for
transferPhoneNumber. - The agent is inserted, under a lock that enforces the plan’s agent cap atomically. Version 1 of its history is recorded.
- The response returns
201with the stored agent. Provisioning of the voice runtime is queued with up to 3 attempts and exponential backoff.
The agent object does not expose a provisioning flag. To know whether an agent is ready, call an endpoint that needs the runtime, such as GET /api/agents/{agentId}/signed-url: it answers 409 AGENT_PROVISIONING with Retry-After: 5 until provisioning completes. Adding tools and saving a workflow behave the same way.
How the prompt is assembled
The agent’s effective instructions are layered. Jelliu supplies a universal base for the agent’s category, an optional per-objective playbook comes from the linked template (templateId), and your systemPrompt is the part you own. When you change the category, template or prompt, the agent is re-synced to its runtime.
categoryis the agent’s objective. It selects the base identity and the default post-call analysis. If you omit it on create, the linked template’s category applies.- Runtime tuning (
turnTimeout,turnEagerness,ttsSpeed,ttsStability,maxCallDurationSeconds) is seeded from the category when you do not send a value, so each objective starts with pacing suited to it. - Analysis. If you do not send
analysis, a default set of success criteria and data-collection fields is generated for the category. Changing the category later regenerates that default analysis, unless the same request also sendsanalysis.
Categories
Channels
channels lists where the agent may answer: voice, whatsapp, email, webchat, instagram and messenger. An agent created without channels serves all of them.
channels is a full replacement, not a delta. Sending ["voice", "whatsapp"] to an agent that serves every channel takes it off email, webchat, instagram and messenger. Always send the complete set you want.
Object
GET /api/agents and GET /api/agents/{agentId} return agents with the fields below. Timestamps are ISO 8601 strings. Keys are snake_case, except for the three computed flags noted in the table.
GET /api/agents/{agentId} returns every stored column, so it also includes, among others:
Treat every field as optional and ignore fields you do not recognize. The detail response can carry internal columns that are not part of the contract.
Common tasks
Create an agent
Pick a voice
List the voice catalog and copy the id of a voice with accessible: true.
The response is { "data": { "voices": [ ... ] } }. Each voice has id, name, previewUrl, category, gender, accent, age, language, useCase, description, accessible and inaccessibleReason. Voices with category: "cloned" require the Enterprise plan.
Create the agent
Only name, voiceId and language are required.
The request takes a second or two because the prompt is screened synchronously. A successful request returns 201 Created:
The default analysis above is abbreviated; its criteria depend on the category. Tuning fields such as turn_timeout, turn_eagerness, tts_speed and tts_stability are also present, with the values seeded from the category.
Wait for provisioning
Poll a runtime endpoint until it stops answering 409 AGENT_PROVISIONING, honoring Retry-After.
When ready, the endpoint returns { "data": { "signed_url": "wss://...", "conversation_token": "..." } }. These are short-lived credentials for a browser test session; conversation_token is omitted when it cannot be minted.
Create fields
1 to 100 characters.
A voice id from GET /api/voices. Cloned voices require the Enterprise plan.
es, es-CO, es-MX, es-AR, es-neutral, en, en-US, pt or pt-BR. A few human labels are also accepted and normalized, for example Spanish (LATAM) becomes es-neutral.
The agent’s objective. See Categories. Omit it to inherit the template’s category.
A template from GET /api/agent-templates: a system template or one your workspace owns. Any other ID fails with 400 VALIDATION_FAILED.
At least one of voice, whatsapp, email, webchat, instagram, messenger. Defaults to all of them.
Up to 8,000 characters. Must be empty (the agent introduces itself generically and never invents a product) or at least 10 characters. Put catalogs, price lists and long scripts in the knowledge base instead.
Up to 500 characters. When omitted or blank, Jelliu generates a greeting in the agent’s language with the agent name and your company name, for example Hola, le habla Valentina de Clínica Dental Sonrisa. ¿Cómo está?.
Up to 50 entries. Keys up to 100 characters, values up to 500.
Up to 50 entries. Keys up to 100 characters, values up to 2,000. Each value is fraud-screened.
Items of trigger (negative_sentiment, explicit_request, repeated_objection, timeout), threshold (number, 0 or more) and action (transfer_to_human, end_call_politely, schedule_callback).
Up to 10 items of targetAgentId (uuid of another agent in your workspace), condition (1 to 500 characters) and optional transferMessage (up to 500). Targets that are not provisioned yet are skipped.
E.164 (+ and 2 to 15 digits). Checked against your workspace’s dial policy when saved; a destination the policy refuses fails with 403 COMPLIANCE_BLOCKED.
30 to 3600. Defaults to the category’s value.
true or false overrides the country policy for this agent. Omit or send null to inherit it.
Detect voicemail on outbound calls.
Up to 100 characters.
Up to 50 items of 1 to 100 characters.
successEvaluation: up to 30 criteria of id (1 to 100 characters) and description (5 to 1,000). dataCollection: up to 40 fields of id, dataType (string, boolean, integer, number), description (5 to 1,000) and optional enum (up to 50 unique strings, only for string fields). Criterion IDs starting with qa_ are reserved. Omit to get the category default.
blockedInputTopics and blockedOutputTopics: up to 20 topics each, up to 200 characters.
redactPiiAudio (default true), deleteAudioAfterProcessing (default true), retentionDays (0 to 365, default 90).
Voice only. 1 to 10 seconds. Defaults to the category’s value.
patient, normal, eager (or legacy low, medium, high). Defaults to the category’s value.
0.5 to 2.0. Defaults to the category’s value.
0 to 1. Defaults to the category’s value.
0 to 1.
Expressive voice delivery.
Play a sound while a tool runs.
system_prompt or elevenlabs.
Asynchronous creation
Add ?async=true to POST /api/agents to run the whole creation, including fraud screening, in the background. The response is 202 Accepted:
Poll GET /api/agents/jobs/{jobId}. data.status moves through pending, processing, then completed (with the agent in data.result) or failed (with the reason in data.error). Job records expire after one hour. The body is still validated synchronously, so an invalid request fails with 400 before a job is created.
List and search agents
GET /api/agents returns up to limit agents (1 to 200, default 50), newest first. Pass the created_at of the last agent as cursor for the next page, and search for a case-insensitive match on the name. See Pagination.
The list response above is abbreviated; each item carries the fields in Object except the detail-only ones. Get one agent with GET /api/agents/{agentId}.
Agent lists and details are cached for up to 120 seconds. Creating, updating and deleting agents through the API clears the cache, but pausing does not. For the current pause state, read GET /api/agents/{agentId}/pause.
Update an agent
PATCH /api/agents/{agentId} accepts any subset of the create fields, and at least one field must be present. It also accepts fields that exist only on update:
Nullable fields on update: templateId, category, transferPhoneNumber, discloseAi and department accept null to clear them.
The response is 200 with the updated agent in data.
How update merges values:
analysis,safety,privacyare merged half by half. An absent key keeps what is stored,nullclears that half, and a value replaces it.nullfor the whole block clears it. In the example above, the storedsuccessEvaluationis kept.toolkitAccessis merged per app.channels,skills,escalationRules,transferRules,dynamicVariablesandobjectionHandlersare replaced whole.systemPrompton update must be 10 to 8,000 characters; an empty string is treated as not sent.
Unknown fields are silently dropped. A misspelled key such as system_prompt in a PATCH body returns 200 and changes nothing. Use the camelCase names documented here.
Estimate a prompt’s cost
POST /api/agents/prompt-cost measures a draft against the base instructions for its category before you save it. The body is systemPrompt (up to 200,000 characters, so an over-limit draft can still be measured) and optional category.
Tokens are estimated at 4 characters per token over the full assembled prompt, and overGuideline flags prompts above 2,000 tokens, where latency and cost start to rise. usdPerMinute is null when the price cannot be fetched.
Pause and resume an agent
Pausing is the emergency stop. A paused agent accepts no new calls or conversation turns; attempts fail with 409 AGENT_PAUSED (or 503 AGENT_PAUSED when the pause state cannot be read, so the stop fails closed). Conversations already in progress continue to their natural end unless you also set terminateActive.
terminateActive hangs up the telephony leg of each live call. Calls with no carrier leg of Jelliu’s own (a SIP trunk, or a number registered directly with the voice provider) cannot be cut: they are counted in stillLiveWithoutCarrierLeg and keep running. If truncated is true, there were more live calls than one sweep handles; repeat the request.
GET /api/agents/{agentId}/pause returns paused, pausedAt, pausedBy, reason and note without changing anything.
Delete an agent
DELETE /api/agents/{agentId} returns 204 No Content. Deleting:
- pauses every active campaign that uses the agent, so they stop dialing on their next cycle;
- unassigns the agent from its phone numbers, so inbound calls to those numbers need a new agent;
- removes the agent from the voice runtime first, and aborts the delete if that fails, so no orphan is left behind;
- is a soft delete on Jelliu’s side: the version history is kept.
Campaigns paused by the delete must be reassigned to another agent before they can resume.
Version history
Every change to an agent’s behavior is recorded as a numbered version: creation, updates, workflow edits, restores and deletion.
A version has id, agent_id, version, change_source (create, update, approved_update, workflow_put, workflow_delete, base_resync, tool_surface, restore, delete), changed_by, actor_type, summary, diff, snapshot_sha256, snapshot_pruned_at, restored_from_version and created_at.
The version record is kept forever, but its snapshot is removed once the version is older than 400 days and is not among the agent’s 50 most recent versions. Restoring such a version fails with 410 and code VALIDATION_FAILED. Restoring to a state identical to the current one is a no-op.
Change approval
A workspace can require a second person to approve behavior changes to agents marked highRisk. It takes both switches: the workspace setting (off by default) and the agent’s highRisk flag.
When both are on, a PATCH that touches a behavior field, a restore, or a workflow change is not applied. The API answers 409 AGENT_CHANGE_PENDING_APPROVAL and returns the request ID:
Behavior fields are systemPrompt, firstMessage, category, templateId, objectionHandlers, escalationRules, transferRules, transferPhoneNumber, enableVoicemailDetection, safety, privacy, analysis, allowedToolkits, disabledTools, toolkitAccess, mcpEnabled, channels, maxCallDurationSeconds and highRisk itself. Renames, voice, language, pacing and TTS tuning pass straight through.
status is one of pending, approved, rejected, applied, failed, cancelled. approve and reject accept an optional note (up to 2,000 characters). An approved change is re-validated against the current schema and applied; if applying fails, the request ends as failed and must be proposed again.
The proposer cannot approve or reject their own request (403 FORBIDDEN). An API key’s identity is the key itself, so a change proposed with one key must be reviewed by a person in the dashboard or with a different key.
Tools, workflows and connected apps
These are managed under the agent and are covered in the API reference:
- Tools (
/api/agents/{agentId}/tools): webhook tools the agent can call during a conversation, with method, URL, parameters and authentication. - Workflow (
GET,PUT,DELETE/api/agents/{agentId}/workflow): an optional conversation graph of up to 12 nodes and 24 edges. Nodes aresubagentsteps orend; edges areunconditional,llm(a natural-language condition) orexpression(a comparison over up to 6 state variables the agent scores as it goes). Without a workflow the agent runs from its prompt alone. - Knowledge (
/api/agents/{agentId}/knowledge): documents the agent retrieves from. See Knowledge base. - MCP servers (
/api/agents/{agentId}/mcp-servers): external tool servers attached to the agent, allowed only whilemcpEnabledistrue. - Controls (
/api/agents/{agentId}/controls/limits): tool-call budgetsperMinute,perHour,perDayandperConversation. When exhausted, actions fail with429 AGENT_BUDGET_EXCEEDED.maxSpendPerDayCentsis stored but not enforced yet, and the response says so withspendEnforced: false.
Tool and workflow changes need a provisioned agent and answer 409 AGENT_PROVISIONING until then.
Errors
See Errors for the envelope and retry guidance.
Limits
Rate limits. Agent routes are under the general API limit. Mutations (POST /api/agents, PATCH, DELETE, prompt-cost, restoring a version, approving a change request, and tool and workflow writes) also share the 10-per-minute configuration budget with campaigns and webhooks. See Rate limits.
Plan limits. Agents per workspace, including agent add-ons you buy on top:
A workspace without an active plan cannot create agents. Cloned voices are available on Enterprise only.
Scopes.
See Authentication for how scopes map to roles.
Webhooks
See Webhooks for payloads and signature verification.
Related
Place outbound calls with an agent and follow their lifecycle.
Run an agent over a list of contacts on a schedule.
Give an agent documents to answer from.
Assign numbers so an agent answers inbound calls.
Read what the agent said across every channel.
Every agent endpoint, parameter and response.

