01
A seed helps compare runs, not guarantee identical pixels
Where seed exists, keep it with the prompt, model version, size and references. Some endpoints remain nondeterministic; the same seed can still produce a different image.
Image API solution
Every image endpoint declares its own fields. Some take a negative prompt, some take a seed, some return four candidates per call. A generic form hides exactly the controls that make output repeatable.

The challenge
Prompt in, image out holds for about ten seconds. Then you need the same character twice, a 3:2 crop instead of a square, four candidates per call, and a seed you can write down.
01
Where seed exists, keep it with the prompt, model version, size and references. Some endpoints remain nondeterministic; the same seed can still produce a different image.
02
Some endpoints take resolution or aspect_ratio, others take width and height in pixels. Sending the wrong one is a 400, and on endpoints priced by megapixel the size you pick is also the price you pay.
03
Where num_outputs exists, the charge follows the number of images rather than the number of requests. A default of 4 costs four times a default of 1, and the estimate is the only place that gap is visible before submission.
The approach
Build inputs from the endpoint schema. Save the exact request, ordered references and model version with the result so you can compare later variations. Keep accepted originals; regenerating them is not guaranteed.
Image tasks use the same create-and-track contract as video. The whole difference lives inside input.
POST /api/v1/jobs/createTask
POST /api/v1/jobs/createTask
Authorization: Bearer $SPICY_API_KEY
Idempotency-Key: 7b1f0c2e-9a4d-4f31-8c67-2b5e0d9a1c44
Content-Type: application/json
{
"model": "<publisher>/<model>/text-to-image",
"input": {
"prompt": "A ceramic teapot on linen, soft window light, muted palette",
"aspect_ratio": "3:2",
"num_outputs": 2,
"seed": 1337
}
}GET /api/v1/jobs/recordInfo?taskId=…
{
"code": 200,
"msg": "success",
"request_id": "req_example_record",
"data": {
"taskId": "job_01k3m8x9q2z4v7n5p6r8s0t1w3",
"state": "succeeded",
"output": {
"assets": [
{
"mime": "image/png",
"url": "https://…/result.png?X-Amz-Signature=…",
"expiresAt": "2026-09-12T12:20:08Z"
}
]
},
"cost": "0.040000",
"settled": true
}
}Contract
| Field or header | Value or limit |
|---|---|
| input | additionalProperties: false |
| seed · num_outputs · aspect_ratio | declared per endpoint |
| cost + settled: false | hold · final charge never exceeds it |
| errorCode | 9 stable values, content_rejected included |
Swipe horizontally to see all columns.
Integration
Fit
Evidence
The body you assemble on the model page is the body you send from your server: same fields, same validation, same estimate. There is no simplified preview mode that diverges later.
Input is validated against the endpoint's schema with additionalProperties closed. A parameter the model does not declare returns 400 with a stable errorCode instead of being quietly ignored.
Results come back as output.assets with a key, a MIME type, a signed url and expiresAt. Nothing hot-links to wherever the model ran.
Before launch
FAQ
Models
Each link opens that model family's own page: inputs, limits, content policy and the current price per unit.
Keep going
Compare image endpoints by accepted inputs, size and seed controls, output count and per-image price, then reuse the exact request you tested.