Skip to content
ArtificialFlow

HTTP API

Call the gateway directly when your language has no SDK, or when a system you already run should speak REST. Node.js covers this whole contract. Python and Go cover workers. Paths have no version prefix.

When to use HTTP

SituationPath
Java, .NET, Ruby, PHP, or any language without a client in this releaseThis HTTP API
A custom gateway, BFF, or ESBThis HTTP API
Node.js or TypeScript automation, workers, and inbox BFFsNode.js SDK
Go external workersGo worker client
Python workers, jobs onlyPython worker
People designing or operating processesThe console, not raw HTTP

Base URL and gateway

The gateway is the supported public entry for Compose and Helm.

EnvironmentCommand writesQuery reads
Local Composehttp://localhost:9100/apihttp://localhost:9100/api/query
Production examplehttps://app.example.com/apihttps://app.example.com/api/query
Direct service, local debugging onlyhttp://localhost:8080http://localhost:8081

The gateway rewrites GET /api/health to command /health, POST /api/instances to command /instances, and GET /api/query/instances to query /instances. Compatibility is the worker protocol header and the platform release.

OpenAPI, Swagger, and Postman

The machine-readable contract is OpenAPI 3.0.3 for release v1.1.0. It covers command, query, worker, inbox, and identity-administration routes. This guide and that file are the release contract. Generate clients from the OpenAPI file. The command service also serves a legacy Swaggo page at /api/swagger/index.html. That page needs a token and lists only annotated handlers, so it is not the complete contract.

On worker calls send X-Workflow-Worker-Protocol-Version: v1. On job complete, fail, and lock extension send a distinct Idempotency-Key of at most 128 characters. The narrative source is docs/API.md.

Authentication

Protected routes require Authorization: Bearer. Integrations use a machine identity that holds only artificialflow client. Obtain the token with client credentials from your OIDC provider. The audience is normally workflow-backend.

TOKEN=$(curl -sS -X POST "$TOKEN_URL" \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=client_credentials" \
  -d "client_id=$CLIENT_ID" \
  -d "client_secret=$CLIENT_SECRET" \
  -d "audience=workflow-backend" \
  | jq -r .access_token)

curl -sS "$API/identity/me" -H "Authorization: Bearer $TOKEN"
RoleAPI use
artificialflow clientWorkers, automation, and backends. Start instances, jobs, messages, signals, query reads, and inbox calls that carry acting-user headers.
artificialflow modelerDeploy and list workflows and decisions. This role cannot start instances or search projected instances.
artificialflow adminDelete workflows and instances, incidents, job retry, admin task claim, metrics, and identity administration. Keep this role off a long-lived worker.

An inbox backend that holds both artificialflow client and artificialflow admin is rejected. Catalog letters below are A for admin, M for modeler, and C for client. GET /identity/me returns the principal for any valid token. GET /identity/config returns non-secret deployment settings: mode, issuers, claim paths, and standard roles.

Conventions

  • JSON bodies use Content-Type: application/json. Deploy BPMN with POST /workflows and Content-Type: application/xml. The body limit is about 20 MB.
  • Resource ids come back as JSON strings. Query instance ids and the workflowId filter must be numeric strings.
  • Worker responses include X-Workflow-Engine-Protocol-Version: v1. Optional X-Correlation-ID traces a request.
  • Query reads are eventually consistent. Read the command instance when the write must be visible immediately.
  • /health only proves the HTTP process is running. Sync health can return HTTP 200 while the worker is starting or degraded.

Error bodies are plain text. Read the body and treat any status outside 2xx as failure.

StatusTypical meaning
400Validation, a bad id, or an unsupported worker protocol version.
401Missing or invalid token, issuer, audience, or expiry.
403The token is valid and the role, or the inbox acting user, is rejected.
404Unknown workflow, instance, or job.
409Conflict, including a task claim state.
413BPMN body larger than about 20 MB.
500Server error.

Quickstart

$API is the gateway command root. The query search in the last call is under the same origin.

export API=http://localhost:9100/api
export TOKEN=…

curl -sS "$API/identity/me" -H "Authorization: Bearer $TOKEN"

curl -sS -X POST "$API/workflows" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/xml" \
  --data-binary @process.bpmn

curl -sS -X POST "$API/instances" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "workflow_id": "order_approval",
    "context": { "orderId": "ord-1", "amount": 1500 }
  }'

