Action Chains
Action Chains API
Action chains are automated workflows that execute a series of steps sequentially. They’re useful for complex, multi-step processes that need to be repeatable.
Chain Management
List Action Chains
GET /orgs/{organizationId}/chainsQuery Parameters:
limit(optional): Number of results per page (default: 20)cursor(optional): Offset-based pagination cursor (default: 0)orderBy(optional):created_at(default) orupdated_atinputType(optional): Filter byjsonorfile
Create Action Chain
POST /orgs/{organizationId}/chainsRequest Body (name, description, llmInstructions are required):
{
"name": "Customer Onboarding",
"description": "Automated customer onboarding workflow",
"llmInstructions": "Guidance the chain runner passes to the model for every step",
"inputType": "json",
"steps": []
}inputType:json(default input) orfile(chain is driven by an uploaded file)steps(optional): array of step objects to create with the chain (see Chain Steps)
Response: Returns the created chain, including its generated actionChainId.
Get Chain
GET /orgs/{organizationId}/chains/{actionChainId}Returns the chain configuration. Returns 404 if the chain does not exist.
Update Chain
PUT /orgs/{organizationId}/chains/{actionChainId}Request Body (name, description, llmInstructions, inputType are required):
{
"name": "Updated Onboarding Flow",
"description": "Updated description",
"llmInstructions": "Updated guidance for the chain runner",
"inputType": "json",
"steps": []
}steps is supplied, it fully replaces the chain’s existing steps. When inputType is file, the first step’s inputSchema must define fileId, knowledgeBaseId, and fileName properties.Delete Chain
DELETE /orgs/{organizationId}/chains/{actionChainId}Permanently deletes the chain and all its steps.
Executing Chains
Run Chain
POST /orgs/{organizationId}/chains/{actionChainId}/runEnqueues a chain run. The run executes asynchronously on the chain runner; this endpoint returns immediately with the queued message id.
Request Body (all fields optional):
{
"payload": {
"customerEmail": "customer@example.com",
"customerName": "John Doe"
},
"runId": "existing-run-id",
"onlyStep": 2
}payload: input object passed to the chain (defaults to{})runId: re-run an existing run instead of creating a new oneonlyStep: run only the step at this order
Query Parameters:
resetToRunning(optional):trueto reset the run’s status torunningbefore executing
Response:
{
"messageId": "b1c2d3e4-..."
}List Chain Runs
GET /orgs/{organizationId}/chains/{actionChainId}/runsGet execution history for a chain. Returns a paginated list of runs.
Query Parameters:
limit(optional): Number of results (default: 20)cursor(optional): Offset-based pagination cursor (default: 0)orderBy(optional):created_at(default) orupdated_at
Response: each run has runId, actionChainId, triggerType, status (pending, running, success, failed), statusMessage, and state.
Chain Steps
Each step is an LLM-driven action. A step is described by natural-language instructions and typed inputSchema / outputSchema, and can have agents, knowledge bases, and tools attached to it (see Step Attachments).
List Steps
GET /orgs/{organizationId}/chains/{actionChainId}/stepsReturns all steps in the chain in execution order.
Create Step
POST /orgs/{organizationId}/chains/{actionChainId}/stepsRequest Body (stepOrder is required):
{
"stepOrder": 1,
"name": "Send Welcome Email",
"description": "Drafts and sends a welcome email",
"instructions": "Send a welcome email to {{input.customerEmail}}",
"reasoning": "none",
"enabled": true,
"inputSchema": { "type": "object", "properties": {} },
"outputSchema": { "type": "object", "properties": {} }
}Optional fields include showWholeChainState, forEachElement (JSON Path to fan the step out over an array), toolChoice (auto / required / none or a specific tool), and the Jexl guards runIf, failBeforeRunningIf, and failAfterRunningIf. reasoning is one of none, low, medium, high.
Get Step
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}Update Step
PUT /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}Request Body: same shape as Create Step (the full step object; the path stepId identifies which step).
Delete Step
DELETE /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}Step Attachments
Steps can have agents, knowledge bases, and tools attached to them.
Each attachment type supports list, get, attach, and detach. Agents and KBs are attached by id; tools carry a per-step config object and additionally support update.
Agents
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/agents
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/agents/{agentId}
POST /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/agents
DELETE /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/agents/{agentId}Attach request body (agentId required):
{
"agentId": "agent-123"
}Knowledge Bases
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/knowledge-bases
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/knowledge-bases/{knowledgeBaseId}
POST /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/knowledge-bases
DELETE /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/knowledge-bases/{knowledgeBaseId}Attach request body (knowledgeBaseId required):
{
"knowledgeBaseId": "kb-123"
}Tools
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/tools
GET /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/tools/{toolCode}
POST /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/tools
PUT /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/tools/{toolCode}
DELETE /orgs/{organizationId}/chains/{actionChainId}/steps/{stepId}/tools/{toolCode}Attach request body (toolCode and config both required):
{
"toolCode": "calculator",
"config": {
"precision": 2
}
}Update (PUT) takes just the config object; the toolCode is taken from the path.
Generate Step from Prompt
POST /orgs/{organizationId}/chains/from-promptGenerates a single suggested chain step from a natural-language description. This is a credit-consuming, LLM-backed call, so it may return 402 when the org is out of credits.
Request Body (prompt required):
{
"prompt": "Classify an incoming customer inquiry as technical or sales",
"isFirstStep": true,
"agentResponse": "optional prior agent output for context",
"workflowInput": { "properties": {} },
"existingWorkflow": { }
}isFirstStep: whentrue, the generated step also includes aninputSchemafor the whole chain inputagentResponse,workflowInput,existingWorkflow: optional context to ground the generation
Response:
{
"step": {
"name": "Classify Inquiry",
"description": "...",
"instructions": "...",
"reasoning": "none",
"outputSchema": { "type": "object", "properties": {} }
}
}Variables and Data Flow
Step instructions are rendered with Handlebars before the step runs, so a step can reference the chain input and the accumulated state of earlier steps with {{...}} placeholders:
{
"name": "Send Welcome Email",
"instructions": "Send a welcome email to {{input.customerEmail}} for {{input.customerName}}"
}A step’s typed outputSchema defines the fields it contributes to the chain state that later steps can reference. Steps may also be gated or fanned out with the runIf / failBeforeRunningIf / failAfterRunningIf (Jexl) and forEachElement (JSON Path) fields.
Example Chain
{
"name": "Support Ticket Router",
"description": "Classifies an inquiry then routes it",
"llmInstructions": "Route support inquiries to the correct team",
"inputType": "json",
"steps": [
{
"stepOrder": 1,
"name": "Analyze Issue",
"description": "Classify the inquiry",
"instructions": "Classify this issue as 'technical' or 'sales': {{input.issueDescription}}",
"reasoning": "low",
"enabled": true,
"inputSchema": { "type": "object", "properties": { "issueDescription": { "type": "string" } } },
"outputSchema": { "type": "object", "properties": { "issueType": { "type": "string" } } }
},
{
"stepOrder": 2,
"name": "Notify Technical Team",
"description": "Only runs for technical issues",
"instructions": "Post a message to the technical team about {{input.issueDescription}}",
"reasoning": "none",
"enabled": true,
"runIf": "issueType == 'technical'",
"inputSchema": { "type": "object", "properties": {} },
"outputSchema": { "type": "object", "properties": {} }
}
]
}Monitoring and Debugging
Review Run History
Poll List Chain Runs to see each run’s status (pending, running, success, failed), statusMessage, and accumulated state.
Browser Sessions for a Run
When a chain run uses browser automation, the sessions it opened can be listed:
GET /orgs/{organizationId}/chains/{actionChainId}/runs/{runId}/browser-sessionsResponse:
{
"browserSessions": [ { "...": "..." } ]
}