Skip to main content
A deployment is addressed exactly like a model or a wrapper. There is no separate API to learn and no SDK change to make: point the same submit call at your own {username}/{alias}.
The response is the standard queue envelope — request_id, status, response_url, status_url, cancel_url — and status polling, SSE, webhooks and retention headers all behave the way they do for catalog models.

The input body is yours

Everything at the top level of the body other than the reserved keys is handed to your workload as its job input, untouched:
There is no input schema on the platform side. Nothing is validated, nothing is coerced, and no field mappings apply — your workload owns its own input contract, and a malformed body surfaces as an error from your own code, not from ModelRunner. Request bodies are accepted up to 10 MB. For anything larger, upload it first and pass a URL your container downloads — see File uploads.

Reserved keys

The same four top-level keys are reserved on every endpoint. Three of them work unchanged on deployments:
Publication exists so a catalog model’s runs can appear as public examples on that model’s page. A deployment has no such surface, which is why public is rejected at submit.The refusal is at submit only: PATCH /requests/{requestId}/visibility is not target-aware and will happily flip a deployment request public afterwards, which also exempts it from retention. Nothing surfaces it publicly, but do not do it.
Because these keys are stripped before dispatch, a workload whose own input schema defines a field named metadata, webhook, webhook_events_filter or public cannot receive it through the raw body.

Results are verbatim

GET {response_url} returns your workload’s own JSON, exactly as your handler returned it:
  • No output schema and no validation. Whatever shape you return — object, array, string — comes back as output.
  • No media finalization. ModelRunner does not scan the output for image or video URLs, does not re-host them, and does not generate thumbnails. Files your workload writes are your responsibility.
  • One exception, and it is blunt: if the output contains a URL pointing at platform-internal infrastructure anywhere, the entire output is replaced by a placeholder string — not just that field — and it stays replaced, because deployment outputs are never re-hosted. If you hit this, change the workload to stop emitting those URLs (upload to your own storage, or return the bytes). Every other URL passes through untouched.
Because the shape is arbitrary, SDK result types for deployment requests are unknown (JS) / Any (Python). Parse them yourself. Reading a failed run still follows the platform convention: GET /requests/{requestId} carries billingStatus: "failed" — the reliable signal — and response_url answers 422 with an error field whenever failure detail is available. See Statuses & failure semantics.

Who can submit

Deployment jobs are owner-only. Your API key can submit to your own deployments; another account’s key gets a 403, even if they know the endpoint. Submission is also gated on two live conditions:
A hibernated deployment accepts jobs but may not run them. Hibernation winds workers down and nothing restores them automatically, so the job is queued with IN_QUEUE and sits there — eventually force-failed by the platform’s stuck-request sweep rather than served. Resume the deployment first, then submit. See Hibernation.
Beta admission applies to job submission too — see Beta gating.

Finding deployment requests later

Deployment jobs land in the same request history as everything else, with two extra fields: Filter the list by deployment:
deploymentId combines with status, metadata and pagination the same way modelEndpoint does. The dashboard’s Requests tab on each deployment is this filter.

What deployments do not have