Skip to content

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}/chains

Query Parameters:

  • limit (optional): Number of results per page (default: 20)
  • cursor (optional): Offset-based pagination cursor (default: 0)
  • orderBy (optional): created_at (default) or updated_at
  • inputType (optional): Filter by json or file

Create Action Chain

POST /orgs/{organizationId}/chains

Request 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) or file (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": []
}
When 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}/run

Enqueues 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 one
  • onlyStep: run only the step at this order

Query Parameters:

  • resetToRunning (optional): true to reset the run’s status to running before executing

Response:

{
  "messageId": "b1c2d3e4-..."
}

List Chain Runs

GET /orgs/{organizationId}/chains/{actionChainId}/runs

Get 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) or updated_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}/steps

Returns all steps in the chain in execution order.

Create Step

POST /orgs/{organizationId}/chains/{actionChainId}/steps

Request 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-prompt

Generates 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: when true, the generated step also includes an inputSchema for the whole chain input
  • agentResponse, 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-sessions

Response:

{
  "browserSessions": [ { "...": "..." } ]
}