curl -sS -X POST "$API/jobs/activate" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Workflow-Worker-Protocol-Version: v1" \
  -d '{
    "type": "payment",
    "worker": "payments-1",
    "maxJobs": 5,
    "timeoutMs": 5000,
    "lockDurationMs": 30000
  }'

curl -sS -X POST "$API/jobs/$JOB_KEY/complete" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -H "X-Workflow-Worker-Protocol-Version: v1" \
  -H "Idempotency-Key: complete-$JOB_KEY-1" \
  -d '{ "worker": "payments-1", "variables": { "paid": true } }'

curl -sS "$API/query/instances?state=RUNNING&page=1&pageSize=20" \
  -H "Authorization: Bearer $TOKEN"

Command reference

Workflows

POST /workflows deploys raw BPMN 2.0 XML. Roles A, M, and C. The response is a workflow definition with string id, process_definition_id, version, and bpmn_xml. GET /workflows and GET /workflows/{id} use the same roles. {id} may be the numeric definition key or the BPMN process id. DELETE /workflows/{id} is admin only and returns 204.

Instances

POST /instances starts a process. Roles A and C. workflow_id is required and may be a numeric definition key or a BPMN process id. Optional version pins a version when workflow_id is a process id. Optional context is the initial variable map. The response status for a running instance is ACTIVE.

  • GET /instances lists active instances from the command store. Modeler-only principals are blocked.
  • GET /instances/history/completed?limit= defaults to a cap of 100.
  • GET /instances/{id} returns the instance, executions, and task metadata.
  • DELETE /instances/{id} is admin only and returns 204.
  • POST /instances/{id}/variables sends { "variables": { "approved": true } }.
  • POST /instances/{id}/complete is legacy step completion by step_id. Human tasks use the inbox.
  • GET /instances/{id}/tasks returns { "tasks": [] }.

Admin task operations, not the end-user inbox:

MethodPathRoles
POST/instances/{id}/tasks/{executionId}/claimA
POST/instances/{id}/tasks/{executionId}/completeA
GET/instances/{id}/jobsA

Messages, signals, and escalations

Roles A and C. Empty bodies are allowed. A successful publish often returns an empty JSON object.

curl -sS -X POST "$API/messages" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "message_name": "PaymentReceived",
    "correlation_key": "ord-1",
    "payload": { "amount": 1500 }
  }'

curl -sS -X POST "$API/signals" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "signal_name": "GlobalCancel", "payload": {} }'

curl -sS -X POST "$API/escalations" \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{ "escalation_code": "NeedManager", "payload": {} }'

Decisions

POST /decisions and GET /decisions accept A, M, and C. The resource field is a string containing the JSON decision table. POST /decisions/{id}/evaluate accepts A and C. {id} is the decision id, and the body is { "inputs": { "amount": 1500 } }. See Decisions.

Incidents, retry, and metrics

MethodPathRoles
GET/incidents?processInstanceKey=&limit=A
POST/jobs/{key}/retryA, optional body { "retries": 3 }
GET/internal/metricsA, outbox and idempotency counters

The Incidents console page is hidden in this release. The HTTP route remains.

Workers

External service tasks become lockable jobs. Protocol version is v1. Roles are A and C. The loop is GET /jobs/capabilities, then POST /jobs/activate, then complete, fail, or extend the lock. Idempotency scope is the operation plus the job key. Replay of the same key returns 200. Complete, fail, and extend-lock need distinct keys. Details and the lock fields are on Workers.

gRPC JobWorkerService listens on the command process at GRPC_ADDR, default :50051. The gateway does not publish it.

Inbox

A trusted backend holds the artificialflow client token and sends the signed-in person on each call. Subject or email is required. Acting roles must omit artificialflow admin and artificialflow client. A person using the browser Task Inbox, with no platform role, acts as themselves and omits these headers.

