Skip to content

Jobs

Asynchronous work: an op, a saved preset or inline steps over a batch of assets, run as one job with a handle. Price it with a dry run, wait on it in the same call or follow it by id or webhook, cancel it, resume what failed. Credits are charged when the job settles, for what completed.

7 endpoints under /api/v1/jobs. What every call shares is on the REST overview, and what they are for — with the calls for every SDK, the CLI and MCP — on Jobs. * marks a required field.

List jobs

GET /api/v1/jobs

Paged — page and perPage, or cursor, in; meta out

Your jobs, newest first, one page at a time. Every filter is optional and they combine; a missing one filters nothing. A row carries the item counts and what ran, not items — read one job for those.

To follow a job you just submitted, read it by id — GET /api/v1/jobs/{id}?wait= holds the answer until it settles — or register a webhook. Polling this list is the slow way to watch one job.

USE THIS WHEN:

  • Finding jobs by status, type, op, preset or date — last week's failures, say
  • Reading every attempt of one job (rootJobId)

DO NOT USE WHEN:

  • You have the job's id → GET /api/v1/jobs/{id}
  • You only need how many → GET /api/v1/jobs/counts

Parameters

NameInTypeDescription
statusquerystringOnly jobs in this statusone of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED · CANCELLING
typequerystringOnly jobs of this typeone of ai-generate · ai-edit · parse · process · render · chain
presetquerystringOnly jobs that ran this preset: a slug or id for every version of it, or slug@version for the one that was pinned. A preset that is not yours, or a version that does not exist, is 404 preset_not_found. Jobs that ran inline steps or a bare op carry no preset and never match.
opquerystringOnly jobs submitted as this op — one entry of GET /api/v1/ops. A job submitted as a raw type or a preset carries no op and never matches.
rootJobIdquerystringEvery attempt of one job: the ones whose rootJobId is this — the first attempt's id, which is its own rootJobId too, so it is in the page. Ordered newest first like any other page, so the latest attempt is first.
createdFromquerystringSubmitted at or after this. Epoch millis, or an ISO-8601 date or instant read as UTC: 2026-09-14, 2026-09-14T08:30:00Z
createdToquerystringSubmitted at or before this. Same forms as createdFrom; a bare date includes the whole of that day — which is also how to freeze the window a walk by page number pages through, since jobs you submit meanwhile would shift its pages. A walk by cursor is not shifted.

Returns 200 — data is JobSummary[]

One page of rows, with meta

Errors

StatusCode and when
400

invalid_param on createdFrom / createdTo — neither epoch milliseconds nor an ISO-8601 date or instant

404

preset_not_found — the preset filter names no preset of yours, or no such version of it

Submit a new job

POST /api/v1/jobs

Accepts an Idempotency-Key

Submits an async job. Name the work with op — one entry of GET /api/v1/ops — and the service derives the rest. Price it first: the same request with ?dryRun=true creates nothing.

op is the vocabulary:

  • {"op": "remove_bg", "assetIds": ["ast_…"]}
  • {"op": "resize", "assetIds": ["ast_…"], "parameters": {"width": 1200}}
  • {"op": "generate", "prompt": "a red bicycle on white", "count": 2}
  • {"op": "render_template", "templateId": "builtin-template-og-image", "items": [{"title": "Hello"}]}

A parameter outside the op's contract is 400 invalid_param naming it, before any credit is touched.

presetId runs a saved preset (GET /api/v1/presets) by slug or id, or slug@version to pin one version. The preset decides the job type; model / prompt / parameters override its ONE AI step — a preset with no AI step, or with several, refuses them (400 invalid_param naming the field). steps runs the same list of steps inline, once, without saving a preset (op, presetId and the overrides are refused beside it — put them on the step). assetIds batches: one item per asset. Several segments — an AI step beside other steps, or two of them — run as one chain job, each item walking the segments in order; the dry run breaks its price down per segment (steps[]). type (its values are the enum on the request schema) is what an op or a preset translates into; send it only without op.

The response is the job: follow it with GET /api/v1/jobs/{id} or a job.* webhook. Nothing is charged at submit — the credits of an AI job are taken when it settles, for the items that completed. A deterministic job counts its items against the period's processing allowance instead.

wait (seconds, at most 60; a larger value is clamped) holds the response until a ONE-item job is terminal: 200 with the finished job and its outputs, or 202 with the same job when the window closes first — then GET /api/v1/jobs/{id}?wait= waits again. One call, one result, and still a job: it is charged for what completes, retried and replayable exactly as without it. On a batch wait is ignored and the answer is the 201 at once.

The dry run is a validation pass. It answers every 400 and 404 a submit would, but never refuses for money or quota (402 insufficient_credit, 422 asset_count_exceeded): what the account cannot afford comes back as data instead — sufficientCredit, assetCountLeft, processCountLeft, and what runs past the allowance would cost (overageRuns, overageCredits). Images not stored yet are priced by how many: imageCount on a dry run stands for that many more assetIds — the price depends on the op, model, parameters and count, never on the pixels — and the submit after the upload names them.

Past the processing allowance a deterministic job (a pass over assets, a render, a chain's passes) is not refused: each run past it is paid from your balance at the plan's overageCredits (GET /api/v1/ops), held with the job and charged for the runs it hands out. Only a balance that cannot cover them refuses the submit — 402 insufficient_credit, like an AI job.

USE THIS WHEN:

  • Running an AI op, a batch, or anything you want an asset_id back for
  • Pricing a run before paying for it (?dryRun=true)

DO NOT USE WHEN:

  • One image you already hold and a deterministic op → POST /api/v1/images/transform (bytes in, bytes out)
  • Reading an image's metadata → POST /api/v1/images/metadata, or GET /api/v1/assets/{id} for a stored one

Parameters

NameInTypeDescription
dryRunquerybooleanPrice the job and return the estimate without creating it or spending anything. Accepts dryRun and dry_run. A dry run ignores Idempotency-Key, so the submit after it can carry the same one.
dry_runquerybooleandryRun spelled snake_case; either one set to true is a dry run.

Request body — JobRequest

Returns

StatusBodyWhen
200data is JobEstimate or Job

?dryRun=true: what the job would cost, nothing was created — or, with wait, the job, terminal inside the window (a FAILED job is terminal too: read status).

201data is Job

The job, created — PENDING or PROCESSING. Also the answer to a wait on a batch, which is ignored.

202data is Job

wait was given and the job is still running when the window closed: the same job document, not yet terminal. Wait again with GET /api/v1/jobs/{id}?wait=.

Errors

StatusCode and when
400
  • invalid_param on the field at fault, before any credit is touched: an unknown op or one that is not a job, a parameter outside the op's contract (parameters.<name>), a model that does not run the op (details.allowed lists those that do), a step that cannot run (steps[i]…), something sent beside steps (or subjects without it), an override a preset has no one step for, a blank id in assetIds (details.index), a collection name that breaks its rules, count outside 1–10, more assetIds / variants / items than a job takes, imageCount without dryRun or on a render, or the removed mode
  • invalid_state — an overlay's layer asset has not finished uploading
402

insufficient_credit — the balance does not cover the estimate. Only an AI job spends credits; the dry run says sufficientCredit: false instead.

404
  • asset_not_found on assetIds — an id that is not one of your assets; details.missing lists every one
  • preset_not_found — no such preset of yours, or no such version of it
  • not_found — the templateId of a render, or an overlay's layer asset, does not exist
422

asset_count_exceeded — the items would take the account past its plan's stored-asset ceiling; the dry run reports assetCountLeft.

Count jobs by status and type

GET /api/v1/jobs/counts

How many of your jobs are in each status and of each type, as one table: a row per status and type that has any, with its count. Takes the filters GET /api/v1/jobs takes, except status and type — those are the table's two dimensions — and every cell is the meta.total that listing would report for that status and type.

To count by status alone, sum the rows for each status; to count the statuses within one type, keep that type's rows first.

USE THIS WHEN:

  • Checking how many jobs failed, or are still running, without paging through them
  • Showing a count beside each status or type filter

DO NOT USE WHEN:

  • You need the jobs themselves → use GET /api/v1/jobs
  • You need credits spent → use GET /api/v1/usage

Parameters

NameInTypeDescription
presetquerystringOnly jobs that ran this preset, as on GET /api/v1/jobs: a slug or id for every version of it, or slug@version. A preset that is not yours is 404 preset_not_found.
opquerystringOnly jobs submitted as this op — one entry of GET /api/v1/ops.
rootJobIdquerystringOnly the attempts of one job: the ones whose rootJobId is this — the first attempt's id, the first attempt included.
createdFromquerystringSubmitted at or after this. Epoch millis, or an ISO-8601 date or instant read as UTC.
createdToquerystringSubmitted at or before this. Same forms as createdFrom; a bare date includes the whole of that day.

Returns 200 — data is JobCount[]

The non-zero cells; an empty list when nothing matches

Errors

StatusCode and when
400

invalid_param on createdFrom / createdTo — neither epoch milliseconds nor an ISO-8601 date or instant

404

preset_not_found — the preset filter names no preset of yours, or no such version of it

Get a job

GET /api/v1/jobs/{id}

One job as it stands: its status, the item counts, what ran (op, preset and version, model, steps) and, per item, the output — resultAssetId, or output for an analyze — or, for a failed item, errorCode and retryable. The first 100 items ride inline and itemsTruncated says when there are more (GET /api/v1/jobs/{id}/items pages the rest). actualCredits is what the job was charged; it is set when the job settles.

wait turns the read into a long-poll: the answer is held until the job is terminal or the window closes, and the job as it stands comes back either way — read status. It is how a 202 from a waited submit is picked up.

A job record lives as long as the assets it made: at expiresAt it is swept, and a read after that is 404.

USE THIS WHEN:

  • Reading what a job produced, or why an item failed
  • Waiting for a job to finish without writing a poll loop (?wait=)

DO NOT USE WHEN:

  • Listing jobs → use GET /api/v1/jobs
  • You only want the assets it made → GET /api/v1/assets?jobId={id}

Parameters

NameInTypeDescription
id (required)pathstringThe job's id, job_…
waitqueryinteger (int32)Long-poll: hold the response until the job is terminal, for at most this many seconds (at most 60; a larger value is clamped). The job as it stands comes back either way — read status. Any job, batches included. More than 8 waits open on one account is 429 rate_limited (details.reason account_concurrency) with Retry-After; a full node is 503 provider_unavailable. Both are retryable.

Returns 200 — data is Job

The job — terminal or not; read status

Errors

StatusCode and when
404

job_not_found — no such job, or it is not yours, or its record has expired

503

provider_unavailable, details.reason capacity — this node holds as many waits as it will; retry after Retry-After, or read without wait

Cancel a job

POST /api/v1/jobs/{id}/cancel

Accepts an Idempotency-Key

Stops a PENDING or PROCESSING job. Items not yet handed to a provider or a worker are cancelled and never charged; items already running finish, and are charged for what they complete — nothing is taken at submit, so there is nothing to refund. The answer is the job: CANCELLED when nothing was in flight, else CANCELLING until the running items settle, and then CANCELLED. A chain item lets the segment in flight finish and starts no further one.

The job settles as CANCELLED and a job.failed event goes out. What it did make is kept; a resume retries the cancelled items.

USE THIS WHEN:

  • Stopping a running or queued job you no longer want

DO NOT USE WHEN:

  • The job is already terminal (COMPLETED, FAILED, CANCELLED) or CANCELLING → 400 invalid_state

Parameters

NameInTypeDescription
id (required)pathstringThe job's id, job_…

Returns 200 — data is Job

The job — CANCELLING or CANCELLED

Errors

StatusCode and when
400

invalid_state — there is nothing left to cancel: the job is already terminal or CANCELLING; details.status says which

404

job_not_found — no such job, or it is not yours

List a job's items

GET /api/v1/jobs/{id}/items

Paged — page and perPage, or cursor, in; meta out

One page of a job's items, in item order (index, from 0) — the number the rest of the API names an item by, in events and in a resume.

GET /api/v1/jobs/{id} carries the first 100 items inline and sets itemsTruncated when there are more; this is how to read the rest. A batch takes up to 10000 assets, each times its variants, so the whole list is not something to hold in a context or re-read on every poll.

USE THIS WHEN:

  • A job says itemsTruncated and you need an item past the first page
  • You want only the failed ones, to decide whether a resume is worth its price (status=FAILED)

DO NOT USE WHEN:

  • You want the assets the job produced → GET /api/v1/assets?jobId={id}, which is the run's products without the items around them

Parameters

NameInTypeDescription
id (required)pathstringThe job's id, job_…
statusquerystringOnly items in this statusone of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED

Returns 200 — data is JobItem[]

One page of items, with meta

Errors

StatusCode and when
404

job_not_found — no such job, or it is not yours

Resume incomplete items in a job

POST /api/v1/jobs/{id}/resume

Accepts an Idempotency-Key

Retries what did not finish: a new job over the FAILED and CANCELLED items of a FAILED or CANCELLED job, with the original's configuration — the same op, model, prompt and parameters, the same preset at the version the original ran, or the same inline steps and subjects. Only the incomplete items are retried (a variant set may repeat a few that had completed — deterministic work, priced like any other run).

  • The new job is an ordinary submit: it is priced, checked and charged like one, so it can be refused like one (402, 422).
  • A chain item restarts on the segment it failed on (failedStep), from the image the last segment it finished made; the segments it already paid for are not paid again.
  • A source asset deleted since the original ran drops its item from the retry; when none is left the answer is 404 asset_not_found.
  • The new job points back with parentJobId, carries rootJobId — the first attempt's id, the same on every resume and on the first attempt itself — and advances attemptNumber by 1; GET /api/v1/jobs?rootJobId= lists every attempt. Only the latest attempt can be resumed, and only a few times (details.job.maxResumes).

Whether a resume can help at all is on the job: retryable: true means at least one failed item failed for a reason that may pass.

USE THIS WHEN:

  • Retrying only the failed items of a partially-successful job without resubmitting the whole batch

DO NOT USE WHEN:

  • Submitting a fresh job → use POST /api/v1/jobs
  • Every failed item says retryable: false — the same input fails the same way

Parameters

NameInTypeDescription
id (required)pathstringThe id of the job to retry, job_…

Returns 201 — data is Job

The new attempt, created

Errors

StatusCode and when
400

invalid_state — the job is not FAILED or CANCELLED, or it has no FAILED or CANCELLED item to retry

402

insufficient_credit — the balance does not cover the retried AI items

404
  • job_not_found — no such job, or it is not yours
  • asset_not_found on assetIds — none of the incomplete items still has its source asset (or, for a chain, the image it would restart from); details.missing lists them
422
  • job_not_resumable — details.reason is NOT_LATEST_ATTEMPT (resume the newest attempt of this rootJobId instead) or RESUME_LIMIT_EXCEEDED (details.job.maxResumes reached)
  • asset_count_exceeded — the retry would pass the plan's stored-asset ceiling

Objects

Each described once; a linked type is another object on this page.

Job

FieldTypeDescription
actualCreditsinteger (int64)
Credits charged: set when the job settles, for the work that completed; 0 until then, and for deterministic work, which spends none
attemptNumberinteger (int32)
1 for a fresh job, one more for each resume
cancelledItemsinteger (int32)
Items cancelled before they ran
collectionstring
The collection the outputs go in, as the request named it; absent when it named none (an output made from an asset then lands in that asset's collection)
completedAtstring (date-time)
When it reached a terminal status
completedItemsinteger (int32)
Items that completed
createdAtstring (date-time)
When it was submitted
errorCodestring
The verdict on the failed items, from the closed set of error codes: a retryable item's code when any is retryable, else the first failed item's. Absent when nothing failed, or no failure was classified
errorMessagestring
On a job with failed items, one line for a person ("2 of 3 items failed"); each item carries its own error
expiresAtstring (date-time)
When the record is swept — the plan's retention window at submit, the same as the assets it made. Never shortened by a downgrade
failedItemsinteger (int32)
Items that failed — each says why, and whether a resume could help
idstring
The job's id, job_…
itemsJobItem[]
The items, in order: the first 100 of them. itemsTruncated says when there are more — GET /api/v1/jobs/{id}/items pages the rest
itemsTruncatedboolean
True when items is only the first page of them; absent otherwise
modelstring
The model the job calls; absent for deterministic work, and on a chain, whose segments name their own
opstring
The op it was submitted as, when it was submitted as one — what usage groups by
parametersobject
What the job runs with: an AI op's model parameters, analyze's schema and maxOutputTokens, or a render's data rows under items
parentJobIdstring
The attempt this one resumed; absent on a first attempt
pipelinesJobPipeline[]
A deterministic job's pipeline as stored at submit — one per variant, named after it — with each layer named by the asset id you gave
presetIdstring
The preset it ran, by id; absent for an op, inline steps or a render
presetNamestring
The preset's name; op:<name> for an op, Ad-hoc for a bare type and model; absent for a render
presetVersioninteger (int32)
The version of the preset it ran — a later edit of the preset never changes it
promptstring
The prompt the model receives, every {{subject.<name>}} already expanded
referencesstring[]
The reference images sent with every model call — the subjects' images, resolved at submit
retryableboolean
Whether a resume could help: true when at least one failed item failed for a reason that may pass. Absent with errorCode
rootJobIdstring
The first attempt's id — the job's own on a first attempt, and the same on every resume of it, so GET /api/v1/jobs?rootJobId= lists every attempt
segmentsJobSegment[]
chain only: the segments each item walks, in order, frozen at submit with what each costs per item
settledItemsinteger (int32)
Items that reached an end — completed, failed or cancelled
statusstring
PENDING waits for a slot (an account runs a few jobs of one type at a time; the rest queue), PROCESSING is running and CANCELLING is a cancel waiting for items already running. Then one of the terminal three: COMPLETED (no item failed), FAILED (at least one did — read the items) or CANCELLED.one of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED · CANCELLING
stepCountinteger (int32)
How many inline steps the job ran; absent for an op or a preset job
stepsPresetStep[]
The inline steps it was submitted with, as written; absent for an op or a preset job
subjectsSubject[]
The subjects sent with inline steps, as checked
submittedAtstring (date-time)
When it left the queue and started running
submittedItemsinteger (int32)
Items handed to a provider or worker so far
templateIdstring
render only: the template, by id
templateNamestring
render only: the template's name
templateVersioninteger (int32)
render only: the version of the template it rendered
totalItemsinteger (int32)
How many items the job has — one per asset (times the variants), per image to generate, or per render row
typestring
What the job runs as — decided by the op, preset or steps it was submitted withone of ai-generate · ai-edit · parse · process · render · chain

JobCount

How many of your jobs are in one status and of one type. Only non-zero cells are listed.

FieldTypeDescription
countinteger (int64)
Jobs in this status and of this type, under the request's filters
statusstring
The cell's statusone of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED · CANCELLING
typestring
The cell's job typeone of ai-generate · ai-edit · parse · process · render · chain

JobEstimate

Cost estimate for a job that has not been created

FieldTypeDescription
assetCountLeftinteger (int64)
How many more assets the account can hold: the plan's stored-asset ceiling minus the assets it stores now (a chain's intermediates and failed uploads do not count). Deleting assets frees room; below zero after a downgrade. More items than this and a submit is 422 asset_count_exceeded.e.g. 188
costPerIteminteger (int64)
Credits per item (1 credit = $0.0001)e.g. 390
creditBalanceinteger (int64)
The account's credit balance right nowe.g. 50000
estimatedCreditsinteger (int64)
totalItems × costPerIteme.g. 4680
maxInputEdgeinteger (int32)
The longest edge, in pixels, of the image the model will be handed: a larger input is turned upright, scaled down to it and re-encoded as WebP with no metadata first. AI jobs that send an image only; a chain states it per step.e.g. 2048
modelstring
Model that would rune.g. "google/gemini-3.1-flash-image-preview"
overageCreditsinteger (int64)
What overageRuns cost, in credits — already in estimatedCredits. Absent for AI jobs.e.g. 0
overageRunsinteger (int32)
Of this job's deterministic runs, how many fall past the plan's allowance and are paid from your balance instead of refused. 0 when they all fit; absent for AI jobs.e.g. 0
presetIdstring
Preset the request resolved to, when it named one
presetNamestring
Preset name; op:<name> for an op with no preset, 'Ad-hoc' for a bare type + model
presetVersioninteger (int32)
The version of that preset the job would run — the one slug@version pinned, or the current onee.g. 3
processCountLeftinteger (int64)
Deterministic-op quota left this period (process / render items), never below zero; -1 when the plan sets no ceiling. Runs your running jobs have claimed are already taken out. Runs past it are paid from your balance — overageRuns · overageCredits. Absent for AI jobs, which are priced in credits.e.g. 190
processPerIteminteger (int32)
chain only: how many process passes each item runs — one per deterministic segment. totalItems × processPerItem is what the job takes out of the period's deterministic-op quota. Every other type runs one pass per item.e.g. 2
promptstring
The prompt the model would receive, with every {{subject.<name>}} already expanded to that subject's locked descriptor. Check it here rather than discovering a mis-typed placeholder in the pictures. AI jobs only.
stepsStepEstimate[]
chain only: what each segment costs, in order, so the total can be added up rather than trusted. Their costPerItem sums to the job's.
sufficientCreditboolean
Whether a submit would be admitted: the balance, plus the one top-up an enabled auto top-up may overdraw, less what your running jobs already hold, covers the estimate. False does NOT mean the request is invalid — it means submitting it now would return insufficient_credit.
templateIdstring
render only: the template the call named, by ide.g. "builtin-template-og-image"
templateNamestring
render only: that template's namee.g. "OG image"
templateVersioninteger (int32)
render only: the version of the template the job would render — the one id@version pinned, or the current onee.g. 1
totalItemsinteger (int32)
Number of items the job would havee.g. 12
typestring
Job type the request resolves toe.g. "ai-generate"
warningsStepWarning[]
What the steps say that is legal, will run, and is probably not what was meant — a shadowed output format, a step the one before it already did. Advisory: a warning never stops a submit, and an empty list is left out. What cannot run at all is a 400 invalid_param here instead, naming the step. Present when the request named a preset or sent inline steps.

JobItem

One unit of a job — an asset, an image to generate or a render row — and its whole trace: what it made, what it cost, how long it took, and why it failed

FieldTypeDescription
creditsinteger (int64)
What this item cost, in credits; 0 for deterministic work. The items' credits add up to the job's actualCredits
currentAssetIdstring
chain only: the image its next segment reads — the source, then each segment's product
durationMsinteger (int64)
finishedAt − startedAt, in milliseconds
errorstring
A failed item: why, in one sentence for a person
errorCodestring
A failed item: the code to branch on, from the closed set of error codes. Absent when the failure was not classified — treat that as not retryable
failedStepinteger (int32)
chain only: the segment a failed item failed on, from 0 — where a resume restarts it
finishedAtstring (date-time)
When it settled
indexinteger (int32)
The item's position in the job, from 0 — how events, the item pages and a resume name it
intermediateAssetIdsstring[]
chain only: the images earlier segments made to feed the next; deleted when the item settles, except the last one a failed item restarts from
modelstring
AI items: the model it ran on
outputobject
analyze only: the answer, in the default schema's shape or your parameters.schema
presetVersioninteger (int32)
The preset version it ran — the job's, repeated so one item explains itself
providerstring
AI items: the upstream that ran ite.g. "fal"
resultAssetIdstring
The asset it made, once COMPLETED; absent for analyze, whose product is output
retryableboolean
A failed item: whether a resume could succeed — the code's own flag
sourceAssetIdstring
The asset it runs on; absent for an image generated from a prompt or a render row
startedAtstring (date-time)
When a worker picked it up
statusstring
Where the item isone of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED
stepinteger (int32)
chain only: the segment the item is on, from 0
templateVersioninteger (int32)
A render item's template version — the job's, repeated
timingsobject
AI items: where the time went, in milliseconds — inputMs (making the image the model is handed), providerMs (the provider call), storeMs (fetching and storing the result). Exclusive of one another, summed over retries
variantstring
The variant that made it; absent outside a variant set

JobPipeline

One pass a deterministic job runs: a name — the variant's, when there is a set of them — and its registry steps

FieldTypeDescription
namestring
The variant's name, or op:<name> for a single op
stepsPipelineStep[]
The registry steps, in order

JobRequest

What to run and on what: one of op, presetId or steps (or a raw type), the inputs, and where the outputs go. The same body prices it with ?dryRun=true.

FieldTypeDescription
assetIdsstring[]
Your assets to run on — one item per id, times the variants. Required unless the op reads no image (requiresAssets: false in GET /api/v1/ops) or the job is a render. Every id must be yours: one that is not is 404 asset_not_found, before anything is created.
collectionstring
Collection to put the output assets in (optional; at most 200 characters, and names starting with job: are reserved). Without one, an output made from an asset is in that asset's collection.e.g. "shoot-01"
countinteger (int32)
A job with no assetIds that makes images from a prompt: how many to make, one item each. 1 when absent.e.g. 1
imageCountinteger (int32)
Dry run only (?dryRun=true): images you have not stored yet, priced as that many more assetIds — one item each, times the variants — so the price can be asked before anything is uploaded. Beside assetIds it adds to them, and those are still checked. A submit needs the images themselves as assetIds: without dryRun, or on a job that reads no image (a render), it is 400 invalid_param. At most 10000 together with assetIds.e.g. 20
itemsobject[]
render_template: one object of template variables per output image (≤ 500). May also be given as parameters.items.e.g. [{"site":"imagestep.dev","title":"Hello"}]
modelstring
The model an AI op runs on — an id from GET /api/v1/ai-models whose categories include the op's modelCategory; any other is 400 invalid_param with the ones that fit in details.allowed. Absent, the op's defaultModel. With a preset it overrides the preset's one AI step.
opstring
An op name — one entry of GET /api/v1/ops, the catalogue every client enumerates. When set, type / presetId / preset are derived from it and parameters carries the op's parameters; the dry run prices it like any job.e.g. "remove_bg"
parametersobject
The op's parameters. A deterministic op's are checked against its params in GET /api/v1/ops, and one outside them is 400 invalid_param naming it; an AI op's go to its model (parameters in GET /api/v1/ai-models). With a preset they replace its one AI step's parameters.
presetPipelineData
A raw processing pipeline — registry steps, run as one pass. What an op translates into; prefer op, or steps for several.
presetIdstring
A saved preset to run: its slug or id, or slug@version / id@version to pin one version (GET /api/v1/presets). The preset decides the job type; model / prompt / parameters override its ONE AI step, and are refused by a preset that has none or several.e.g. "builtin-util-web-optimize"
promptstring
The prompt of an AI op that takes one — required where the op's entry says requiresPrompt. With a preset it overrides the one AI step's prompt, and {{subject.<name>}} in it expands to that subject's descriptor.
retentionDaysinteger (int32)
Keep the assets this job makes — and its own record — for this many days instead of your plan's retention: shorter only. More than the plan keeps is kept for the plan's time, not refused; the assets' expiresAt says what was stamped. Absent: the plan's retention.e.g. 7
stepsPresetStep[]
An inline chain: the same steps a preset stores (each {op, model?, prompt?, parameters?} or {operation, params}), checked as a preset's are and run once without saving one. Sent instead of op or presetId; model, prompt and parameters go on the step. The job records them.
subjectsSubject[]
With steps only: the subjects a preset stores — reference images plus the locked words, applied to every generate / edit step, with {{subject.<name>}} in a prompt expanding to the descriptor. Checked as a preset's are (your own DONE assets, at most 4 subjects, and a generate or edit step to read them). The job records them.
templateIdstring
render_template: the template to render — an id, or id@version to pin one version. May also be given as parameters.templateId.e.g. "builtin-template-og-image"
typestring
Job type. chain is what several segments run as — a preset's or inline steps — and is derived from them; asked for on its own it is refused.one of ai-generate · ai-edit · parse · process · render · chain
variantsobject[]
Run the op once per entry, producing one asset each — the whole set of social sizes from one call. Each entry is {name, parameters}; the parameters are merged over the top-level ones, and each name must be distinct (it is added to the output's name). Deterministic ops only — beside an AI op, render_template or a preset it is 400 invalid_param; at most 20.
waitinteger (int32)
Hold the response until the job is terminal, for at most this many seconds — capped at 60 (a larger value is clamped, not refused). A job of ONE item only; on a batch it is ignored and the handle comes back at once. Terminal inside the window → 200 with the finished job; still running → 202 with the same handle, and GET /api/v1/jobs/{id}?wait= waits again. Ignored on a dry run.e.g. 30

JobSegment

One segment of a chain: a deterministic pass or one AI step, and what it costs per item

FieldTypeDescription
boundboolean
True when the model bills by the size of the image it is sent: costPerItem was priced at the largest image it is ever sent, and it is the charge whatever the size of an item's own
costPerIteminteger (int64)
Credits one item costs on this segment, frozen at submit; 0 for a deterministic one
modelstring
An AI segment's model
opstring
The op the segment runs; absent for a pass built from registry steps only
parametersobject
An AI segment's parameters
pipelinePipelineStep[]
A deterministic segment's steps, as one pass
promptstring
An AI segment's prompt, every {{subject.<name>}} expanded
typestring
What the segment runs as: a deterministic pass, or an AI op's job typeone of ai-generate · ai-edit · parse · process

JobSummary

One row of GET /api/v1/jobs: the job's own fields, as on Job — what ran, how far it got, what it cost — without items, steps, subjects, pipelines, segments, parameters, prompt, references or collection. Read the job by id for those.

FieldTypeDescription
actualCreditsinteger (int64)
apiKeyIdstring
The API key that submitted it; absent for a signed-in console session
attemptNumberinteger (int32)
cancelledItemsinteger (int32)
completedAtstring (date-time)
completedItemsinteger (int32)
costPerIteminteger (int64)
Credits one item is priced at — what the job was quoted; 0 for deterministic work, and on a chain the sum of its segments
createdAtstring (date-time)
errorCodestring
errorMessagestring
expiresAtstring (date-time)
failedItemsinteger (int32)
idstring
modelstring
opstring
parentJobIdstring
presetIdstring
presetNamestring
presetVersioninteger (int32)
retryableboolean
rootJobIdstring
settledItemsinteger (int32)
statusstring
one of PENDING · PROCESSING · COMPLETED · FAILED · CANCELLED · CANCELLING
stepCountinteger (int32)
submittedAtstring (date-time)
submittedItemsinteger (int32)
templateIdstring
templateNamestring
templateVersioninteger (int32)
totalItemsinteger (int32)
typestring
one of ai-generate · ai-edit · parse · process · render · chain

PipelineData

An inline processing pipeline: a name and the registry steps a process job runs.

FieldTypeDescription
namestring
pipelinePipelineStep[]

PipelineStep

FieldTypeDescription
disabledboolean
operationstring
paramsany

PresetStep

A preset step: either an L1 op from GET /api/v1/ops — {op, model?, prompt?, parameters?} — or a processing-registry step — {operation, params} — for what no op covers. Never both.

FieldTypeDescription
modelstring
AI steps: the model; the op's default when absent.
opstring
An op from GET /api/v1/ops (kind ai or deterministic).e.g. "resize"
operationstring
A processing-registry key (deterministic only), for steps no op covers.e.g. "sharpen"
parametersobject
The op's parameters. A deterministic op's are checked against its catalogue contract when the steps are written, and so are analyze's bounds; an AI image op's go to the model as sent.
paramsany
That registry step's arguments.
promptstring
AI steps: the prompt. {{subject.<name>}} expands to that subject's descriptor.

StepEstimate

One segment of a chain job's cost

FieldTypeDescription
boundboolean
True when this segment's model is priced by the size of the image it is sent: costPerItem is set at the largest image that model is ever sent (maxInputEdge), and it is what every item is charged, whatever the size of its own image. Absent means the price does not depend on the image.
costPerIteminteger (int64)
Credits one item costs on this segment; 0 for a process segmente.g. 390
indexinteger (int32)
Segment index, 0-basede.g. 0
maxInputEdgeinteger (int32)
The longest edge, in pixels, of the image this segment's model is handed; absent for a process segmente.g. 2048
modelstring
The model this segment would call; absent for a process segment
opstring
What the segment runs: process for a pipeline pass, else the AI op's namee.g. "remove_bg"

StepWarning

An advisory finding about a list of steps: legal, and probably not what was meant

FieldTypeDescription
codestring
Machine-readable finding code from a closed set; the table is /docs/presets#warningse.g. "format_shadowed"
messagestring
The finding in one sentence, naming the steps by indexe.g. "steps[1] writes jpeg and steps[3] writes webp; a process segment writes one image, in the format of its last format step, so steps[1]'s format is not written"
stepsinteger (int32)[]
The step indexes the finding is about, in order — the redundant one firste.g. [1,3]

Subject

A recurring character, product or location: reference images plus the locked words for it.

FieldTypeDescription
descriptorstring
The locked description — colour, material, markings — at most 300 characters. Text pins what an image cannot show.
namestring
Lowercase handle ([a-z0-9][a-z0-9_-]{0,39}, unique among the subjects), referenced in a prompt as {{subject.<name>}}.e.g. "hero"
referenceAssetIdsstring[]
Your own DONE asset ids showing this subject. They pin the geometry.