Run
POST /v1/run: execute a capability with routing, cost caps and waterfall failover.
POST /v1/run
Execute a capability. The maximum billable amount is reserved before the provider call, then settled to the actual charge on success or released on failure. The request waits up to wait_seconds (default 30, max 120) for the result and answers 200 with the finished run; a run still executing answers 202 with the same payload (done: false) to poll at GET /v1/runs/{run_id}?wait=60. Send "async": true to get the 202 immediately. A run that would breach the organization's daily spend guard ends as blocked with error budget_exceeded before any money moves.
Headers
| Header | Required | Notes |
|---|---|---|
Authorization |
yes | Bearer rg_test_... or Bearer rg_live_... |
Idempotency-Key |
recommended | any unique string; makes the call safe to retry |
Request
{
"capability": "contact.find",
"input": {"first_name": "Alex", "last_name": "Rivera", "company_domain": "example.com"},
"routing": {"provider": "auto", "strategy": "best_value", "max_cost": "0.10", "allow_fallback": true},
"response": {"include_raw": false}
}
| Field | Type | Default | Notes |
|---|---|---|---|
capability |
string | required | from discover |
input |
object | required | must match the capability's input_schema from inspect |
routing.provider |
string | "auto" |
auto, or a provider slug to pin |
routing.strategy |
string | "best_value" |
cheapest, fastest, highest_success_rate, best_value |
routing.max_cost |
string | none | USD cap; offers above it are excluded before the call |
routing.allow_fallback |
bool | true |
set false to disable waterfall failover |
response.include_raw |
bool | false |
include the provider's raw payload alongside the normalized result |
Response
{
"run_id": "run_...",
"status": "succeeded",
"capability": "contact.find",
"provider": "...",
"routing_reason": "auto: best_value picked ...",
"billing": {"currency": "USD", "quoted": "0.05", "charged": "0.05", "platform_funded": true},
"timing": {"duration_ms": 842},
"attempts": [
{"provider": "...", "outcome": "provider_timeout", "duration_ms": 8000, "detail": "..."},
{"provider": "...", "outcome": "succeeded", "duration_ms": 842, "detail": null}
],
"result": {"...": "..."},
"request_id": "req_...",
"created_at": "2026-09-02T09:30:00+00:00"
}
result is present on success; error ({code, message}) is present on failure. billing.charged is what actually settled: null or lower than quoted when the reservation was released or partly released.
Run lifecycle
created → reserved → running → succeeded | no_match | failed | timed_out
A run still in created, reserved or queued can be cancelled. no_match means at least one provider answered authoritatively that there is no result; whether that bills depends on the capability's stated billing conditions.
Waterfall failover
With provider: "auto", a provider error, timeout or unbilled no-match falls through to the next-best provider automatically, up to 3 attempts. Only the provider that delivers is charged; every attempt appears in attempts with its outcome. max_cost caps every attempt, and a pinned provider never falls back.
Idempotency
Replaying the same Idempotency-Key returns the original run, marked Idempotent-Replay: true, without executing or billing again. Use it on every retry loop.
Errors you should handle
| Code | Meaning |
|---|---|
insufficient_balance (402) |
reservation exceeds available balance: top up |
cost_limit_exceeded (402) |
no offer fits under routing.max_cost |
provider_not_available (409) |
no live provider for this capability yet (production) |
no_match (404) |
the providers found nothing; billed only if the capability bills no-matches |
provider_timeout (504), provider_error (502) |
all attempts failed; nothing charged |
Full list: Errors.
Reading this as an agent? This page as markdown: /docs/api/run.md · every page: /docs/llms.txt