Public beta — not for production use. Data may be wiped at any time. Questions? Contact us.
Documentation menu

Invoke a flow via API

Create an API key, copy the ready-made curl command from the Use via API dialog, and call your compiled flow over HTTP — one-shot or as an SSE stream.

View as Markdown

Every flow you build in the canvas can be invoked over HTTP. This page takes the flow from Build your first flow and calls it from outside the editor: create an API key, copy a ready-made curl command from the Use via API dialog, run it, and read the result — about ten minutes.

Prerequisites

  • A saved flow in the editor — finish Build your first flow first.
  • An account you can sign in to the editor with. The API key you create must belong to the same account that owns the flow.
  • curl on your machine.

Create an API key

API requests authenticate with a bearer API key. To create one:

  1. In the app, go to Console → API Keys (/console/api-keys).
  2. Click Create key, fill in Name (for example my-laptop), and click Create key in the dialog.
  3. The Save your API key dialog shows the raw key — a 64-character hex string — exactly once. Copy it now and click Done; the key is never shown or recoverable again (the platform stores only its SHA-256 hash).

Export it so the commands below can use it:

export AXIOM_API_KEY="<the 64-character key you copied>"

After the dialog closes, the key list shows only the name and a masked form (first 8 characters … last 4). To revoke a key, click Revoke <name> in its row and confirm with Revoke key; revocation takes effect on the key's very next use. Full management details: Create and manage API keys.

The key authorizes requests as your tenant: it can invoke flows your account owns and nothing belonging to other tenants — see Sandboxing and tenancy.

Copy the curl command from the Use via API dialog

The editor generates the invoke command for you, two ways:

  • Open your flow, click Run at the bottom of the canvas, then click Use via API in the run dialog's footer. Any input values you filled into the run form are pre-filled into the command.
  • Or open the flow inspector's API section and click Use via API (curl). The same section shows the invoke URL and an Open interactive docs button — see Use the interactive API docs.

The dialog compiles the current canvas into a compiled artifact and shows a complete curl command containing:

  • the invoke URL on your deployment's origin — /invocations/v1/flows/invoke, or /invocations/v1/flows/invoke/stream when the flow runs in pipeline mode;
  • a JSON body whose graph_id is the compiled artifact's 26-character id and whose input is the entry node's input message as a JSON object.

Click the copy button, then replace $AXIOM_API_KEY with your key — or keep the variable and change the quotes around the Authorization header to double quotes so your shell expands it.

The graph_id is pinned to this version of the flow: if you edit the flow, reopen the dialog to get an updated command.

Invoke the flow and read the result

The copied command has this shape (your origin, graph_id, and input are filled in by the dialog; the header is quoted here so $AXIOM_API_KEY expands):

curl -X POST 'https://flows.example-axiom-host.com/invocations/v1/flows/invoke' \
  -H "Authorization: Bearer $AXIOM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "graph_id": "01JX3F8Q4ZJ4M9W4Y0B8T2K7RD",
  "input": { "text": "hello" },
  "wait": true
}'

"wait": true makes the request block until the execution completes — up to 30 seconds by default; set "timeout_seconds" to wait longer. On success the response is HTTP 202 with the result inline:

{
  "accepted": true,
  "execution_id": "4bf92f3577b34da6a3ce929d0e0e4736",
  "result": {
    "success": true,
    "output": { "text": "hello" },
    "completed_at": 1765432100000
  }
}
  • execution_id identifies this execution everywhere — execution history, debug events, and traces all reference it (Debug a flow).
  • result.output is the terminal node's output message, decoded to JSON.

The request body accepts these fields:

FieldRequiredMeaning
graph_idyesThe compiled artifact to execute.
inputyesThe entry node's input message as a JSON object; the platform converts it to the typed message.
waitnoBlock until the execution completes and include result in the response. Without it the response returns immediately with just accepted and execution_id.
timeout_secondsnoHow long to wait for completion (default 30).
config_idnoNamed flow config profile to apply — see Flow configs.

A missing, invalid, or revoked key gets HTTP 401 with {"error":"unauthorized"}. Other failures return a structured error body — see the error catalog and the full HTTP API reference.

Stream a pipeline flow over SSE

A flow in pipeline mode emits a sequence of result frames instead of a single response, so it uses the streaming endpoint /invocations/v1/flows/invoke/stream. The Use via API dialog detects pipeline mode and generates this variant automatically:

curl -N -X POST 'https://flows.example-axiom-host.com/invocations/v1/flows/invoke/stream' \
  -H "Authorization: Bearer $AXIOM_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{
  "graph_id": "01JX3F8Q4ZJ4M9W4Y0B8T2K7RD",
  "input": { "text": "hello" }
}'

-N disables curl's output buffering so frames print as they arrive. The response is Server-Sent Events (Content-Type: text/event-stream); each frame is one data: line of JSON:

data: {"execution_id":"4bf92f3577b34da6a3ce929d0e0e4736","frame_index":0,"payload":{"text":"chunk 1"},"is_final":false}

data: {"execution_id":"4bf92f3577b34da6a3ce929d0e0e4736","frame_index":1,"payload":{"text":"chunk 2"},"is_final":false}

data: {"execution_id":"4bf92f3577b34da6a3ce929d0e0e4736","frame_index":2,"payload":{"text":"chunk 3"},"is_final":false}

data: {"execution_id":"4bf92f3577b34da6a3ce929d0e0e4736","frame_index":3,"is_final":true,"success":true}
  • payload is the terminal node's output message for that frame, decoded to JSON. Payload-carrying frames always have "is_final": false.
  • The stream ends with a separate final frame — "is_final": true and no payload; its success reports whether the execution succeeded, and on failure error carries the message.
  • The stream times out after 30 seconds by default; set "timeout_seconds" in the body to extend it. A timeout ends the stream with a final frame whose error is "timeout waiting for pipeline result".
  • wait does not apply here — streaming always delivers frames as they are produced.

A flow that contains a pipeline node always runs in pipeline mode; for other flows, the flow type is shown in the run dialog and can be switched there — see Execution model.

Next steps

Your flow is now an endpoint any program can call. From here: