API

Requests & lifecycle

Submit, follow and cancel requests; statuses and the result object.

Every generation is a request. You create one with a submit call, then follow it by its request_id until it reaches a final status.

#Submit endpoints

EndpointRunsBody
POST /v1/models/{model_id}one modelthe model's input fields (see GET /v1/models/{model_id}), plus optional webhook_url and asset_name
POST /v1/editan edit of an existing fileasset_url, instruction, optional media_type, max_credits, plan_token, webhook_url
POST /v1/batch1 to 12 independent generationsitems[], optional webhook_url

All three accept the query parameters ?dry_run=true (price estimate only, see Billing) and ?wait=N (long-poll, see Polling).

Input is validated with the same schema the AITOPIA app and MCP server use. A wrong value answers 400 INVALID_INPUT with the offending field in error.field (for example max_credits or items[1].model_id), and nothing runs.

A successful submit answers 202 Accepted with the request object. The request usually starts as queued; a run that finished during the call is returned already completed (still with status code 202).

#The request object

GET /v1/requests/{request_id}, the submit answer and the webhook body all use the same object:

FieldTypeDescription
request_idstringId of the request (a UUID).
statusstringqueued, running, completed, partial, failed or cancelled.
endpointstringThe model id, or edit_media / generate_batch.
created_atstringISO 8601 time of the submit.
completed_atstring or nullWhen the request reached a final status.
credits_estimatednumber or nullEstimated credits of the request (see Billing).
outputobjectGenerated files: images[], videos[], audio[], files[].
itemsarrayBatch requests only: one entry per item (index, status, output, error, credits_estimated).
errorobjectWhy a request failed (code, message, retryable, ...).
aitopia_urlstringWhen present, opens the result in the AITOPIA app.
status_urlstringURL to GET for status and result.
result_urlstringSame URL as status_url.
cancel_urlstringURL to POST to cancel.

#Output

Files are grouped by kind. Each image is { url, content_type, width?, height? }, each video { url, content_type, duration? }, each audio file { url, content_type }. Fields marked ? are given only when known: the sandbox's sample files always carry them, live results often do not, so do not rely on them. A file whose type cannot be determined is listed in files[] with content_type: null.

JSON
"output": {
  "images": [],
  "videos": [{ "url": "https://cdn.aitopia.ai/...", "content_type": "video/mp4" }],
  "audio": [],
  "files": []
}

For a batch, output lists the finished files of every item, and items[] shows them per item.

#Statuses

StatusFinalMeaning
queuednoAccepted; the run has not been seen running yet.
runningnoThe run is in progress.
completedyesFinished; files are in output.
partialyesFinished with only part of the work done. A batch where some items failed (each failed item has its own error), or an edit where a step failed after earlier steps finished (the finished steps' files are kept).
failedyesNothing usable was produced; see error.
cancelledyesCancelled before it finished.

Once a request is final it does not change again, and it is served from storage for 30 days (retention).

#Open requests with an error

A queued or running request can carry an error with retryable: true. It is not a failure: it says why the last status check did not get through, and the request stays open and is checked again.

CodeMeaning
STATUS_CHECK_FAILEDThe run status could not be checked just now.
RUN_STALEThe run has not finished yet; it is checked until 24 hours after submit.
KEY_SESSION_EXPIREDThe key's aitopia.ai session ended; the run is still tracked and its result appears once the key works again (details).

A request still open 24 hours after submit is given up on; only then is a failed status check stored as failed.

#Submit failures

If a submit is refused (invalid input, not enough credits, unknown model, ...), you get an error status and an error body. When the request was already recorded before the refusal, the body also carries its request_id:

JSON
{
  "error": { "code": "INSUFFICIENT_CREDITS", "message": "Not enough credits.", "retryable": false },
  "request_id": "0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10"
}

502 UPSTREAM_UNCERTAIN means the run may have started (and may be charged). Check GET /v1/requests/{request_id} and your balance before you submit again.

#Model runs

POST /v1/models/{model_id} takes the model input as the JSON body. Two extra fields are read by AITOPIA and not passed to the model:

  • webhook_url: see Webhooks.
  • asset_name: a name for the generated file (string).

An unknown model id answers 404 MODEL_NOT_FOUND, with close matches in error.suggestions (id, name, type).

#Edits

POST /v1/edit edits an existing file from an instruction written in plain language ("remove the background, make it 9:16"). AITOPIA plans the steps (models, store agents or media tools) and runs them in order.

FieldRequiredDescription
asset_urlyesURL of the image, video or audio file to edit.
instructionyes1 to 1000 characters, any language.
media_typenoimage, video or audio. Omit it to read the type from the file.
max_creditsnoNumber ≥ 0. A plan that costs more is refused with 402 OVER_BUDGET.
plan_tokennoFrom a dry run: runs exactly the plan that was priced (once, within 1 hour).
webhook_urlnoSee Webhooks.

Planning, dry runs included, is limited to 10 per minute and 100 per day. Each step is billed like the tool it runs.

#Batches

POST /v1/batch submits 1 to 12 independent generations as one request:

JSON
{
  "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" }
  ]
}
Item fieldRequiredDescription
kindyesimage, audio or video.
promptyesNon-empty prompt.
model_idyesModel to run; items may use different models.
inputnoExtra model fields (for example aspect ratio, duration, image URL; see the model's input_schema).
asset_namenoName of the generated file.

Each item follows the rules and price of a single run of its model. Identical items need a model that takes a seed, otherwise the batch is refused with DUPLICATE_ITEM: vary the prompts. The request is completed when every item completed, failed when every item failed and partial otherwise.

#Cancelling

Shell
curl -X POST "https://api-live.aitopia.ai/v1/requests/$REQUEST_ID/cancel" \
  -H "Authorization: Key $AITOPIA_KEY"
JSON
{ "request_id": "0d6f3c1e-5b7a-4c2e-9d1f-2a8b6e4c9f10", "cancel": "cancelled" }
cancelMeaning
cancelledEvery pending run was cancelled. The request is now cancelled (or partial for a batch whose finished items are kept).
cancellation_requestedCancellation was accepted for at least one run but not confirmed for all. Keep polling.
cannot_cancelThe run cannot be cancelled. will_be_charged (when present) says whether it will still be billed.
already_terminalThe request had already finished.

Only model runs can be cancelled. Edits and other background media runs answer cannot_cancel. If the cancel service cannot be reached, the answer is 502 UPSTREAM_5XX with retryable: true.

#Known limitation

Edits and some batch items run as background jobs on AITOPIA servers. A server restart can interrupt them; the request then fails with a code such as RUN_INTERRUPTED.

AITOPIA REST API · Live https://api-live.aitopia.ai/v1 · Sandbox https://api-sandbox.aitopia.ai/v1