Predictions. image, video & audio
Image, video, and audio generation models run asynchronously: create the job with POST /v1/predictions, poll GET /v1/predictions/{id} every ~2 seconds, and download from the assets array once status is succeeded and assets is non-empty. Outputs are mirrored onto Hormouz's own servers for fast, reliable downloads from inside Iran.
/v1/predictionsBearer authCreate a prediction
Start an async prediction job on an image/video model (image generation, video, audio, etc.). Returns immediately with a prediction ID that you poll until completion.
The async flow:
POST /v1/predictions→ Get predictionid(status:starting)GET /v1/predictions/{id}→ Poll untilsucceededANDassetspopulatedGET /v1/assets/{asset_id}→ Download the output file
Parameters
| Field | in | Type | Description |
|---|---|---|---|
Idempotency-Key | header | string | Optional deduplication token (any string up to 200 characters). How it works:
When to use: Add this header when you want to safely retry a request after a network timeout without risking a duplicate operation. |
Request bodyrequired
| Field | Type | Description |
|---|---|---|
versionrequired | string | Model identifier. Two formats:
Must be an admin-approved model. Unapproved models return
Example: |
inputrequired | object | Model-specific input parameters. Each model accepts different
inputs: check Common fields for image models:
|
webhook | string (uri) | Optional webhook URL to receive prediction status updates. Hormouz normally handles webhooks internally for billing; only set this if you need a copy of the events. |
webhook_events_filter | array of string | Filter which events trigger your webhook. Values:
|
Example
Responses
201Prediction created. Poll GET /v1/predictions/{id} for status.
400The request body or query parameters are invalid. Check the
error.code and error.message fields for details. Codes the
gateway emits at 400:
BAD_REQUEST: generic malformed JSON / missing required field.INVALID_TOOLS: thetoolsarray,pluginsfield, or model's:onlinesuffix uses an unsupported shape. The response names the offender and links to the supported form. See the dedicatedInvalidToolsresponse below for the three triggers and migration hints.UNSUPPORTED_TOOL: a built-in tool (file_search,code_interpreter,computer_use,mcp) whose pricing dimension is not yet wired into the gateway hold estimator.INVALID_AUDIO_FORMAT:input_audio.formatvalue is not in the supported set. The envelope lists every supported codec name. The gateway accepts both short names (wav,webm) and full MIME aliases (audio/wav,audio/webm); anything else fails fast at admission. See API guide §8b.AUDIO_NOT_SUPPORTED_ON_RESPONSES:input_audiocontent part sent toPOST /v1/responses. The Responses API has no audio content type today; resend toPOST /v1/chat/completionsinstead.
401Authentication failed. Either the Authorization header is missing,
the key format is invalid, or the key doesn't match any active account.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"status": 401
}
}402Insufficient credit balance.
409Idempotency key conflict: you sent the same Idempotency-Key with
a different request body.
429Too many requests. Back off and retry after a short delay.
Check the Retry-After header for guidance.
451The submitted image was flagged by our content policy. Explicit or NSFW content is not permitted on image-only models. The prediction does not run. See the Content Policy section above for details on what is screened.
{
"error": {
"code": "CONTENT_POLICY_VIOLATION",
"message": "The submitted image was flagged by our content policy. Explicit or NSFW content is not permitted.",
"status": 451
}
}499Your HTTP client cancelled the request before the gateway finished. No charge: the hold has been released. The most common cause is a 30 s default client timeout against a model whose p95 latency is 45-60 s; bump your client timeout to 120 s.
Retries with the same Idempotency-Key will replay this 499
forever (the prior outcome is "you cancelled"). For an actual
re-attempt, mint a fresh Idempotency-Key. See
docs/CUSTOMER_ERROR_HANDLING.md §3 for the full contract.
{
"error": {
"code": "CLIENT_CLOSED",
"message": "Client disconnected before response",
"status": 499
}
}500Unexpected server error. Please retry with exponential backoff. If the issue persists, contact your admin.
502The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
503The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
504The gateway's 120 s upstream deadline elapsed before the upstream
provider produced a response. Retry with the same
Idempotency-Key so a delayed-but-eventually-successful upstream
call can be replayed instead of re-charged. Consider switching
to a faster model or capping max_tokens if this recurs.
{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "Upstream did not respond before timeout",
"status": 504
}
}/v1/models/{owner}/{name}/predictionsBearer authCreate a prediction (path-based model)
Alternative to POST /v1/predictions where the model is specified
in the URL path instead of the request body. Useful for integrations
that prefer path-based routing.
Equivalent to calling POST /v1/predictions with
"version": "{owner}/{name}".
Parameters
| Field | in | Type | Description |
|---|---|---|---|
ownerrequired | path | string | Model owner (e.g., |
namerequired | path | string | Model name (e.g., |
Idempotency-Key | header | string | Optional deduplication token (any string up to 200 characters). How it works:
When to use: Add this header when you want to safely retry a request after a network timeout without risking a duplicate operation. |
Request bodyrequired
| Field | Type | Description |
|---|---|---|
inputrequired | object | Model-specific input parameters. |
webhook | string (uri) | Optional webhook URL. |
webhook_events_filter | array of string | Webhook event filter. |
Example
Responses
201Prediction created.
400The request body or query parameters are invalid. Check the
error.code and error.message fields for details. Codes the
gateway emits at 400:
BAD_REQUEST: generic malformed JSON / missing required field.INVALID_TOOLS: thetoolsarray,pluginsfield, or model's:onlinesuffix uses an unsupported shape. The response names the offender and links to the supported form. See the dedicatedInvalidToolsresponse below for the three triggers and migration hints.UNSUPPORTED_TOOL: a built-in tool (file_search,code_interpreter,computer_use,mcp) whose pricing dimension is not yet wired into the gateway hold estimator.INVALID_AUDIO_FORMAT:input_audio.formatvalue is not in the supported set. The envelope lists every supported codec name. The gateway accepts both short names (wav,webm) and full MIME aliases (audio/wav,audio/webm); anything else fails fast at admission. See API guide §8b.AUDIO_NOT_SUPPORTED_ON_RESPONSES:input_audiocontent part sent toPOST /v1/responses. The Responses API has no audio content type today; resend toPOST /v1/chat/completionsinstead.
401Authentication failed. Either the Authorization header is missing,
the key format is invalid, or the key doesn't match any active account.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"status": 401
}
}402Insufficient credit balance.
409Idempotency key conflict: you sent the same Idempotency-Key with
a different request body.
429Too many requests. Back off and retry after a short delay.
Check the Retry-After header for guidance.
451Image flagged by content policy. See Content Policy section.
499Your HTTP client cancelled the request before the gateway finished. No charge: the hold has been released. The most common cause is a 30 s default client timeout against a model whose p95 latency is 45-60 s; bump your client timeout to 120 s.
Retries with the same Idempotency-Key will replay this 499
forever (the prior outcome is "you cancelled"). For an actual
re-attempt, mint a fresh Idempotency-Key. See
docs/CUSTOMER_ERROR_HANDLING.md §3 for the full contract.
{
"error": {
"code": "CLIENT_CLOSED",
"message": "Client disconnected before response",
"status": 499
}
}500Unexpected server error. Please retry with exponential backoff. If the issue persists, contact your admin.
502The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
503The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
504The gateway's 120 s upstream deadline elapsed before the upstream
provider produced a response. Retry with the same
Idempotency-Key so a delayed-but-eventually-successful upstream
call can be replayed instead of re-charged. Consider switching
to a faster model or capping max_tokens if this recurs.
{
"error": {
"code": "UPSTREAM_TIMEOUT",
"message": "Upstream did not respond before timeout",
"status": 504
}
}/v1/predictions/{id}Bearer authGet prediction status
Returns the current state of a prediction. Poll this endpoint
until status is succeeded (or failed / canceled).
Important: After succeeded, wait for the assets array to
be populated before downloading. The background mirror worker
typically takes 5–30 seconds to copy outputs to local storage.
Recommended poll interval: Every 2 seconds. Don't poll faster than once per second.
Parameters
| Field | in | Type | Description |
|---|---|---|---|
idrequired | path | string | Prediction ID from the create response. |
Example
Responses
200Current prediction state.
401Authentication failed. Either the Authorization header is missing,
the key format is invalid, or the key doesn't match any active account.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"status": 401
}
}404Prediction not found. Either the ID is wrong or it belongs to a different account.
429Too many requests. Back off and retry after a short delay.
Check the Retry-After header for guidance.
503The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
/v1/predictions/{id}/cancelBearer authCancel a prediction
Cancels a running or queued prediction. The prediction status
changes to canceled and any held credits are released.
Parameters
| Field | in | Type | Description |
|---|---|---|---|
idrequired | path | string | Prediction ID to cancel. |
Idempotency-Key | header | string | Optional deduplication token (any string up to 200 characters). How it works:
When to use: Add this header when you want to safely retry a request after a network timeout without risking a duplicate operation. |
Example
Responses
200Cancellation accepted.
401Authentication failed. Either the Authorization header is missing,
the key format is invalid, or the key doesn't match any active account.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"status": 401
}
}404The requested resource was not found. Either the ID is wrong or it belongs to a different account.
429Too many requests. Back off and retry after a short delay.
Check the Retry-After header for guidance.
503The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
/v1/predictions/{id}/streamBearer authStream prediction events (SSE)
Opens a Server-Sent Events stream for real-time prediction updates. Events include output progress, logs, and completion status.
Event types:
output: Partial or final model outputlogs: Model execution logsdone: Prediction complete
Parameters
| Field | in | Type | Description |
|---|---|---|---|
idrequired | path | string | Prediction ID. |
Example
Responses
200Event stream.
401Authentication failed. Either the Authorization header is missing,
the key format is invalid, or the key doesn't match any active account.
{
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required",
"status": 401
}
}404The requested resource was not found. Either the ID is wrong or it belongs to a different account.
429Too many requests. Back off and retry after a short delay.
Check the Retry-After header for guidance.
503The upstream AI provider is temporarily
unavailable. Retry with exponential backoff (1s, 2s, 4s) using the
same Idempotency-Key: if the upstream actually completed
the work and only the response failed, the gateway replays the
cached success without a second charge. Holds are released
automatically on upstream failures.
FAQ
- Why wait for assets, not just status succeeded?
Output mirroring completes a few seconds after the job (typically 5–30s). The
assetsURLs live on Hormouz's domain and stay valid for 7 days; the source URL expires quickly.- How are predictions billed?
Each model has a fixed per-run price shown in the catalogue. The amount is held from your credit before the run and settled when it finishes; canceled or failed runs release the hold.