A Flow API runs a reusable flow for whoever calls it. The caller sends the inputs and settings the flow asks for, and gets its results back as files.
A run can take a while, so the API answers at once with a run to follow.
Create one
In API Builder, start a new API and choose "Flow API". Pick a reusable flow and choose "Create API".
The page shows what a caller sends and what a caller gets back. Both come from the flow itself, so there is nothing to map by hand.
A Flow API counts as one API on your plan. It is a draft until you publish it.
Try it
Under Try it, choose a layer for each input, set the settings, pick the format of each result and select Run. The flow runs now, as you, on data in this workspace. Each result comes back as a file you can download. This is the same request and the same checks a published call gets. It counts as one flow run, and nothing is published.
Publish it
Choose "Publish to Server". The release keeps the exact flow version you published. Saving a newer version of the flow later changes nothing on Server until you choose the new version on the API's page and publish again.
In the Server console, make a key for the caller and give it access to the API.
Start a run
Send a POST to the API's /runs address with the key in a header.
curl -X POST "https://<your-server>/public/api/<organization>/<environment>/<api>/runs" \
-H "X-Api-Key: $TAMAAT_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-42" \
-d '{
"inputs": {
"buildings": { "layer_id": "5da52cb6-3b4f-4db7-a12c-1a9047ddf735" },
"area": { "area": { "type": "Polygon", "coordinates": [[[-114.3, 50.9], [-113.8, 50.9], [-113.8, 51.2], [-114.3, 50.9]]] } }
},
"parameters": { "distance": 250 },
"wait_seconds": 20
}'
Each input is one of:
| Send | For |
|---|---|
{"layer_id": "…"} | A layer the environment has been allowed to read |
{"geojson": …} | Your own features, as a GeoJSON FeatureCollection |
{"rows": […]} | Your own table rows |
{"area": …} | One polygon, for an area input |
null | An optional input you leave out |
Data you send with a request is used for that run only. It never becomes a layer in the workspace. A request can carry up to 5,000 rows for one input.
The answer is 202 with the run:
{
"run_id": "0c0f3f3e-7f5e-4a55-9c55-3f6b3c0e8f11",
"state": "queued",
"links": { "self": "/public/api/…/runs/0c0f3f3e-…", "cancel": "/public/api/…/runs/0c0f3f3e-…/cancel" }
}
If something in the request is wrong, the answer is 422 and names each field. No run is started and nothing is counted.
Wait for a short run
Add wait_seconds, up to 60. If the run finishes in that time, the answer is 200 with the finished run and its results. Otherwise it is 202 as before.
Retry safely
Send an Idempotency-Key header. Sending the same request again with the same key returns the same run and does not start a second one. Using the key with a different request is refused.
Follow a run and fetch results
| Call | Does |
|---|---|
GET /runs/{run_id} | Returns the run and its state |
POST /runs/{run_id}/cancel | Cancels a run that has not finished |
GET /runs/{run_id}/results/{key} | Returns one result as a file |
A run is queued, running, completed, failed or cancelled. Results are listed only when it has completed.
A layer result comes back as GeoJSON, or as GeoParquet if you ask. A table comes back as CSV, or as Parquet if you ask:
{ "formats": { "nearby": "geoparquet" } }
A run answers only to the key's consumer that started it. Anyone else is told it does not exist.
Use it from an AI client
On Delivery and Enterprise, a Flow API can be offered to AI clients as a tool through the Model Context Protocol (MCP).
In the Server console, open the API, go to Settings and turn on "Available to AI assistants". "Connect an AI client" then shows the address and the configuration to paste into the client.
The client sees one tool per Flow API, with the flow's inputs and settings as its arguments. A call that finishes quickly is answered with its results. A longer one is answered with a run id, which the client finishes with the run_status, run_result and run_cancel tools.
What a run counts as
Every accepted run is one ETL run on the workspace that owns the API, and its time counts as processing time. Every call counts as an API request. A refused call counts as neither.
When the flow is deleted
If the flow behind a Flow API is moved to the trash, the API's page shows "Source in trash" and it cannot be published again until the flow is restored. After a permanent delete it shows "Needs a source". What is already on Server keeps serving in both cases.