run
Run an endpoint, a job by id, or a workflow, spending prepaid credit with idempotent retries and optional fallback across providers.
Runs spend prepaid credit. Needs the runs.execute scope. On a new workspace, call
balance first and top_up if needed. run
validates the input, checks the workspace budget, reserves the estimated max cost, then runs or
queues the endpoint. Some endpoints act on your connected accounts and can send or change things
there.
endpointId can be a concrete endpoint id, "job:<job id>" to let looot pick the first provider
in fallback.prefer order that this workspace can run now and whose schema accepts your input,
or "workflow:<id>" to start that workflow (follow its workflowRunId with runs_get).
Inputs
| Argument | Type | Required | Default | Limits | Meaning |
|---|---|---|---|---|---|
endpointId |
string | Yes | - | - | An endpoint id, job:<job id>, or workflow:<id>. |
input |
object | Yes | - | - | The endpoint’s own input fields, per its inputSchema from inspect. |
idempotencyKey |
string | Yes | - | - | Unique per logical call. Same key and identical body replay the original run; same key with a different body returns 409. |
output.mode |
string | No | - | raw | custom |
raw returns the provider’s own shape; custom needs mappingId (and optional version) for a stored output mapping. |
fallback |
boolean or object | No | - | see below | true takes every default. Object: {enabled, maxAttempts (1-10, default 3), maxCostUsd (0-100), prefer, exclude (max 50 ids), stopAtFirstMiss (default false)}. |
wait |
number | No | 20 | 0-60 | Seconds to block for the settled result inline before returning the queued/running run instead. wait: 0 returns at once. |
error on a failed run: {code, providerStatus, message, requestId, whoseError, retryable, retryHint},
never secrets or raw provider headers. Every run carries outcome
(hit|weak|miss|error|rejected|skipped|pending). With fallback, the result
also carries route: {servedBy, attempts, skipped, summary}. A completed run of a normalized
job can carry normalized next to result.
Example call
{
"endpointId": "linkup-search",
"input": {
"q": "What is Microsoft's 2024 revenue?",
"depth": "standard",
"outputType": "searchResults"
},
"idempotencyKey": "9e2f7c1a-4b3d-4e5f-8a6b-1c2d3e4f5a6b",
"wait": 20
}
Example answer
Abridged: result is the provider’s own payload and varies by endpoint.
{
"runId": "run_807967cc4b7f468fa5d7dbcaefdee859",
"endpointId": "linkup-search",
"status": "completed",
"providerResponseStatus": "ok",
"createdAt": "2026-09-24T21:14:36.435Z",
"completedAt": "2026-09-24T21:14:37.377607+00:00",
"input": {
"q": "What is Microsoft's 2024 revenue?",
"depth": "standard",
"outputType": "searchResults"
},
"outcome": "hit",
"actualCost": 0.005,
"error": null
}
Errors
Out of credit is a tool error with code: "insufficient_balance" and status: "blocked": show
the customer error.message and topUp.checkoutUrl (or topUp.dashboardUrl), wait for payment,
then retry with a new idempotencyKey. A successful call can still carry status: "failed",
for an unknown endpointId or input failing the endpoint’s schema: check status and error,
not the tool call’s own success. Reusing an idempotencyKey with a different endpointId or
input fails as idempotency_conflict, never silently applying the new body to the old run.
Missing idempotencyKey, input or endpointId returns validation_error naming the field.
This workspace already at its in-flight run limit returns too_many_inflight_runs.
REST and CLI
- REST:
POST /v1/runs - CLI:
looot run <endpoint-id> --input '{"..."}' [--wait] [--fallback]