Skip to main content

Chains

Chains are multi-step workflows that execute actions sequentially. Each step can be an HTTP call, a human approval gate, or a timed wait. Data flows between steps through variable interpolation.

Create Chain

POST /chains

Request Body

FieldTypeRequiredDescription
namestringYesChain name (max 255 chars)
stepsarrayYesStep definitions (min 2, max 20)
inputobjectNoInput variables available for interpolation in all steps
error_handlingstringNofail_chain (default) or skip_step

Step Types

Every step requires a name, a type, and optionally a condition.

http_call step

FieldTypeRequiredDescription
namestringYesStep name
urlstringYesRequest URL
methodstringNoHTTP method (default: POST)
headersobjectNoRequest headers
bodyobjectNoRequest body
max_attemptsintegerNoMax delivery attempts (default: 5)
retry_strategystringNoexponential (default) or linear
conditionstringNoExpression that must evaluate to true for the step to run

gated step

FieldTypeRequiredDescription
namestringYesStep name
gate.messagestringYesApproval request message
gate.recipientsarrayYesEmail addresses, phone numbers, or contact IDs
gate.timeoutstringNoResponse timeout (e.g., 4h, 7d). Default: 7d.
gate.on_timeoutstringNocancel (default), expire, or approve
gate.confirmation_modestringNofirst_response (default) or all_required
gate.max_snoozesintegerNoMax snooze count (default: 5)
conditionstringNoExpression that must evaluate to true for the step to run

delay step

FieldTypeRequiredDescription
namestringYesStep name
delaystringYesHow long to pause (e.g., 5m, 1h, 2d)
conditionstringNoExpression that must evaluate to true for the step to run

Note: Responses return webhook, approval, wait as aliases for http_call, gated, delay respectively.

Variable Interpolation

Steps can reference input data and results from earlier steps:

  • {{input.field}} -- Access values from the chain's input object
  • {{steps.N.response.field}} -- Access the JSON response body of step N (zero-indexed)
  • {{steps.N.status}} -- Access the outcome status of step N

Condition Operators

OperatorDescription
==Equal
!=Not equal
>Greater than
<Less than
>=Greater than or equal
<=Less than or equal
containsString contains substring
not_containsString does not contain substring
starts_withString starts with prefix
ends_withString ends with suffix

Example condition: {{steps.1.status}} == 'confirmed'

Example

curl -X POST https://api.callmelater.io/v1/chains \
-H "Authorization: Bearer sk_live_..." \
-H "Content-Type: application/json" \
-d '{
"name": "Expense Approval Workflow",
"steps": [
{
"name": "Submit expense",
"type": "http_call",
"url": "https://api.example.com/expenses",
"method": "POST",
"body": {
"amount": "{{input.amount}}",
"description": "{{input.description}}"
}
},
{
"name": "Manager approval",
"type": "gated",
"gate": {
"message": "Approve expense of ${{input.amount}} for {{input.description}}?",
"recipients": ["manager@example.com"],
"timeout": "4h",
"on_timeout": "cancel"
}
},
{
"name": "Process payment",
"type": "http_call",
"url": "https://api.example.com/payments",
"method": "POST",
"body": {
"expense_id": "{{steps.0.response.id}}"
},
"condition": "{{steps.1.status}} == '\''confirmed'\''"
}
],
"input": {
"amount": 150.00,
"description": "Team lunch"
}
}'

List Chains

GET /chains

Query Parameters

ParameterTypeDefaultDescription
statusstring--Filter by status: pending, running, completed, failed, cancelled
per_pageinteger15Results per page (max 100)
pageinteger1Page number

Response

{
"data": [
{
"id": "01chain789-...",
"name": "Expense Approval Workflow",
"status": "running",
"current_step": 1,
"created_at": "2026-01-15T10:00:00Z"
}
],
"meta": {
"current_page": 1,
"last_page": 1,
"total": 1
}
}

Get Chain

GET /chains/{id}

Returns the chain with its full step array, including each step's current status, response data (in context), started_at, and completed_at timestamps.

Response

{
"data": {
"id": "01chain789-...",
"name": "Expense Approval Workflow",
"status": "running",
"current_step": 1,
"steps": [
{
"name": "Submit expense",
"type": "http_call",
"status": "completed",
"started_at": "2026-01-15T10:00:05Z",
"completed_at": "2026-01-15T10:00:06Z"
},
{
"name": "Manager approval",
"type": "approval",
"status": "running",
"started_at": "2026-01-15T10:00:07Z",
"completed_at": null
},
{
"name": "Process payment",
"type": "http_call",
"status": "pending",
"started_at": null,
"completed_at": null
}
],
"context": {
"steps": {
"0": { "status": "completed", "response": { "id": "exp_123" } }
}
},
"error_handling": "fail_chain",
"created_at": "2026-01-15T10:00:00Z"
}
}

Cancel Chain

DELETE /chains/{id}

Only chains in pending or running status can be cancelled. Cancelling a chain also cancels any currently pending steps.

Response

{
"data": {
"id": "01chain789-...",
"status": "cancelled"
}
}

Statuses

Chain statuses: pending, running, completed, failed, cancelled

Step statuses: pending, running, completed, failed, skipped, cancelled