Skip to content
looot docs
Esc
↑↓navigate↵open⌘Jpreview

Create a run

Sending an idempotencyKey that was used before returns the existing run, in any status, with replayed: true. No new run is created.

Dispatch starts at once for the run’s workspace, and the call returns at once unless wait says otherwise. wait works as this query parameter or as a body field of the same name; the query parameter wins when both are set. wait=true (or a bare ?wait) waits up to the default of 20 s; a number is seconds, clamped to 0-60.

If the run reaches a terminal status within wait seconds, the answer carries the result inline, in the same run shape. If it is still queued or running when the window ends, you get that queued or running run, as with no wait at all; poll it with GET /v1/runs/{runId} or runs_get.

A 201 can carry status: "failed" for a denial before dispatch, such as endpoint_not_found or a validation_error. Check the run’s own status and error fields, not the HTTP status code alone, to know whether it ran.

POST/v1/runs
Authorization
AuthorizationBearer token · headerrequired
Query parameters
waitboolean | number

Seconds to wait for a terminal result inline (default 20 when true/bare, max 60). Omit entirely for the pre-existing immediate-return behavior.

Header parameters
Idempotency-Keystring

Alternative to the request body's idempotencyKey field. Either satisfies the (still mandatory) requirement; if both are present, they must be equal or the request is a 400.

min length 1
Request body
requiredapplication/json
endpointIdstringrequired

The catalog endpoint id to run

min length 1
inputobjectrequired

Arbitrary key/value input, validated against the endpoint's own input schema

idempotencyKeystring

Required, unless supplied instead as the Idempotency-Key request header (either satisfies the requirement; supplying both requires them to match, or the request is a 400). A replay with the same key and the same body returns the original run (replayed:true); the same key with a different body is a 409. Never auto-generated by the gateway -- see the report's decision options for why.

min length 1
outputobject

Optional output selection/mapping pin; same shape as an inspected endpoint's outputMappingPin

waitboolean | number

Optional alternative to the ?wait= query parameter (the query parameter wins if both are given)

Show properties
One of:
boolean
boolean
number
number
fallbackboolean | object

Optional. Let the run move to the next provider of the same job when one misses or fails, within ONE hold; only attempts that ran are charged. true takes every default. The run then carries route {servedBy, outcome, chargedUsd, capped, attempts[], skipped[], summary}.

Show properties
One of:
boolean
boolean
object
enabledboolean

false turns it off (the same as omitting fallback)

maxAttemptsinteger

Dispatched attempts, default 3

min 1 · max 10
maxCostUsdnumber

The route's cap; default the sum of the first maxAttempts prices; can only lower it

max 100
preferany

Order of the job's other providers, default balanced

Allowed:cheapestreliablefastestbalanced
excludestring[]

Endpoint or provider ids never tried

max items 50
stopAtFirstMissboolean

Stop at the first empty answer, default false

Responses
201

Run created (or the existing run replayed, any status, with replayed:true). A 201 is not itself success -- a pre-dispatch denial (endpoint_not_found, validation_error) also answers 201 with status:"failed" and a populated error; read the body, not the status code.

402

Out of balance -- the run was blocked before dispatch, never billed

errorobjectrequired
Show properties
codestringrequired
messagestringrequired
requestIdstringrequired
balanceMicrosintegerrequired
estimatedCostMicrosintegerrequired
topUpUrlstring | nullrequired
topUpobjectrequired
Show properties
minimumUsdnumberrequired
suggestedUsdnumberrequired
checkoutUrlstring | nullrequired
dashboardUrlstringrequired
messagestringrequired
reasonstring
Allowed:billing_disabledpayment_processor_not_configuredoperator_workspaceread_only_tokenrate_limitedcheckout_failedstripe_timeoutamount_out_of_rangebalance_lowbalance_sufficient
409

Idempotency-key conflict -- a request already exists for this key that this one does not match

429

Rate limit exceeded (execute class, too_many_inflight_runs) -- see Retry-After and X-RateLimit-* response headers

errorobjectrequired
Show properties
codestringrequired
messagestringrequired
requestIdstringrequired
inflightintegerrequired
limitintegerrequired
retryAfterSecondsintegerrequired
Try it
Server
Authorization
Parameters
Bodyapplication/json
Request
curl -X POST "https://api.looot.ai/v1/runs" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
  "endpointId": "string",
  "input": {},
  "idempotencyKey": "string",
  "output": {},
  "wait": true,
  "fallback": true
}'
Response
{
  "runId": "run_0123456789abcdef0123456789abcdef",
  "endpointId": "hunter-email-finder",
  "status": "completed",
  "providerResponseStatus": "ok",
  "createdAt": "2026-09-24T21:14:36.435Z",
  "completedAt": "2026-09-24T21:14:37.377Z",
  "input": {
    "first_name": "Jane",
    "last_name": "Doe",
    "domain": "example.com"
  },
  "outcome": "hit",
  "actualCost": 0.0245,
  "result": {
    "data": {
      "email": "jane.doe@example.com",
      "score": 94
    }
  },
  "error": null
}