Skip to content

The Run API

Every flow you build is also a live HTTP endpoint. This page is the reference for calling one: the URL shape, which HTTP methods work, how request inputs reach your Start node, authentication, how the End node shapes the response, tracing, rate limits, and status codes.

The URL

A flow is called at:

/api/run/<projectId>/<path-to-your-flow-file>[/<extra path params>]
  • <projectId> — the ID of the project the flow lives in.
  • <path-to-your-flow-file> — the folder-and-file path, slugified. FlowRunner lowercases each folder and file name and replaces runs of non-alphanumeric characters with a single hyphen. A file named Create User inside a folder Users resolves at users/create-user.
  • <extra path params> — optional positional segments consumed by the Start node's declared path inputs (see below).
bash
curl https://your-host/api/run/proj_abc/users/create-user

NOTE

Folders with a blank or symbol-only name are transparent — they don't add a segment. If two Start nodes want different HTTP methods on the same file, they share one URL and are told apart by the request method.

Methods

GET, POST, PUT, PATCH, and DELETE are all handled. When a request arrives, FlowRunner looks for a Start node on that file whose configured method matches (Start nodes default to GET). If no Start node matches the method, you get a 404.

OPTIONS is answered directly with 204 and CORS headers — it never runs a flow. All responses carry permissive CORS (Access-Control-Allow-Origin: *) so a browser front-end can call a flow directly.

Inputs: four sources

A Start node declares its inputs in four buckets. The Run API fills each bucket from a different part of the request, validates it against the node's schema, then merges everything into the values your flow sees.

BucketComes fromNotes
pathPositional trailing URL segmentsBound in declared order. Extra segments beyond what's declared → 404.
queryThe URL query string (?a=1&b=2)
headersRequest headersLooked up case-insensitively.
bodyThe JSON request bodyOnly read for non-GET/HEAD methods, and only when the Start node declares body fields. Must be application/json.

If any bucket fails validation (a required field missing, a wrong type, or malformed JSON), the request stops before the flow runs and returns 400 with the list of problems:

json
{ "ok": false, "errors": ["body.email is required", "query.count must be a number"] }

Inside the flow, merged inputs are available under the Start node's name — for a Start node named Start, a field email reads as start.email.

Authentication

Auth is checked before any input parsing. A Start node can require one of four schemes, and the expected secret is resolved from the workspace secrets vault (so you store ${secrets.API_TOKEN}, not a raw token).

SchemeClient sendsOn failure
nonenothing
bearerAuthorization: Bearer <token>401 + WWW-Authenticate: Bearer
basicAuthorization: Basic <base64 user:pass>401 + WWW-Authenticate: Basic
apiKeya header (default X-API-Key)401

Credentials are compared in constant time. Auth is fail-closed: if a scheme is configured but its expected secret is empty or unresolved, every request is rejected rather than let through.

bash
curl https://your-host/api/run/proj_abc/orders/create \
  -H "Authorization: Bearer my-token" \
  -H "Content-Type: application/json" \
  -d '{"sku":"ABC","qty":2}'

Shaping the response

What the caller gets back is decided by the End node the flow reaches:

  • Status code — the End node's configured status (any value 100599; defaults to 200).
  • Body — the End node's response body, composed field-by-field from your flow's data. Each field can be a literal or a reference to a value produced upstream (for example the output of an HTTP or MongoDB node).

If the flow finishes without reaching an End node, you get a 200 with a diagnostic echo of the inputs instead:

json
{ "ok": true, "inputs": { "email": "a@b.com" } }

Tracing with ?_trace

Add ?_trace=1 to any call to get a step-by-step execution trace. The trace lists every node that ran, in order, with timing, the outgoing port it chose, iteration counts (for ForEach), and any error. It's returned two ways:

  • Inlined into the JSON body under a _trace key.
  • URL-encoded in an X-Flow-Trace response header.
bash
curl "https://your-host/api/run/proj_abc/users/create-user?_trace=1"

TIP

?_trace is the fastest way to see where a flow went wrong in production. The same trace is stored for every run and shown visually in run history.

Rate limits

Calls are rate-limited per client IP: 60 requests per 60 seconds. Over the limit you get a 429 with a Retry-After header (in seconds).

json
{ "ok": false, "errors": ["rate limited"] }

NOTE

This is a flat per-IP ceiling today. Per-project plan quotas are planned but not yet in place.

Status codes

CodeMeaning
200 (or your End node's code)Flow completed. Body is the End node's response, or an inputs echo if no End was reached.
204Answer to a CORS OPTIONS preflight.
400Input validation failed. errors lists what was wrong.
401Missing or invalid credentials.
404No such project, flow file, or method — or too many trailing path segments.
429Rate limit exceeded. See Retry-After.
500The flow ran but hit an error. Body includes node (the failing node's ID).

A 500 body looks like this (with _trace added when requested):

json
{ "ok": false, "errors": ["http: network down"], "node": "node_7" }

See also

  • HTTP triggers — configuring the Start node in the editor
  • OpenAPI — a generated spec for every endpoint in a project
  • Run history — the stored trace of every call
  • Errors & try/catch — how a node failure becomes a 500 or routes to a handler branch

FlowRunner — the no-code platform for small businesses.