Skip to main content
All API errors follow a consistent JSON structure with a machine-readable code and a request_id for support.
Response headers: X-Request-ID carries the same value as request_id for server-side log correlation. Fields:
  • error.message (string, required) — Human-readable error description
  • error.code (string, optional) — Machine-readable error code for programmatic handling
  • error.details (any, optional) — Additional context (e.g., validation errors)
  • request_id (string, optional) — Unique request identifier for debugging

HTTP status codes

Error code catalog

validation_error

HTTP 422. Request body or parameters failed validation. Review the details array, which lists each invalid field:
Each details item contains: type (error type), loc (JSON path to the field), msg (message), input (the invalid value), and optional ctx (constraints) and url. A malformed Idempotency-Key header on POST /api/flow-executions (not a ULID, or lower case) is reported the same way, and no run is created:

invalid_dsl_input

HTTP 400. The flow DSL definition is malformed or invalid — missing required fields, invalid task executor names, circular dependencies, or configurations that don’t match executor schemas.
Ensure all tasks reference valid executors and that dependencies form a valid directed acyclic graph (DAG).

not_found

HTTP 404. The requested resource does not exist — wrong ID, deleted resource, or a resource owned by a different organization (and therefore not visible).

conflict

HTTP 409. The request conflicts with existing state or a database constraint — for example, a duplicate flow name within an organization. Use a different identifier, or retry with backoff for concurrent-modification conflicts. On POST /api/flow-executions, a 409 means a run of this flow with the same Idempotency-Key exists but is not accessible to you (for example, your access to the flow changed while the request was in progress). No new run is created. Repeating the request with the same key won’t create one either; use a new key only if you want a new run.

bad_request

HTTP 400. The request is syntactically correct but semantically invalid — invalid query parameter values, references to non-existent resources, or invalid state transitions.

user_info_not_found

HTTP 401. User information could not be retrieved from the authentication token — invalid/expired token or a deactivated account. Re-authenticate to obtain a fresh token.

repository_error

HTTP 500. A database or repository-layer error occurred (connection failure, query timeout, deadlock). Retry with exponential backoff; contact support with the request_id if it persists.

service_error

HTTP 500 (or a custom status). An application service-layer error — business-logic failure, external integration failure, or unexpected state. Check the message for specifics.

internal_error

HTTP 500. An unexpected internal error. These are automatically logged with full stack traces. Retry (it may be transient) and report the request_id.

HTTP errors without a code

Some errors return a status code without an error.code field — for example 405 Method Not Allowed, 415 Unsupported Media Type, 413 Request Entity Too Large, or 429 Too Many Requests. Handle these by HTTP status.

Handling errors

1

Check the HTTP status code first

2

Branch on the error code

3

Retry transient server errors

Retrying POST /api/flow-executions after a timeout, connection error or 5xx is only safe when the request carries an Idempotency-Key, and the retry reuses the same key. Without one, the first request may already have started the run, and the retry starts a second one. See Retry safely.
4

Log the request_id for support

Summary