Runs
Submit model runs, edits and batches.
Submit calls answer 202 Accepted with a request object; follow it by polling or a webhook. Add ?dry_run=true for a price estimate (Billing). Input is validated with the same schema as the AITOPIA app; see Requests & lifecycle for field details.
| Method | Path | Summary |
|---|---|---|
POST | /v1/models/{model_id} | Submit a model run. The body is the model input (see GET /v1/models/{model_id}). |
POST | /v1/edit | Edit an asset from an instruction. |
POST | /v1/batch | Submit 1 to 12 generations as one request. |
#POST /v1/models/{model_id}
Submit a model run. The body is the model input (see GET /v1/models/{model_id}).
Besides the model input, the body may carry webhook_url and asset_name.
Authentication: Authorization: Key <key>.
The body is the model input as described by input_schema (the example sends a prompt). webhook_url and asset_name are read by AITOPIA and not passed to the model.
#Path parameters
| Name | Type | Required | Description |
|---|---|---|---|
model_id | string | yes | Model id, for example google/nano-banana-2. Send the "/" as it is or encoded as %2F (generated clients encode it); both reach the same model. |
#Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
wait | integer (min 0, max 60) | no | Long-poll up to N seconds (integer 0-60) for a terminal status. |
dry_run | true | 1 | yes | false | 0 | no | no | true/1/yes returns a price estimate and runs nothing; false/0/no (or absent) runs. Anything else is a 400. |
#Request body
Content type application/json. Additional fields are accepted (the model input).
| Field | Type | Required | Description |
|---|---|---|---|
webhook_url | string (uri) | no | Optional https URL (public host only) that receives the final result as a signed POST. |
asset_name | string | no |
#Responses
| Status | Description | Body |
|---|---|---|
200 | Dry run estimate (dry_run=true) | DryRun |
202 | Accepted | Request |
400 | INVALID_INPUT (with field), URL_NOT_ALLOWED, MODEL_REQUIRED, MODEL_KIND_MISMATCH, MODEL_NOT_ALLOWED, DUPLICATE_ITEM or INVALID_RUN_TOKEN | Error |
401 | UNAUTHENTICATED (missing/invalid/revoked key) or KEY_SESSION_EXPIRED (sign in to aitopia.ai to reactivate the key) | Error |
402 | INSUFFICIENT_CREDITS, KEY_CREDIT_CAP_REACHED or OVER_BUDGET | Error |
404 | MODEL_NOT_FOUND or NOT_FOUND | Error |
409 | PRICE_CHANGED, PRICE_UNKNOWN or PLAN_EXPIRED | Error |
422 | PLAN_INVALID, ASSET_UNREACHABLE or NOT_SUPPORTED | Error |
429 | RATE_LIMIT, RUN_LIMITED or QUEUE_LIMIT_EXCEEDED (see retry_after_seconds and the Retry-After header) | Error |
500 | INTERNAL_ERROR (an unexpected server error) | Error |
502 | UPSTREAM_5XX, or UPSTREAM_UNCERTAIN (the run may have started: check the request_id in the body and your balance before retrying) | Error |
503 | MODEL_UNAVAILABLE, SERVER_RESTARTING or SESSION_UNAVAILABLE (retryable) | Error |
504 | TIMEOUT | Error |
#Example
curl -X POST "https://api-live.aitopia.ai/v1/models/google/nano-banana-2" \
-H "Authorization: Key $AITOPIA_KEY" \
-H "Content-Type: application/json" \
-d '{"prompt":"a lighthouse at dusk, watercolor","webhook_url":"https://example.com/aitopia/webhook"}'{
"dry_run": true,
"endpoint": "google/nano-banana-2",
"credits_estimated": 4,
"affordable": true,
"credits_available": 100
}{
"request_id": "0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"status": "queued",
"endpoint": "google/nano-banana-2",
"created_at": "2026-10-23T10:00:00.000Z",
"completed_at": null,
"credits_estimated": 4,
"output": {
"images": [],
"videos": [],
"audio": [],
"files": []
},
"status_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"result_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"cancel_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10/cancel"
}#POST /v1/edit
Edit an asset from an instruction.
Authentication: Authorization: Key <key>.
instruction: 1 to 1000 characters, any language. media_type: image, video or audio (omit to read it from the file). max_credits ≥ 0 refuses dearer plans (402 OVER_BUDGET). plan_token (from a dry run) runs exactly that priced plan, once, within 1 hour. Planning, dry runs included, is limited to 10 per minute and 100 per day.
#Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
wait | integer (min 0, max 60) | no | Long-poll up to N seconds (integer 0-60) for a terminal status. |
dry_run | true | 1 | yes | false | 0 | no | no | true/1/yes returns a price estimate and runs nothing; false/0/no (or absent) runs. Anything else is a 400. |
#Request body
Content type application/json.
| Field | Type | Required | Description |
|---|---|---|---|
asset_url | string (uri) | yes | |
instruction | string | yes | |
media_type | string | no | |
max_credits | number | no | |
plan_token | string | no | From a dry run: run exactly that priced plan. |
webhook_url | string (uri) | no | Optional https URL (public host only) that receives the final result as a signed POST. |
#Responses
| Status | Description | Body |
|---|---|---|
200 | Dry run estimate (dry_run=true) | DryRun |
202 | Accepted | Request |
400 | INVALID_INPUT (with field), URL_NOT_ALLOWED, MODEL_REQUIRED, MODEL_KIND_MISMATCH, MODEL_NOT_ALLOWED, DUPLICATE_ITEM or INVALID_RUN_TOKEN | Error |
401 | UNAUTHENTICATED (missing/invalid/revoked key) or KEY_SESSION_EXPIRED (sign in to aitopia.ai to reactivate the key) | Error |
402 | INSUFFICIENT_CREDITS, KEY_CREDIT_CAP_REACHED or OVER_BUDGET | Error |
409 | PRICE_CHANGED, PRICE_UNKNOWN or PLAN_EXPIRED | Error |
422 | PLAN_INVALID, ASSET_UNREACHABLE or NOT_SUPPORTED | Error |
429 | RATE_LIMIT, RUN_LIMITED or QUEUE_LIMIT_EXCEEDED (see retry_after_seconds and the Retry-After header) | Error |
500 | INTERNAL_ERROR (an unexpected server error) | Error |
502 | UPSTREAM_5XX, or UPSTREAM_UNCERTAIN (the run may have started: check the request_id in the body and your balance before retrying) | Error |
503 | MODEL_UNAVAILABLE, SERVER_RESTARTING or SESSION_UNAVAILABLE (retryable) | Error |
504 | TIMEOUT | Error |
#Example
curl -X POST "https://api-live.aitopia.ai/v1/edit" \
-H "Authorization: Key $AITOPIA_KEY" \
-H "Content-Type: application/json" \
-d '{"asset_url":"https://cdn.aitopia.ai/...","instruction":"remove the background, make it 9:16","max_credits":50}'{
"dry_run": true,
"endpoint": "edit_media",
"credits_estimated": 30,
"affordable": true,
"credits_available": 100,
"plan_token": "<plan token>",
"plan_token_expires_in_sec": 3600
}{
"request_id": "0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"status": "queued",
"endpoint": "edit_media",
"created_at": "2026-10-23T10:00:00.000Z",
"completed_at": null,
"credits_estimated": 30,
"output": {
"images": [],
"videos": [],
"audio": [],
"files": []
},
"status_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"result_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"cancel_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10/cancel"
}#POST /v1/batch
Submit 1 to 12 generations as one request.
Authentication: Authorization: Key <key>.
kind is image, audio or video. Each item is priced and billed like a single run of its model. Identical items need a model that takes a seed, otherwise DUPLICATE_ITEM.
#Query parameters
| Name | Type | Required | Description |
|---|---|---|---|
wait | integer (min 0, max 60) | no | Long-poll up to N seconds (integer 0-60) for a terminal status. |
dry_run | true | 1 | yes | false | 0 | no | no | true/1/yes returns a price estimate and runs nothing; false/0/no (or absent) runs. Anything else is a 400. |
#Request body
Content type application/json.
| Field | Type | Required | Description |
|---|---|---|---|
items | array of BatchItem (min 1 items, max 12 items) | yes | |
items[].kind | string | yes | |
items[].prompt | string | yes | |
items[].model_id | string | yes | |
items[].input | object | no | |
items[].asset_name | string | no | |
webhook_url | string (uri) | no | Optional https URL (public host only) that receives the final result as a signed POST. |
#Responses
| Status | Description | Body |
|---|---|---|
200 | Dry run estimate (dry_run=true) | DryRun |
202 | Accepted | Request |
400 | INVALID_INPUT (with field), URL_NOT_ALLOWED, MODEL_REQUIRED, MODEL_KIND_MISMATCH, MODEL_NOT_ALLOWED, DUPLICATE_ITEM or INVALID_RUN_TOKEN | Error |
401 | UNAUTHENTICATED (missing/invalid/revoked key) or KEY_SESSION_EXPIRED (sign in to aitopia.ai to reactivate the key) | Error |
402 | INSUFFICIENT_CREDITS, KEY_CREDIT_CAP_REACHED or OVER_BUDGET | Error |
409 | PRICE_CHANGED, PRICE_UNKNOWN or PLAN_EXPIRED | Error |
422 | PLAN_INVALID, ASSET_UNREACHABLE or NOT_SUPPORTED | Error |
429 | RATE_LIMIT, RUN_LIMITED or QUEUE_LIMIT_EXCEEDED (see retry_after_seconds and the Retry-After header) | Error |
500 | INTERNAL_ERROR (an unexpected server error) | Error |
502 | UPSTREAM_5XX, or UPSTREAM_UNCERTAIN (the run may have started: check the request_id in the body and your balance before retrying) | Error |
503 | MODEL_UNAVAILABLE, SERVER_RESTARTING or SESSION_UNAVAILABLE (retryable) | Error |
504 | TIMEOUT | Error |
#Example
curl -X POST "https://api-live.aitopia.ai/v1/batch" \
-H "Authorization: Key $AITOPIA_KEY" \
-H "Content-Type: application/json" \
-d '{"items":[{"kind":"image","prompt":"a red fox, studio light","model_id":"google/nano-banana-2"},{"kind":"image","prompt":"a red fox, forest at dawn","model_id":"google/nano-banana-2"}]}'{
"dry_run": true,
"endpoint": "generate_batch",
"credits_estimated": 8,
"affordable": true,
"credits_available": 100,
"items": [
{
"index": 0,
"kind": "image",
"model_id": "google/nano-banana-2",
"credits_estimated": 4
},
{
"index": 1,
"kind": "image",
"model_id": "google/nano-banana-2",
"credits_estimated": 4
}
]
}{
"request_id": "0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"status": "queued",
"endpoint": "generate_batch",
"created_at": "2026-10-23T10:00:00.000Z",
"completed_at": null,
"credits_estimated": 8,
"output": {
"images": [],
"videos": [],
"audio": [],
"files": []
},
"status_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"result_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10",
"cancel_url": "https://api-live.aitopia.ai/v1/requests/0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10/cancel"
}