using-procedure-api
Procedures are reusable instruction blocks that an agent runs when a trigger matches. Create, edit, compile, and publish them with the Python or JavaScript SDK, or over the public REST API with `curl`. Reference:
How it fires
How this agent gets triggered: by you, by Claude, or both.
- Fires itselfAuto-invocation. Claude auto-loads it when your prompt matches the work.Auto-invocation is when the right skill fires by itself at the right moment, driven by a FLOW.md router and a hook, instead of you invoking it by name. It is the difference between a skill being installed and a skill actually getting used.Read the full definition →
- You can call itInvoke it directly when you want it.
Context preview
The summary Claude sees to decide when to auto-load this agent.
Procedures are reusable instruction blocks that an agent runs when a trigger matches. Create, edit, compile, and publish them with the Python or JavaScript SDK, or over the public REST API with `curl`. Reference:
Agent definition
using-procedure-api.mdUsing the Procedure API
Procedures are reusable instruction blocks that an agent runs when a trigger matches. Create, edit, compile, and publish them with the Python or JavaScript SDK, or over the public REST API with `curl`. Reference: [Procedures](https://elevenlabs.io/docs/eleven-agents/customization/procedures.md) · [API Reference](https://elevenlabs.io/docs/api-reference/agents/procedures/).
For what belongs in `trigger` and `content`, see [Writing Procedures](writing-procedures.md).
Procedures are in Alpha. The feature set and the content schema are still changing, and some changes may break. Check the reference pages above before relying on a detail here.
Prerequisites
- `ELEVENLABS_API_KEY` is set, with the `CONVAI_READ` and `CONVAI_WRITE` scopes.
- Reading requires the viewer role on the target agent. Creating, updating, removing, compiling, and publishing require the editor role. Publishing to a protected branch requires admin.
- The target `agent_id` is known.
- The target `branch_id` is known. If not, read `main_branch_id` from `GET /v1/convai/agents/{agent_id}`, or list branches with `GET /v1/convai/agents/{agent_id}/branches`.
API_BASE="https://api.elevenlabs.io/v1/convai"
AUTH_HEADER="xi-api-key: $ELEVENLABS_API_KEY"
Never print or persist the API key.
SDKs
Procedure APIs are available in both SDKs starting in `2.60.0`. Earlier versions do not include a `procedures` client, so install at or above that version:
pip install "elevenlabs>=2.60.0"
npm install @elevenlabs/elevenlabs-js@^2.60.0
For JavaScript, use `@elevenlabs/elevenlabs-js`. The unscoped `elevenlabs` npm package is the deprecated v1.x and has no procedures client at any version.
Both clients read `ELEVENLABS_API_KEY` from the environment; never pass a literal key.
Use these SDK methods for the procedure endpoints. Python nests them under `client.conversational_ai.agents`; JavaScript uses `client.conversationalAi.agents`:
| Operation | Endpoint | Method | |-----------|----------|--------| | List | `GET .../procedures` | `procedures.list` | | Create | `POST .../procedures` | `procedures.create` | | Read branch HEAD | `GET .../procedures/{procedure_id}` | `procedures.get` | | Read draft | `GET .../procedures/{procedure_id}/draft` | `procedures.drafts.get` | | Update draft | `PATCH .../procedures/{procedure_id}/draft` | `procedures.drafts.update` | | Discard draft | `DELETE .../procedures/{procedure_id}/draft` | `procedures.drafts.delete` | | Remove | `DELETE .../procedures/{procedure_id}` | `procedures.remove` | | Compile | `POST .../procedures/compile` | `procedures.compile` | | Publish | `PATCH /v1/convai/agents/{agent_id}?branch_id=...` | `agents.update` |
SDK notes:
- JavaScript takes the IDs positionally, then a body object. Python takes keyword arguments — except `procedures.create`, which takes its body as `request=CreateProcedureRequestModel(...)`. Flat keywords on `create` raise `TypeError`.
- Read one historical version with `procedures.get(..., version_id=...)` or `procedures.get(agentId, branchId, procedureId, { versionId })`.
- For structured changes, pass the `workflow` returned by `procedures.compile` to `agents.update`.
The flow below creates a free-form procedure, edits its draft, and publishes it.
Python
from elevenlabs import ElevenLabs
from elevenlabs.types import CreateProcedureRequestModel
client = ElevenLabs()
procedures = client.conversational_ai.agents.procedures
created = procedures.create(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
request=CreateProcedureRequestModel(
name="Refund requests",
type="free_form",
trigger="When the user asks for a refund",
content="Confirm the order number, check eligibility, and explain the next step.",
),
)
draft = procedures.drafts.get(
agent_id=AGENT_ID, branch_id=BRANCH_ID, procedure_id=created.procedure_id
)
procedures.drafts.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
procedure_id=created.procedure_id,
name=draft.name,
type="free_form",
trigger=draft.trigger,
content="Confirm the order number. Check refund eligibility. Explain the refund timeline.",
)
client.conversational_ai.agents.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
version_description="Publish refund procedure",
)If the pending changes include structured procedures, compile before publishing:
from elevenlabs.errors import BadRequestError
try:
compiled = procedures.compile(agent_id=AGENT_ID, branch_id=BRANCH_ID)
except BadRequestError as error:
print(f"Compile failed, nothing published: {error.body}")
raise
client.conversational_ai.agents.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
workflow=compiled.workflow,
version_description="Publish refund procedure",
)JavaScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient();
const procedures = client.conversationalAi.agents.procedures;
const created = await procedures.create(agentId, branchId, {
name: "Refund requests",
type: "free_form",
trigger: "When the user asks for a refund",
content: "Confirm the order number, check eligibility, and explain the next step.",
});
const draft = await procedures.drafts.get(agentId, branchId, created.procedureId);
await procedures.drafts.update(agentId, branchId, created.procedureId, {
name: draft.name,
type: "free_form",
trigger: draft.trigger,
content: "Confirm the order number. Check refund eligibility. Explain the refund timeline.",
});
await client.conversationalAi.agents.update(agentId, {
branchId,
versionDescription: "Publish refund procedure",
});If the pending changes include structured procedures, compile before publishing:
import { ElevenLabsError } from "@elevenlabs/elevenlabs-js";
try {
const compiled = await procedures.compile(agentId, branchId);
await client.converRead more
Using the Procedure API
Procedures are reusable instruction blocks that an agent runs when a trigger matches. Create, edit, compile, and publish them with the Python or JavaScript SDK, or over the public REST API with `curl`. Reference: [Procedures](https://elevenlabs.io/docs/eleven-agents/customization/procedures.md) · [API Reference](https://elevenlabs.io/docs/api-reference/agents/procedures/).
For what belongs in `trigger` and `content`, see [Writing Procedures](writing-procedures.md).
Procedures are in Alpha. The feature set and the content schema are still changing, and some changes may break. Check the reference pages above before relying on a detail here.
Prerequisites
- `ELEVENLABS_API_KEY` is set, with the `CONVAI_READ` and `CONVAI_WRITE` scopes.
- Reading requires the viewer role on the target agent. Creating, updating, removing, compiling, and publishing require the editor role. Publishing to a protected branch requires admin.
- The target `agent_id` is known.
- The target `branch_id` is known. If not, read `main_branch_id` from `GET /v1/convai/agents/{agent_id}`, or list branches with `GET /v1/convai/agents/{agent_id}/branches`.
API_BASE="https://api.elevenlabs.io/v1/convai" AUTH_HEADER="xi-api-key: $ELEVENLABS_API_KEY"
Never print or persist the API key.
SDKs
Procedure APIs are available in both SDKs starting in `2.60.0`. Earlier versions do not include a `procedures` client, so install at or above that version:
pip install "elevenlabs>=2.60.0" npm install @elevenlabs/elevenlabs-js@^2.60.0
For JavaScript, use `@elevenlabs/elevenlabs-js`. The unscoped `elevenlabs` npm package is the deprecated v1.x and has no procedures client at any version.
Both clients read `ELEVENLABS_API_KEY` from the environment; never pass a literal key.
Use these SDK methods for the procedure endpoints. Python nests them under `client.conversational_ai.agents`; JavaScript uses `client.conversationalAi.agents`:
| Operation | Endpoint | Method | |-----------|----------|--------| | List | `GET .../procedures` | `procedures.list` | | Create | `POST .../procedures` | `procedures.create` | | Read branch HEAD | `GET .../procedures/{procedure_id}` | `procedures.get` | | Read draft | `GET .../procedures/{procedure_id}/draft` | `procedures.drafts.get` | | Update draft | `PATCH .../procedures/{procedure_id}/draft` | `procedures.drafts.update` | | Discard draft | `DELETE .../procedures/{procedure_id}/draft` | `procedures.drafts.delete` | | Remove | `DELETE .../procedures/{procedure_id}` | `procedures.remove` | | Compile | `POST .../procedures/compile` | `procedures.compile` | | Publish | `PATCH /v1/convai/agents/{agent_id}?branch_id=...` | `agents.update` |
SDK notes:
- JavaScript takes the IDs positionally, then a body object. Python takes keyword arguments — except `procedures.create`, which takes its body as `request=CreateProcedureRequestModel(...)`. Flat keywords on `create` raise `TypeError`.
- Read one historical version with `procedures.get(..., version_id=...)` or `procedures.get(agentId, branchId, procedureId, { versionId })`.
- For structured changes, pass the `workflow` returned by `procedures.compile` to `agents.update`.
The flow below creates a free-form procedure, edits its draft, and publishes it.
Python
from elevenlabs import ElevenLabs
from elevenlabs.types import CreateProcedureRequestModel
client = ElevenLabs()
procedures = client.conversational_ai.agents.procedures
created = procedures.create(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
request=CreateProcedureRequestModel(
name="Refund requests",
type="free_form",
trigger="When the user asks for a refund",
content="Confirm the order number, check eligibility, and explain the next step.",
),
)
draft = procedures.drafts.get(
agent_id=AGENT_ID, branch_id=BRANCH_ID, procedure_id=created.procedure_id
)
procedures.drafts.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
procedure_id=created.procedure_id,
name=draft.name,
type="free_form",
trigger=draft.trigger,
content="Confirm the order number. Check refund eligibility. Explain the refund timeline.",
)
client.conversational_ai.agents.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
version_description="Publish refund procedure",
)If the pending changes include structured procedures, compile before publishing:
from elevenlabs.errors import BadRequestError
try:
compiled = procedures.compile(agent_id=AGENT_ID, branch_id=BRANCH_ID)
except BadRequestError as error:
print(f"Compile failed, nothing published: {error.body}")
raise
client.conversational_ai.agents.update(
agent_id=AGENT_ID,
branch_id=BRANCH_ID,
workflow=compiled.workflow,
version_description="Publish refund procedure",
)JavaScript
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient();
const procedures = client.conversationalAi.agents.procedures;
const created = await procedures.create(agentId, branchId, {
name: "Refund requests",
type: "free_form",
trigger: "When the user asks for a refund",
content: "Confirm the order number, check eligibility, and explain the next step.",
});
const draft = await procedures.drafts.get(agentId, branchId, created.procedureId);
await procedures.drafts.update(agentId, branchId, created.procedureId, {
name: draft.name,
type: "free_form",
trigger: draft.trigger,
content: "Confirm the order number. Check refund eligibility. Explain the refund timeline.",
});
await client.conversationalAi.agents.update(agentId, {
branchId,
versionDescription: "Publish refund procedure",
});If the pending changes include structured procedures, compile before publishing:
import { ElevenLabsError } from "@elevenlabs/elevenlabs-js";
try {
const compiled = await procedures.compile(agentId, branchId);
await client.converAgent skills for ElevenLabs developer products. These skills follow the Agent Skills specification and can be used with any compatible AI coding assistant.
Repo: elevenlabs/skills
Other agents on elevenlabs-skills.
- agent-configuration
Complete reference for configuring conversational AI agents.
Open agent - client-tools
Extend your agent with custom capabilities. Tools let the agent take actions beyond just talking.
Open agent - installation
The ElevenLabs CLI is the recommended way to create and manage agents:
Open agent - outbound-calls
Make outbound phone calls using your ElevenLabs agent via Twilio or Exotel integration.
Open agent - widget-embedding
Add an ElevenLabs agent to any website with the conversation widget.
Open agent - writing-procedures
Check the current documentation before authoring procedure content. Procedures are in Alpha, and the content schema may change:
Open agent

