English
Workflows
Routes are relative to <PUBLIC_BASE_URL>; request and response bodies are JSON unless stated otherwise. Authentication, scopes, pagination and the error format are described in the REST API guides.
GET /api/v1/workflows
List my workflows
The workflows of the member, with their draft and published version references. Archived ones are left out unless includeArchived=true.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
includeArchived | query | string | no |
Responses
200 — The workflows.
| Field | Type | Required |
|---|---|---|
workflows | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"workflows": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"published": { "type": "boolean" },
"draftVersion": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"publishedVersion": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"archivedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"dispatchPriority": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"hasWebhook": { "type": "boolean" },
"pausedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"errorWorkflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"maxConcurrency": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"executionTimeoutMs": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"executionLimits": {
"type": "object",
"properties": {
"maxConcurrency": {
"type": "object",
"properties": {
"effective": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"default": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "effective", "default", "max" ],
"additionalProperties": false
},
"executionTimeoutMs": {
"type": "object",
"properties": {
"effective": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"default": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "effective", "default", "max" ],
"additionalProperties": false
}
},
"required": [ "maxConcurrency", "executionTimeoutMs" ],
"additionalProperties": false
},
"lastExecution": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"status": {
"type": "string",
"enum": [
"queued",
"running",
"waiting",
"succeeded",
"failed",
"cancelled"
]
},
"createdAt": { "type": "string" }
},
"required": [ "id", "status", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [
"id",
"name",
"published",
"draftVersion",
"publishedVersion",
"archivedAt",
"dispatchPriority",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [ "workflows" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
POST /api/v1/workflows
Create a workflow
Creates a draft workflow owned by the member, empty or from the given graph. Nothing is published: publishing is a separate, explicit step.
Access — Member session or API key with scope workflows:write.
Request body (application/json)
| Field | Type | Required |
|---|---|---|
name | string | yes |
graph | object | no |
JSON Schema
json
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"graph": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 128 },
"workflowId": { "type": "string", "minLength": 1, "maxLength": 128 },
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ]
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ]
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name" ]
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"output": { "type": "string" },
"to": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ]
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ]
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ]
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "position" ]
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ]
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
}
},
"required": [ "name" ]
}Responses
201 — The workflow, with its draft graph and diagnostic.
| Field | Type | Required |
|---|---|---|
id | string | yes |
name | string | yes |
published | boolean | yes |
draftVersion | object | null | yes |
publishedVersion | object | null | yes |
archivedAt | string | null | yes |
dispatchPriority | integer | null | yes |
hasWebhook | boolean | no |
pausedAt | string | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
executionLimits | object | no |
lastExecution | object | null | no |
createdAt | string | yes |
updatedAt | string | yes |
graph | object | yes |
validation | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"published": { "type": "boolean" },
"draftVersion": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"publishedVersion": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"archivedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"dispatchPriority": {
"anyOf": [
{
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"hasWebhook": { "type": "boolean" },
"pausedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"errorWorkflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"maxConcurrency": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"executionTimeoutMs": {
"anyOf": [
{
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
{ "type": "null" }
]
},
"executionLimits": {
"type": "object",
"properties": {
"maxConcurrency": {
"type": "object",
"properties": {
"effective": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"default": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "effective", "default", "max" ],
"additionalProperties": false
},
"executionTimeoutMs": {
"type": "object",
"properties": {
"effective": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"default": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"max": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
}
},
"required": [ "effective", "default", "max" ],
"additionalProperties": false
}
},
"required": [ "maxConcurrency", "executionTimeoutMs" ],
"additionalProperties": false
},
"lastExecution": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"status": {
"type": "string",
"enum": [
"queued",
"running",
"waiting",
"succeeded",
"failed",
"cancelled"
]
},
"createdAt": { "type": "string" }
},
"required": [ "id", "status", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" },
"graph": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
}
},
"required": [
"id",
"name",
"published",
"draftVersion",
"publishedVersion",
"archivedAt",
"dispatchPriority",
"createdAt",
"updatedAt",
"graph",
"validation"
],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
Example request
json
{ "name": "Triage des factures" }GET /api/v1/workflows/{id}
Read a workflow
The summary, the draft graph and its validation diagnostic. A workflow that does not belong to the caller is a 404, never a 403.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The workflow.
| Field | Type | Required |
|---|---|---|
id | string | yes |
name | string | yes |
published | boolean | yes |
draftVersion | object | null | yes |
publishedVersion | object | null | yes |
archivedAt | string | null | yes |
dispatchPriority | integer | null | yes |
hasWebhook | boolean | no |
pausedAt | string | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
executionLimits | object | no |
lastExecution | object | null | no |
createdAt | string | yes |
updatedAt | string | yes |
graph | object | yes |
validation | object | yes |
Same schema as POST /api/v1/workflows.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
PATCH /api/v1/workflows/{id}
Rename, archive or configure a workflow
Partial update: name, archived flag, dispatch priority and error workflow. For nullable fields, an absent key leaves the value unchanged and null clears it. Archiving disarms the triggers without deleting anything.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
name | string | no |
archived | boolean | no |
dispatchPriority | integer | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
JSON Schema
json
{
"type": "object",
"properties": {
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"archived": { "type": "boolean" },
"dispatchPriority": {
"anyOf": [
{ "type": "integer", "minimum": 0, "maximum": 9999 },
{ "type": "null" }
]
},
"errorWorkflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"maxConcurrency": {
"anyOf": [
{ "type": "integer", "minimum": 1, "maximum": 1000 },
{ "type": "null" }
]
},
"executionTimeoutMs": {
"anyOf": [
{ "type": "integer", "minimum": 60000, "maximum": 9007199254740991 },
{ "type": "null" }
]
}
}
}Responses
200 — The workflow, updated.
| Field | Type | Required |
|---|---|---|
id | string | yes |
name | string | yes |
published | boolean | yes |
draftVersion | object | null | yes |
publishedVersion | object | null | yes |
archivedAt | string | null | yes |
dispatchPriority | integer | null | yes |
hasWebhook | boolean | no |
pausedAt | string | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
executionLimits | object | no |
lastExecution | object | null | no |
createdAt | string | yes |
updatedAt | string | yes |
graph | object | yes |
validation | object | yes |
Same schema as POST /api/v1/workflows.
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — request.bad_request, workflow.not_found, workflow.error_workflow_invalid. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
DELETE /api/v1/workflows/{id}
Delete a pristine draft
Only a workflow that was never published and never ran can be deleted. Any other workflow is refused with workflow.delete_forbidden: archive it instead.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
204 — Deleted.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.delete_forbidden. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/duplicate
Duplicate a workflow
Creates a new draft from the draft graph of the source. The copy carries no publication, no executions, no test messages and no webhook token.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
name | string | yes |
JSON Schema
json
{
"type": "object",
"properties": { "name": { "type": "string", "minLength": 1, "maxLength": 200 } },
"required": [ "name" ]
}Responses
201 — The copy.
| Field | Type | Required |
|---|---|---|
id | string | yes |
name | string | yes |
published | boolean | yes |
draftVersion | object | null | yes |
publishedVersion | object | null | yes |
archivedAt | string | null | yes |
dispatchPriority | integer | null | yes |
hasWebhook | boolean | no |
pausedAt | string | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
executionLimits | object | no |
lastExecution | object | null | no |
createdAt | string | yes |
updatedAt | string | yes |
graph | object | yes |
validation | object | yes |
Same schema as POST /api/v1/workflows.
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.not_found, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/workflows/{id}/draft
Read the draft
The same shape as GET /workflows/{id}: the summary with the draft graph and its diagnostic.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The draft.
| Field | Type | Required |
|---|---|---|
id | string | yes |
name | string | yes |
published | boolean | yes |
draftVersion | object | null | yes |
publishedVersion | object | null | yes |
archivedAt | string | null | yes |
dispatchPriority | integer | null | yes |
hasWebhook | boolean | no |
pausedAt | string | null | no |
errorWorkflowId | string | null | no |
maxConcurrency | integer | null | no |
executionTimeoutMs | integer | null | no |
executionLimits | object | no |
lastExecution | object | null | no |
createdAt | string | yes |
updatedAt | string | yes |
graph | object | yes |
validation | object | yes |
Same schema as POST /api/v1/workflows.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
PUT /api/v1/workflows/{id}/draft
Save the draft
Warning-only: an inconsistent graph is saved and its issues are returned, only a malformed document is refused (400). With expectedDraft, the write is refused (409 workflow.draft_conflict) when the draft was written elsewhere since it was read.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
graph | object | yes |
expectedDraft | object | no |
JSON Schema
json
{
"type": "object",
"properties": {
"graph": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 128 },
"workflowId": { "type": "string", "minLength": 1, "maxLength": 128 },
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ]
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ]
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name" ]
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"output": { "type": "string" },
"to": { "type": "string", "pattern": "^[A-Za-z0-9_-]{1,64}$" },
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ]
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ]
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ]
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "position" ]
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ]
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"expectedDraft": {
"type": "object",
"properties": { "id": { "type": "string" }, "updatedAt": { "type": "string" } },
"required": [ "id", "updatedAt" ]
}
},
"required": [ "graph" ]
}Responses
200 — The new draft version and its diagnostic.
| Field | Type | Required |
|---|---|---|
version | object | yes |
validation | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"version": {
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
}
},
"required": [ "version", "validation" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.invalid_graph, workflow.graph_outdated, workflow.draft_conflict. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/publish
Publish the draft
Freezes the draft as the published version and arms its triggers. Blocking on validation errors (409 workflow.not_publishable, with the diagnostic in details.validation). For a webhook trigger, the token is returned here in clear, once, and never again.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The published version, the armed mailboxes and the webhook URL if any.
| Field | Type | Required |
|---|---|---|
ok | boolean | yes |
validation | object | yes |
publishedVersion | object | null | yes |
armedMailboxes | integer | yes |
webhook | object | null | no |
JSON Schema
json
{
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
},
"publishedVersion": {
"anyOf": [
{
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"armedMailboxes": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"webhook": {
"anyOf": [
{
"type": "object",
"properties": {
"configured": { "type": "boolean" },
"url": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"token": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "configured", "url", "token" ],
"additionalProperties": false
},
{ "type": "null" }
]
}
},
"required": [ "ok", "validation", "publishedVersion", "armedMailboxes" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — workflow.not_found, workflow.archived, workflow.not_publishable, workflow.call_cycle, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/unpublish
Unpublish a workflow
Disarms the triggers and clears the published version. The draft is untouched.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — Unpublished.
| Field | Type | Required |
|---|---|---|
published | false | yes |
JSON Schema
json
{
"type": "object",
"properties": { "published": { "type": "boolean", "const": false } },
"required": [ "published" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.not_published. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/pause
Pause a published workflow
Stops the triggers without unpublishing: the published version stays, nothing fires until resume. Requires a published workflow (409 workflow.not_published otherwise). Recorded in the audit log.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The pause instant.
| Field | Type | Required |
|---|---|---|
pausedAt | string | yes |
JSON Schema
json
{
"type": "object",
"properties": { "pausedAt": { "type": "string" } },
"required": [ "pausedAt" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.not_published. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/resume
Resume a paused workflow
The triggers fire again. Idempotent: resuming a workflow that is not paused returns 200.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — Resumed.
| Field | Type | Required |
|---|---|---|
pausedAt | null | yes |
JSON Schema
json
{
"type": "object",
"properties": { "pausedAt": { "type": "null" } },
"required": [ "pausedAt" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/webhook
Generate or rotate the webhook URL
Issues a new token for the webhook trigger; the previous URL stops answering at once. The token is stored hashed, so this is the only way to see a URL again. Allowed before publishing: the URL fires nothing until the workflow is published.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The webhook URL and its token, in clear, once.
| Field | Type | Required |
|---|---|---|
webhook | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"webhook": {
"type": "object",
"properties": {
"configured": { "type": "boolean" },
"url": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"token": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "configured", "url", "token" ],
"additionalProperties": false
}
},
"required": [ "webhook" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.not_a_webhook. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/workflows/{id}/versions
List the versions of a workflow
The history, as version references (no graph). Fetch a frozen graph with GET .../versions/{versionId}/graph.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The versions.
| Field | Type | Required |
|---|---|---|
versions | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"versions": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
}
}
},
"required": [ "versions" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/workflows/{id}/versions/{versionId}/graph
Read the frozen graph of a version
A version of another workflow, or of another member, is the same 404 as an unknown id.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
versionId | path | string | yes |
Responses
200 — The graph.
| Field | Type | Required |
|---|---|---|
graph | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"graph": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
}
},
"required": [ "graph" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/versions/{versionId}/restore
Restore a version as the draft
Copies the frozen graph of the version into the draft, through the same path as a save. Nothing is published or deleted. No concurrency check: the call deliberately replaces the draft. Refused on an archived workflow.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
versionId | path | string | yes |
Responses
200 — The new draft version, its graph and diagnostic.
| Field | Type | Required |
|---|---|---|
version | object | yes |
graph | object | yes |
validation | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"version": {
"type": "object",
"properties": {
"id": { "type": "string" },
"number": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"publishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [ "id", "number", "publishedAt", "createdAt" ],
"additionalProperties": false
},
"graph": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"nodeName": { "type": "string" },
"nodeType": { "type": "string" },
"connectionIndex": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"port": { "type": "string" },
"availablePorts": { "type": "array", "items": { "type": "string" } },
"cycle": { "type": "array", "items": { "type": "string" } },
"param": { "type": "string" },
"value": { "anyOf": [ { "type": "string" }, { "type": "boolean" } ] },
"triggerTypes": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"path": { "type": "string" }
},
"required": [ "code", "message", "path" ],
"additionalProperties": false
}
}
},
"required": [ "code", "message" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
}
},
"required": [ "version", "graph", "validation" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found, workflow.archived, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/test
Run the draft in simulation
Plans a simulated execution of the DRAFT on a real mirrored message or on trigger data: no mail leaves, no side effect. triggerNodeId is required when the draft has triggers of different natures; targetNodeId stops after that node. 202: the execution is planned, its steps arrive over the WebSocket and GET /executions/{id}.
Access — Member session or API key with scope executions:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
messageId | string | no |
triggerData | object | no |
triggerNodeId | string | no |
targetNodeId | string | no |
JSON Schema
json
{
"type": "object",
"properties": {
"messageId": { "type": "string", "minLength": 1 },
"triggerData": {
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"triggerNodeId": { "type": "string", "minLength": 1 },
"targetNodeId": { "type": "string", "minLength": 1 }
}
}Responses
202 — The planned execution and the nodes it will run.
| Field | Type | Required |
|---|---|---|
execution | object | yes |
plannedNodes | string[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"execution": {
"type": "object",
"properties": {
"id": { "type": "string" },
"workflowId": { "type": "string" },
"workflowVersionId": { "type": "string" },
"mailboxId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"messageId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"status": {
"type": "string",
"enum": [ "queued", "running", "waiting", "succeeded", "failed", "cancelled" ]
},
"simulated": { "type": "boolean" },
"parentExecutionId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"triggerNodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"triggerType": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"retryOfExecutionId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"messageHeadline": {
"anyOf": [
{
"type": "object",
"properties": {
"subject": { "type": "string" },
"fromName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"fromEmail": { "type": "string" }
},
"required": [ "subject", "fromName", "fromEmail" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"error": {
"anyOf": [
{
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "type": "string" },
"kind": { "type": "string", "enum": [ "transient", "permanent" ] },
"attempts": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"nodeType": { "type": "string" },
"details": {
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"at": { "type": "string" }
},
"required": [ "code", "message" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"startedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"finishedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" }
},
"required": [
"id",
"workflowId",
"workflowVersionId",
"mailboxId",
"messageId",
"status",
"simulated",
"error",
"startedAt",
"finishedAt",
"createdAt"
],
"additionalProperties": false
},
"plannedNodes": { "type": "array", "items": { "type": "string" } }
},
"required": [ "execution", "plannedNodes" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.not_found, workflow.not_publishable, workflow.trigger_required, workflow.unknown_trigger, workflow.unknown_node, workflow.node_not_executable, workflow.test_message_not_found, workflow.trigger_poll_failed, workflow.invalid_graph, workflow.graph_outdated. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/run
Run the published version on a message
A REAL execution of the PUBLISHED version on a mirrored message of the member: mails do leave. Not to be confused with test. An unpublished workflow is refused (workflow.not_published). Replayable on the same message at will. 202: the execution is planned.
Access — Member session or API key with scope executions:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
messageId | string | yes |
clientToken | string | no |
JSON Schema
json
{
"type": "object",
"properties": {
"messageId": { "type": "string", "minLength": 1 },
"clientToken": {
"type": "string",
"minLength": 8,
"maxLength": 128,
"pattern": "^[A-Za-z0-9._:-]+$"
}
},
"required": [ "messageId" ]
}Responses
202 — The planned execution id and the nodes it will run.
| Field | Type | Required |
|---|---|---|
executionId | string | yes |
plannedNodes | string[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"executionId": { "type": "string" },
"plannedNodes": { "type": "array", "items": { "type": "string" } }
},
"required": [ "executionId", "plannedNodes" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.not_found, workflow.not_published, workflow.archived, workflow.test_message_not_found, workflow.invalid_graph. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
Example request
json
{ "messageId": "0192f1c2-aaaa-7000-8000-000000000042" }Example response (202)
json
{
"executionId": "0192f1c2-bbbb-7000-8000-000000000007",
"plannedNodes": [ "trigger", "categorize", "reply" ]
}POST /api/v1/workflows/{id}/executions/retry-failed
Retry the failed executions of a workflow
Plans a retry of the real executions that failed since since (24 hours by default, 30 days at most) and were not retried yet, up to limit. hasMore says whether to call again. 202: the executions are planned.
Access — Member session or API key with scope executions:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
since | string (date-time) | no |
from | "start" | "failed_step" | no |
version | "published" | "origin" | no |
limit | integer | no |
JSON Schema
json
{
"type": "object",
"properties": {
"since": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z|([+-](?:[01]\\d|2[0-3]):[0-5]\\d)))$"
},
"from": { "default": "start", "type": "string", "enum": [ "start", "failed_step" ] },
"version": {
"default": "published",
"type": "string",
"enum": [ "published", "origin" ]
},
"limit": { "default": 50, "type": "integer", "minimum": 1, "maximum": 200 }
}
}Responses
202 — The new executions, the skipped count and whether more remain.
| Field | Type | Required |
|---|---|---|
executionIds | string[] | yes |
skipped | integer | yes |
hasMore | boolean | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"executionIds": { "type": "array", "items": { "type": "string" } },
"skipped": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"hasMore": { "type": "boolean" }
},
"required": [ "executionIds", "skipped", "hasMore" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/{id}/executions/cancel
Cancel the in-flight executions of a workflow
Cancels the queued, running and waiting top-level executions of the workflow, up to limit; their children (sub-workflows, loop iterations) follow by cascade. 200: the cancellations are done, not planned. hasMore says whether to call again.
Access — Member session or API key with scope executions:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
limit | integer | no |
JSON Schema
json
{
"type": "object",
"properties": {
"limit": { "default": 50, "type": "integer", "minimum": 1, "maximum": 200 }
}
}Responses
200 — What was cancelled, what was skipped, and whether more remain.
| Field | Type | Required |
|---|---|---|
executionIds | string[] | yes |
skipped | object[] | yes |
hasMore | boolean | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"executionIds": { "type": "array", "items": { "type": "string" } },
"skipped": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"reason": { "type": "string", "enum": [ "not_found", "already_settled" ] }
},
"required": [ "id", "reason" ],
"additionalProperties": false
}
},
"hasMore": { "type": "boolean" }
},
"required": [ "executionIds", "skipped", "hasMore" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — request.bad_request, workflow.not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/schedule/preview
Preview the next runs of a schedule
A pure function of the rhythm and the clock: the next occurrences of a schedule being edited, without saving anything. An invalid rhythm is not an error: 200 with issues and no runs, the same codes the publication would refuse with.
Access — Member session or API key with scope workflows:read.
Request body (application/json)
| Field | Type | Required |
|---|---|---|
mode | "interval" | "cron" | yes |
everyMinutes | integer | no |
cron | string | no |
timezone | string | no |
JSON Schema
json
{
"type": "object",
"properties": {
"mode": { "type": "string", "enum": [ "interval", "cron" ] },
"everyMinutes": {
"type": "integer",
"minimum": -9007199254740991,
"maximum": 9007199254740991
},
"cron": { "type": "string", "maxLength": 120 },
"timezone": { "type": "string", "maxLength": 64 }
},
"required": [ "mode" ]
}Responses
200 — The next runs, or the issues.
| Field | Type | Required |
|---|---|---|
runs | string[] | yes |
issues | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"runs": { "type": "array", "items": { "type": "string" } },
"issues": {
"type": "array",
"items": {
"type": "object",
"properties": { "code": { "type": "string" }, "field": { "type": "string" } },
"required": [ "code", "field" ],
"additionalProperties": false
}
}
},
"required": [ "runs", "issues" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — request.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/workflows/wait/preview
Preview when a wait would wake up
Resolves a deadline against the business calendar and the maximum wait of the instance, from from or now. capped says the instance ceiling shortened it. A deadline that cannot be computed is a 400 carrying the deadline error code.
Access — Member session or API key with scope workflows:read.
Request body (application/json)
| Field | Type | Required |
|---|---|---|
mode | "duration" | "until" | "business" | yes |
amount | number | no |
unit | "minutes" | "hours" | "days" | "weeks" | "months" | "years" | no |
date | string | no |
offsetAmount | number | no |
offsetUnit | "days" | "weeks" | "months" | "years" | no |
businessAmount | number | no |
businessUnit | "businessDays" | "businessHours" | no |
atClock | string | no |
timezone | string | no |
onlyBusinessHours | boolean | no |
from | string (date-time) | no |
JSON Schema
json
{
"type": "object",
"properties": {
"mode": { "type": "string", "enum": [ "duration", "until", "business" ] },
"amount": { "type": "number" },
"unit": {
"type": "string",
"enum": [ "minutes", "hours", "days", "weeks", "months", "years" ]
},
"date": { "type": "string", "maxLength": 200 },
"offsetAmount": { "type": "number" },
"offsetUnit": { "type": "string", "enum": [ "days", "weeks", "months", "years" ] },
"businessAmount": { "type": "number" },
"businessUnit": { "type": "string", "enum": [ "businessDays", "businessHours" ] },
"atClock": { "type": "string", "maxLength": 80 },
"timezone": { "type": "string", "maxLength": 100 },
"onlyBusinessHours": { "type": "boolean" },
"from": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
}
},
"required": [ "mode" ]
}Responses
200 — The wake-up instant.
| Field | Type | Required |
|---|---|---|
at | string (date-time) | yes |
waitMs | integer | yes |
past | boolean | yes |
capped | boolean | yes |
shiftedToBusinessHours | boolean | yes |
timezone | string | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"at": {
"type": "string",
"format": "date-time",
"pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))T(?:(?:[01]\\d|2[0-3]):[0-5]\\d(?::[0-5]\\d(?:\\.\\d+)?)?(?:Z))$"
},
"waitMs": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"past": { "type": "boolean" },
"capped": { "type": "boolean" },
"shiftedToBusinessHours": { "type": "boolean" },
"timezone": { "type": "string" }
},
"required": [ "at", "waitMs", "past", "capped", "shiftedToBusinessHours", "timezone" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — wait.bad_request, wait.deadline_invalid. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/workflows/{id}/test-messages
List the pinned test messages
The messages pinned to this workflow for testing. Messages purged from the mirror are gone from the list.
Access — Member session or API key with scope workflows:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The messages.
| Field | Type | Required |
|---|---|---|
messages | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"messages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"mailboxId": { "type": "string" },
"from": {
"anyOf": [
{
"type": "object",
"properties": { "name": { "type": "string" }, "email": { "type": "string" } },
"required": [ "email" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"subject": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"snippet": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"receivedAt": { "type": "string" },
"folderLabels": { "type": "array", "items": { "type": "string" } },
"flags": {
"type": "object",
"properties": {
"seen": { "type": "boolean" },
"flagged": { "type": "boolean" },
"draft": { "type": "boolean" },
"sent": { "type": "boolean" }
},
"required": [ "seen", "flagged", "draft", "sent" ],
"additionalProperties": false
},
"signals": {
"type": "object",
"properties": {
"isAutoReply": { "type": "boolean" },
"isNoReply": { "type": "boolean" },
"isMailingList": { "type": "boolean" },
"isFromSelf": { "type": "boolean" }
},
"required": [ "isAutoReply", "isNoReply", "isMailingList", "isFromSelf" ],
"additionalProperties": false
},
"hasAttachments": { "type": "boolean" },
"position": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"addedAt": { "type": "string" }
},
"required": [
"id",
"mailboxId",
"from",
"subject",
"snippet",
"receivedAt",
"folderLabels",
"flags",
"signals",
"hasAttachments",
"position",
"addedAt"
],
"additionalProperties": false
}
}
},
"required": [ "messages" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — workflow.not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
PUT /api/v1/workflows/{id}/test-messages
Replace the pinned test messages
A replacement, not an addition: the whole set, twenty messages at most, an empty list clears it. A message outside the mailboxes of the member is a 404.
Access — Member session or API key with scope workflows:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
messageIds | string[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"messageIds": {
"maxItems": 20,
"type": "array",
"items": { "type": "string", "minLength": 1 }
}
},
"required": [ "messageIds" ]
}Responses
200 — The new set.
| Field | Type | Required |
|---|---|---|
messages | object[] | yes |
Same schema as GET /api/v1/workflows/{id}/test-messages.
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — request.bad_request, workflow.not_found, workflow.test_message_not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.