API reference · Orders

Orders

One workflow, fanned into many runs, under one budget. Concepts are on Generation Orders.

POST/v1/ordersPlan an order. Nothing runs yet.
GET/v1/ordersList orders.
GET/v1/orders/{order_id}Read one, with its counts.
POST/v1/orders/{order_id}/startBegin executing.
POST/v1/orders/{order_id}/cancelStop what has not started.
POST/v1/orders/{order_id}/retry-failedRe-run failed children.
POST/v1/orders/{order_id}/accept-gapSettle short, on purpose.

Lifecycle

StatusMeaning
plannedCreated and estimated. Children exist as planned runs. Nothing spent.
runningStarted. Children are executing.
attentionSettled short but still fulfillable — retry, or accept the gap.
completedEvery child settled successfully, or the gap was accepted.
failedCould not complete.
cancelledYou stopped it.

POST /v1/orders

Plan an order. Returns in the planned state with an estimate; nothing executes.

requestbash
curl -X POST https://api.esy.com/v1/orders \
  -H "Authorization: Bearer $ESY_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "workflowId": "generate-clip-art-asset-v2",
    "workspaceId": "9a1b6d4c-…",
    "intakeBase": { "style": "clay", "aspectRatio": "1:1", "categories": "woodland" },
    "variationSpec": {
      "resolver": "list",
      "params": { "items": [ { "prompt": "a fox" }, { "prompt": "a badger" } ] }
    },
    "budgetLimitUsd": 2.0,
    "budgetEnforcementMode": "hard_stop"
  }'
201 Createdjson
{
  "id": "order-1f2e3d4c",
  "workflowId": "generate-clip-art-asset-v2",
  "workflowVersion": "2026.09.10",
  "status": "planned",
  "executionMode": "standard",
  "estimatedCostUsd": 0.09,
  "counts": { "planned": 2, "running": 0, "succeeded": 0, "failed": 0, "skipped": 0 },
  "currency": "USD"
}
Note the field name
Orders take workflowId, while runs take templateId. Same value, two field names — an inconsistency in the API, not in these docs.

Body

FieldTypeRequiredDescription
workflowIdstringrequiredThe workflow every child runs.
variationSpecobjectrequiredHow children differ. resolver is list, matrix, or csv; params supplies the values.
intakeBaseobjectoptionalIntake shared by every child; variations are merged over it.
workflowVersionstringoptionalPin a version. Defaults to the live one.
workspaceId / projectIduuidoptionalWhere the runs and costs land.
targetCountintegeroptionalHow many successful children you need.
executionModeenumoptionalstandard (default) or batch — provider batch APIs, slower and cheaper.
budgetLimitUsdnumberoptionalA cap for this order alone.
budgetEnforcementModeenumoptionalSame modes as budgets.
providerOverridesobjectoptionalRole → model id, applied to every child.
planArtifactIdstringoptionalLinks children into a pack family.

POST /v1/orders/{order_id}/start

Start executing a planned order.

The budget is checked again here, against current spend — an order planned yesterday can be refused today with a 402.

GET /v1/orders/{order_id}

Read an order and its rollup.

counts gives planned, running, succeeded, failed, and skipped; actualCostUsd rolls up every child. To see the children themselves, list runs with GET /v1/runs?parentOrderId=….

POST /v1/orders/{order_id}/retry-failed

Re-run failed children.

requestbash
curl -X POST https://api.esy.com/v1/orders/order-1f2e3d4c/retry-failed \
  -H "Authorization: Bearer $ESY_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "all": true }'

Pass all: true, or name specific children. Failures classed as deterministic — the same input would fail the same way — are skipped unless you set includeDeterministic: true, because retrying them only buys a second identical failure.

POST /v1/orders/{order_id}/accept-gap

Settle an order short, deliberately, with a recorded reason.

requestbash
curl -X POST https://api.esy.com/v1/orders/order-1f2e3d4c/accept-gap \
  -H "Authorization: Bearer $ESY_API_KEY" \
  -H "content-type: application/json" \
  -d '{ "reason": "Shipping 23 of 25; two prompts need a plan fix." }'

reason is required. Accepting a gap is a decision, and it is kept on the order so a short pack is never silent.