Skip to main content

The one rule

status alone does not signal success. A generation that fails at the provider is normalized to status: "COMPLETED" with billingStatus: "failed" — the request finished, but produced no billable output. Each surface exposes failure differently, so read the signal that surface actually carries:
A client that treats status: "COMPLETED" as success will show failed generations as successful. Always branch on the surface’s own signal above.

Terminal states

COMPLETED, FAILED and CANCELLED are terminal — a request never transitions away from them. Two of the three carry caveats:
  • FAILED is rare. A generation that fails at the provider is normalized to COMPLETED (see above); FAILED is what the platform writes when it force-fails a request that got stuck. A job that exceeds a deployment’s execution timeout follows the same normalization — COMPLETED with billingStatus: "failed" — not a resting FAILED.
  • CANCELLED is reachable on deployment jobs. Pollers must include it in their terminal set or they will spin forever on a cancelled job.

Cancellation

Cancellation depends on what the endpoint is. Serverless GPU deployments: cancel is real. PUT (or GET) the cancel_url and the job is stopped, the request goes terminal on CANCELLED with billingStatus: "failed" (zero charge), and a completed webhook fires. An unconfirmed stop is never converted into a local CANCELLED — the response carries the request’s real state instead, which may be COMPLETED. See Cancel and terminal states. Models and wrappers: cancellation is not supported. The cancel_url returned on submit is reserved: requesting it returns the same body as status_url and does not stop the request.

Visibility

Requests are private by default: only the owner (and the platform) can read them. PATCH /requests/{requestId}/visibility with { "public": true } publishes a request so it can appear on catalog preview surfaces (for example as a model example). Publication is all-or-nothing — there is no scoped sharing. The same vocabulary applies to models with one important difference: a private model is unlisted, not access-controlled. It is excluded from listings and search, but direct reads by its owner/alias endpoint (model detail, its openapi.json, invoking it) still resolve. Do not rely on model privacy as an ACL.

Rate limits

Limits are enforced per IP address at the edge; exceeding them returns HTTP 429 (without a Retry-After header). Back off with jitter on 429. There are no per-key quotas today.