HeaderPurpose
X-ArtificialFlow-Acting-SubjectStable user id. Preferred.
X-ArtificialFlow-Acting-UsernameUsername, used when subject is absent.
X-ArtificialFlow-Acting-EmailEmail. Subject or email is required.
X-ArtificialFlow-Acting-NameDisplay name.
X-ArtificialFlow-Acting-RolesComma-separated roles and candidate groups.
MethodPath
GET/inbox
GET/inbox/history?limit=
GET/inbox/instances/{id}
GET/inbox/instances/{id}/tasks
POST/inbox/instances/{id}/tasks/{executionId}/claim
POST/inbox/instances/{id}/tasks/{executionId}/complete

Query

Base {gateway}/api/query. GET /query/instances and GET /query/instances/{id} accept admin and client. workflowId is a numeric definition key. state=RUNNING maps to stored status ACTIVE. Other filters include COMPLETED and FAILED. page defaults to 1 and pageSize to 20. Projected instances omit the task tree. Use command GET /instances/{id} or the inbox for task detail. GET /query/workflows accepts admin, modeler, and client, and omits BPMN XML. GET /query/health is public. GET /query/identity/me inspects the same bearer principal.

Identity administration

These routes are in the v1.1.0 contract for trusted administrative automation. Every one requires artificialflow admin. Do not call them from browser code. Create and rotate responses can contain one-time secret material.

MethodPath
GET, POST/identity/management/clients
DELETE/identity/management/clients/{id}
POST/identity/management/clients/{id}/tokens
DELETE/identity/management/clients/{id}/tokens/{tokenId}
POST/identity/management/clients/{id}/keys
DELETE/identity/management/clients/{id}/keys/{keyId}
GET, POST/identity/management/users
PUT, DELETE/identity/management/users/{id}
POST/identity/management/users/{id}/terminate
POST/identity/management/users/{id}/reactivate
GET, POST/identity/management/roles
PUT, DELETE/identity/management/roles/{roleKey}

Command catalog

Paths are relative to /api.

MethodPathRoles
GET/healthpublic
GET/identity/meauth
GET/identity/configauth
POST/workflowsA, M, C
GET/workflowsA, M, C
GET/workflows/{id}A, M, C
DELETE/workflows/{id}A
POST/decisionsA, M, C
GET/decisionsA, M, C
POST/decisions/{id}/evaluateA, C
POST/instancesA, C
GET/instancesscoped
GET/instances/history/completedscoped
GET/instances/{id}scoped
DELETE/instances/{id}A
POST/instances/{id}/variablesA, C
POST/instances/{id}/completeA, C
GET/instances/{id}/tasksscoped
POST/instances/{id}/tasks/{executionId}/claimA
POST/instances/{id}/tasks/{executionId}/completeA
GET/instances/{id}/jobsA
GET/incidentsA
POST/jobs/{key}/retryA
POST/signalsA, C
POST/messagesA, C
POST/escalationsA, C
GET/jobs/capabilitiesA, C
POST/jobs/activateA, C
POST/jobs/{key}/completeA, C
POST/jobs/{key}/failA, C
POST/jobs/{key}/extend-lockA, C
GET/inboxinbox
GET/inbox/historyinbox
GET/inbox/instances/{id}inbox
GET/inbox/instances/{id}/tasksinbox
POST/inbox/instances/{id}/tasks/{executionId}/claiminbox
POST/inbox/instances/{id}/tasks/{executionId}/completeinbox
GET/internal/metricsA

Query catalog

Paths are relative to /api/query.

MethodPathRoles
GET/healthpublic
GET/identity/meauth
GET/instancesA, C
GET/instances/{id}A, C
GET/workflowsA, M, C

Production checklist

  • Use a dedicated machine identity with only artificialflow client.
  • Keep client secrets in a secret manager. Obtain short-lived tokens on the server.
  • Send X-Correlation-ID and record it with your own request id.
  • Retry transient network failures and selected 5xx responses. Do not blindly retry instance starts or message publication. Reuse an Idempotency-Key only for the same job operation and payload.
  • Set the worker lock longer than normal execution, and extend it before it expires.
  • Read command GET /instances/{id} when the write must be visible immediately. Poll query with a bounded timeout.
  • Pin the minor line, check GET /jobs/capabilities at worker startup, and regenerate clients only from a reviewed OpenAPI diff.