api
workflowdev
API Reference
All routes are under /api/v1/. The API server runs on port 8080 by default.
Flows
| Method | Endpoint | Description |
|---|---|---|
GET | /flows | List all flows |
POST | /flows | Create a flow |
GET | /flows/{id} | Get a flow |
PUT | /flows/{id} | Update a flow |
DELETE | /flows/{id} | Delete a flow |
POST | /flows/{id}/execute | Execute a flow |
POST | /flows/validate | Validate YAML |
POST | /flows/import | Import a flow from JSON |
GET | /flows/{id}/export | Export a flow as JSON |
GET | /flows/{id}/revisions | List revisions (auto-saved on YAML update) |
POST | /flows/{id}/revisions/{rev}/restore | Restore a revision |
Create a flow
curl -X POST http://localhost:8080/api/v1/flows \
-H "Content-Type: application/json" \
-d '{
"name": "my-workflow",
"namespace": "production",
"yamlContent": "name: my-workflow\ntasks:\n - name: hello\n type: util.log\n properties:\n message: Hello world\n"
}'
Response (201):
{
"id": "a1b2c3d4-...",
"name": "my-workflow",
"namespace": "production",
"yamlContent": "...",
"createdAt": "2026-03-25T10:00:00Z",
"updatedAt": "2026-03-25T10:00:00Z"
}
Execute a flow
curl -X POST http://localhost:8080/api/v1/flows/{id}/execute
Response:
{
"executionId": "e5f6g7h8-...",
"status": "QUEUED",
"tasksTotal": 3
}
Executions
| Method | Endpoint | Description |
|---|---|---|
GET | /executions | List executions |
GET | /executions/{id} | Get execution with task details |
GET | /executions/{id}/logs | Stream logs (WebSocket) |
POST | /executions/{id}/cancel | Cancel a running execution |
POST | /executions/{id}/retry | Retry a failed execution |
Get execution status
curl http://localhost:8080/api/v1/executions/{id}
Response:
{
"execution": {
"id": "e5f6g7h8-...",
"flowId": "a1b2c3d4-...",
"status": "SUCCESS",
"tasksTotal": 3,
"tasksExecuted": 3,
"startedAt": "2026-03-25T10:00:01Z",
"finishedAt": "2026-03-25T10:00:03Z",
"durationMs": 1650
},
"tasks": [
{
"taskName": "fetch",
"taskType": "http.request",
"status": "SUCCESS",
"outputs": "{\"status_code\":200,\"body\":{...}}",
"startedAt": "...",
"finishedAt": "..."
}
]
}
Terminal statuses: SUCCESS, FAILED, CANCELLED, TIMED_OUT
Triggers
| Method | Endpoint | Description |
|---|---|---|
GET | /triggers | List all triggers |
POST | /triggers | Create a trigger |
PUT | /triggers/{id} | Update a trigger |
DELETE | /triggers/{id} | Delete a trigger |
POST | /webhook/{key} | Fire a webhook trigger |
Fire a webhook
curl -X POST http://localhost:8080/api/v1/webhook/my-webhook-key \
-H "Content-Type: application/json" \
-d '{"customerId": 42}'
Plugins
| Method | Endpoint | Description |
|---|---|---|
GET | /plugins | List all 83 plugins with manifests |
GET | /plugins/categories | List categories |
GET | /plugins/{id} | Get a specific plugin manifest |
List plugins
curl http://localhost:8080/api/v1/plugins | jq '.[].id'
Each plugin manifest includes id, name, category, description, inputSchema, and outputSchema.
Credentials
Encrypted credential storage (AES-256-GCM). Reference in workflows via ${CREDENTIAL_NAME}.
| Method | Endpoint | Description |
|---|---|---|
GET | /credentials | List credentials (values are encrypted) |
POST | /credentials | Create a credential |
GET | /credentials/{id} | Get a credential |
PUT | /credentials/{id} | Update a credential |
DELETE | /credentials/{id} | Delete a credential |
Key-Value Store
Simple key-value storage, namespaced. Useful for workflow state that persists across executions.
| Method | Endpoint | Description |
|---|---|---|
PUT | /kv/{namespace}/{key} | Set a value |
GET | /kv/{namespace}/{key} | Get a value |
GET | /kv/{namespace} | List all keys in namespace |
DELETE | /kv/{namespace}/{key} | Delete a key |
Other Endpoints
| Method | Endpoint | Description |
|---|---|---|
GET | /healthz | Health check |
GET | /readyz | Readiness check (verifies DB connection) |
GET | /metrics | Prometheus metrics |
GET | /api/v1/audit | Recent audit log entries |
GET | /api/v1/approvals/{id} | Get gate approval status |
POST | /api/v1/approvals/{id}/approve | Approve a gate |
POST | /api/v1/approvals/{id}/reject | Reject a gate |
Authentication
The API supports optional JWT authentication. When enabled:
# Register
curl -X POST http://localhost:8080/auth/register \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "...", "role": "admin"}'
# Login
TOKEN=$(curl -s -X POST http://localhost:8080/auth/login \
-H "Content-Type: application/json" \
-d '{"username": "admin", "password": "..."}' | jq -r .token)
# Use token
curl -H "Authorization: Bearer $TOKEN" http://localhost:8080/api/v1/flows
Roles: viewer → executor → editor → admin (hierarchical)