AI Agents
Stateway is designed to be consumed directly by AI agents via REST. An agent can start a process, query its state, complete human tasks, and send events — all through straightforward HTTP calls.
This page covers the complete integration pattern with ready-to-use JSON payloads suitable for LLM tool calls.
Authentication
Every request requires an API Key in the X-API-Key header. The key resolves the tenant automatically — you never pass a tenant_id.
X-API-Key: sw_live_<key>
Core Operations
1. Start a Process
Instantiate a process definition by its key. Pass any initial variables the process needs.
POST /v1/instances
Content-Type: application/json
X-API-Key: sw_live_<key>
{
"definitionKey": "loan-approval",
"variables": {
"applicantId": "usr_123",
"amount": 5000,
"currency": "BRL"
}
}
Response:
{
"id": "inst_abc123",
"status": "running",
"definitionKey": "loan-approval",
"definitionVersion": 3,
"variables": {
"applicantId": "usr_123",
"amount": 5000,
"currency": "BRL"
},
"createdAt": "2026-04-01T10:00:00Z"
}
Save the id — you'll use it for all subsequent calls on this instance.
2. Query Instance State
Check whether the process is still running, which element it's waiting on, and what the current variable values are.
GET /v1/instances/{instanceId}
X-API-Key: sw_live_<key>
Response:
{
"id": "inst_abc123",
"status": "running",
"currentElement": "approve-loan-task",
"variables": {
"applicantId": "usr_123",
"amount": 5000,
"decision": null
},
"updatedAt": "2026-04-01T10:01:00Z"
}
status is one of: running, completed, failed, suspended.
3. List Pending Tasks
Retrieve human tasks that are waiting for action within an instance — or across all instances.
GET /v1/tasks?instanceId=inst_abc123&status=pending
X-API-Key: sw_live_<key>
Response:
{
"items": [
{
"id": "task_xyz789",
"name": "Approve Loan",
"instanceId": "inst_abc123",
"status": "pending",
"assignee": null,
"candidateGroups": ["credit-team"],
"variables": {
"amount": 5000
}
}
],
"total": 1
}
4. Complete a Task
Submit the outcome of a human task. The variables object sets or updates process variables.
POST /v1/tasks/{taskId}/complete
Content-Type: application/json
X-API-Key: sw_live_<key>
{
"variables": {
"decision": "approved",
"reviewedBy": "agent-gpt4o",
"reviewNotes": "Income verified. Risk score within acceptable range."
}
}
Response:
{
"id": "task_xyz789",
"status": "completed",
"completedAt": "2026-04-01T10:05:00Z"
}
5. Send a Message Event
Trigger a Catch Message Event in a running process. Use this to deliver external signals — payment confirmations, webhook callbacks, approval decisions from other systems.
POST /v1/instances/{instanceId}/events
Content-Type: application/json
X-API-Key: sw_live_<key>
{
"type": "message",
"name": "PaymentConfirmed",
"variables": {
"transactionId": "txn_9981",
"paidAt": "2026-04-01T10:10:00Z"
}
}
Response:
{
"instanceId": "inst_abc123",
"eventName": "PaymentConfirmed",
"accepted": true
}
6. Send a Signal
Broadcast a signal to all instances currently waiting for it.
POST /v1/instances/{instanceId}/events
Content-Type: application/json
X-API-Key: sw_live_<key>
{
"type": "signal",
"name": "GlobalShutdown"
}
Tool Definitions for LLMs
The examples below are ready to paste into your LLM's tool schema. They follow the JSON Schema format used by the OpenAI/Anthropic tool call APIs.
start_process
{
"name": "start_process",
"description": "Start a new instance of a Stateway process definition. Returns the instance ID needed for all subsequent operations.",
"parameters": {
"type": "object",
"properties": {
"definitionKey": {
"type": "string",
"description": "The process definition key (e.g. 'loan-approval', 'onboarding')"
},
"variables": {
"type": "object",
"description": "Initial process variables as key-value pairs",
"additionalProperties": true
}
},
"required": ["definitionKey"]
}
}
get_instance
{
"name": "get_instance",
"description": "Query the current state of a process instance, including status, active element, and variable values.",
"parameters": {
"type": "object",
"properties": {
"instanceId": {
"type": "string",
"description": "The instance ID returned by start_process"
}
},
"required": ["instanceId"]
}
}
list_tasks
{
"name": "list_tasks",
"description": "List pending human tasks for a given process instance.",
"parameters": {
"type": "object",
"properties": {
"instanceId": {
"type": "string",
"description": "Filter tasks by instance ID"
},
"status": {
"type": "string",
"enum": ["pending", "completed", "claimed"],
"description": "Task status filter (default: pending)"
}
},
"required": []
}
}
complete_task
{
"name": "complete_task",
"description": "Complete a pending human task and supply output variables that will be set in the process.",
"parameters": {
"type": "object",
"properties": {
"taskId": {
"type": "string",
"description": "The task ID from list_tasks"
},
"variables": {
"type": "object",
"description": "Output variables to set in the process after task completion",
"additionalProperties": true
}
},
"required": ["taskId"]
}
}
send_event
{
"name": "send_event",
"description": "Send a message or signal event to a running process instance. Use for delivering external results (e.g. payment confirmed, document approved).",
"parameters": {
"type": "object",
"properties": {
"instanceId": {
"type": "string",
"description": "Target instance ID"
},
"type": {
"type": "string",
"enum": ["message", "signal"],
"description": "Event type"
},
"name": {
"type": "string",
"description": "Message or signal name as defined in the BPMN"
},
"variables": {
"type": "object",
"description": "Variables to attach to the event",
"additionalProperties": true
}
},
"required": ["instanceId", "type", "name"]
}
}
Complete Agent Loop Example
A typical agent loop for a process that requires an external decision:
import httpx
BASE_URL = "https://api.stateway.io/v1"
HEADERS = {"X-API-Key": "sw_live_<key>", "Content-Type": "application/json"}
# 1. Start the process
resp = httpx.post(f"{BASE_URL}/instances", headers=HEADERS, json={
"definitionKey": "credit-analysis",
"variables": {"customerId": "cust_001", "requestedLimit": 10000}
})
instance_id = resp.json()["id"]
# 2. Poll until a task appears
import time
while True:
tasks = httpx.get(f"{BASE_URL}/tasks", headers=HEADERS,
params={"instanceId": instance_id, "status": "pending"}).json()
if tasks["items"]:
break
time.sleep(2)
task = tasks["items"][0]
# 3. Agent makes a decision and completes the task
decision = run_agent_analysis(task["variables"]) # your LLM call
httpx.post(f"{BASE_URL}/tasks/{task['id']}/complete", headers=HEADERS, json={
"variables": {"decision": decision["result"], "score": decision["score"]}
})
# 4. Wait for the process to finish
while True:
instance = httpx.get(f"{BASE_URL}/instances/{instance_id}", headers=HEADERS).json()
if instance["status"] in ("completed", "failed"):
break
time.sleep(2)
print(instance["variables"])
Tips for Agent Implementations
- Poll with backoff. Processes can wait for minutes or hours at a human task or timer. Use exponential backoff instead of tight loops.
- Prefer webhooks for production. Subscribe to
instance.completedandtask.createdevents via the Webhooks guide instead of polling. - Idempotency. Completing a task twice returns an error. Check
statusbefore callingcomplete_task. - Variables are merged. Sending
variablesin a task completion merges them into the existing instance variables — you don't need to send every variable, only the ones you're setting. - Use MCP for richer integrations. If your agent framework supports MCP, the MCP guide describes the Stateway MCP server which exposes all operations as native tools with JSON Schema types.