REST API

Drive MadMax from CI, scripts, or your own services — the same workflows, runs, and lifecycle verbs as the canvas. Paste a token below and every endpoint on this page is live.

base url https://madmax.build/api/v1

Authentication

Every request carries a bearer token minted in Settings → developer. Tokens are pinned to ONE workspace — all reads and writes happen there, no matter what else your account can see. Read-scope tokens may only GET; the build scope unlocks the write verbs. Two headers are mandatory on every call:

Authorization: Bearer mmx_... Content-Type: application/vnd.api+json

Stays in this browser (localStorage) and is sent ONLY as the Authorization header of requests you fire from this page — never to our servers otherwise. Every endpoint card below gets a try it panel.

Conventions

Two response shapes
Resource routes (list / get / patch / delete) speak JSON:API: enveloped {"data": {"type", "id", "attributes"}} objects. The lifecycle verbs (run, activate, export, …) take a flat {"data": {<args>}} body and return plain JSON — zero-argument verbs can be POSTed with no body at all.
Pagination
Lists are keyset-paginated: ?page[limit]=25 (max 100), then follow the links.next URL — or pass page[after]=<cursor> yourself.
Sparse fieldsets
Heavy payloads stay off the wire until asked for: GET /executions/:id?fields[execution]=status,output,error pulls a run's full output; fields[execution-step]=node_id,status,output does the same per step.
Create from a document
POST /workflows accepts an optional document — a madmax/v1 export (from the export endpoint), an n8n export, or a bare React-Flow {"nodes": [...], "edges": [...]} graph — and reports placeholders + connection requirements to finish by hand:
{"data": {"name": "My workflow", "document": {"format": "madmax/v1", ...}}}
Errors
JSON:API error objects: {"errors": [{"status", "title", "detail"}]} — 401 bad/expired token, 403 read-only token on a write, 404 outside the pinned workspace, 400/422 invalid input, 429 rate limited (with retry-after).

Token

GET /api/v1/me returns 200

Token introspection — the authenticated user, the pinned workspace (id, name, slug), and the token's scopes + expiry. The first call to make when wiring up a client.

try it

Workflows

List, create (bare or from a document), rename, export, edit the graph, activate/deactivate, run, duplicate, and delete workflows.

GET /api/v1/workflows returns 200

Workflows in the token's workspace, newest first.

param in type required
filter query no
sort query string no
page query object no
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/workflows \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
POST /api/v1/workflows returns 201

Create a workflow — bare (name only) or from a document: a madmax/v1 export, an n8n export, or a bare {nodes, edges} graph. Returns a summary + placeholder/requirement report for document imports.

curl -X POST https://madmax.build/api/v1/workflows \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"data":{"document":"","name":""}}'
try it
GET /api/v1/workflows/{id} returns 200

One workflow by id, pinned-workspace only.

param in type required
id path string yes
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/workflows/{id} \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
PATCH /api/v1/workflows/{id} returns 200

Rename / toggle auto-probe. Nothing else is PATCHable.

param in type required
id path string yes
include query string no
fields query object no
curl -X PATCH https://madmax.build/api/v1/workflows/{id} \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"data":{"attributes":{},"id":"{id}","type":"workflow"}}'
try it
DELETE /api/v1/workflows/{id} returns 200

/workflows/:id operation on workflow resource

param in type required
id path string yes
include query string no
fields query object no
curl -X DELETE https://madmax.build/api/v1/workflows/{id} \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
POST /api/v1/workflows/{id}/activate returns 201

Freeze the canvas into a snapshot and start firing triggers.

param in type required
id path string yes
curl -X POST https://madmax.build/api/v1/workflows/{id}/activate \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
POST /api/v1/workflows/{id}/deactivate returns 201

Stop firing triggers; the snapshot survives for audit.

param in type required
id path string yes
curl -X POST https://madmax.build/api/v1/workflows/{id}/deactivate \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
POST /api/v1/workflows/{id}/duplicate returns 201

Copy into the same workspace as "<name> (copy)"; connection bindings reset.

param in type required
id path string yes
curl -X POST https://madmax.build/api/v1/workflows/{id}/duplicate \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
GET /api/v1/workflows/{id}/export returns 200

The workflow as a portable madmax/v1 document (env ids stripped).

param in type required
id path string yes
curl -X GET https://madmax.build/api/v1/workflows/{id}/export \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
PUT /api/v1/workflows/{id}/graph returns 200

Replace the live canvas graph (same write path as autosave).

param in type required
id path string yes
curl -X PUT https://madmax.build/api/v1/workflows/{id}/graph \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"data":{"graph":{}}}'
try it
POST /api/v1/workflows/{id}/run returns 201

Execute now. Active workflows run their pinned snapshot; draft: true runs the live canvas.

param in type required
id path string yes
curl -X POST https://madmax.build/api/v1/workflows/{id}/run \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json" \
  -d '{"data":{"draft":""}}'
try it

Executions

Run history. Heavy payloads (inputs, output, error) are opt-in via ?fields[execution]=status,output,error.

GET /api/v1/executions returns 200

Executions across the token's workspace, newest first.

param in type required
filter query no
sort query string no
page query object no
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/executions \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
GET /api/v1/executions/{id} returns 200

One execution by id, pinned-workspace only.

param in type required
id path string yes
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/executions/{id} \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
POST /api/v1/executions/{id}/cancel returns 201

Terminal stop for a pending/running/waiting execution — flips the row to :cancelled and kills the underlying Oban jobs (same path as the canvas Stop button). Fail-closed: the execution is re-fetched under the actor + pinned-workspace lens first.

param in type required
id path string yes
curl -X POST https://madmax.build/api/v1/executions/{id}/cancel \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it
GET /api/v1/workflows/{workflow_id}/executions returns 200

Executions for one workflow, newest first, pinned-workspace only.

param in type required
workflow_id path string yes
filter query no
sort query string no
page query object no
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/workflows/{workflow_id}/executions \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it

Execution steps

Per-node results within one run — status, timing, and (opt-in) input/output.

GET /api/v1/executions/{workflow_execution_id}/steps returns 200

/executions/:workflow_execution_id/steps operation on execution-step resource

param in type required
workflow_execution_id path string yes
filter query no
sort query string no
page query object no
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/executions/{workflow_execution_id}/steps \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it

Step templates

The primitive catalog (webhook, http, agent, code, …) with each template's config schema — everything needed to author graph nodes.

GET /api/v1/step-templates returns 200

Globally readable. Sorts by `sort_order` so the catalog renders in the same order as the canvas palette.

param in type required
filter query no
sort query string no
include query string no
fields query object no
curl -X GET https://madmax.build/api/v1/step-templates \
  -H "Authorization: Bearer $MADMAX_API_TOKEN" \
  -H "Content-Type: application/vnd.api+json"
try it

machine-readable spec: /api/docs/openapi.json (public, OpenAPI 3 — imports into Postman/Insomnia)