Jobs and polling
Nothing generates inside a request. A block takes seconds and a model can take tens of minutes, so every generation endpoint answers 202 Accepted straight away with a job handle, and you poll that handle.
POST /packs/my-pack/textures → 202 { "job": "my-pack:texture:mossy_bricks", … }
GET /jobs/my-pack:texture:mossy_bricks → { "status": "generating" }
GET /jobs/my-pack:texture:mossy_bricks → { "status": "ready" }
GET /packs/my-pack/assets/texture/mossy_bricks → the PNGThree statuses, and only two are terminal:
status | Meaning |
|---|---|
| generating | Still running. Keep polling. |
| ready | Done. Fetch the file. |
| error | Failed. error says why, and the credit has been refunded. |
There's no jobs table#
Worth knowing, because it explains the handle's shape. Generation is two-phase:
the asset row is written up front with status generating and the runner fills
it in. The asset is the job record — it carries the status, the error and
the result in one place, and it outlives the run. So a handle is just an asset's
id, <pack>:<kind>:<name>, and it stays resolvable long after the generation
finished.
It also means the asset listing is how you recover a handle for something generated in an earlier run.
Polling always terminates#
A loop that waits for the status to change is safe to write.
| Image generation | Each call to the image model is given 5 minutes |
| The whole run | 20 minutes, after which it's stopped |
| Models | Much longer — up to an hour, since the builder works cube by cube |
| Backstop | A run that dies without recording anything reads as error after 25 minutes, or 45 for a model |
That last row is the one to know about. If the machinery running a generation
disappears mid-flight there's nobody left to write down that it failed, so a job
untouched past the cutoff is reported as error rather than left pending.
How often to poll
Every couple of seconds is plenty. Blocks, items and icons come back in seconds; a model takes minutes, so back off rather than hammering — there's no rate limit to hit, but there's nothing to gain either.
A full loop#
Create, generate, wait, download:
#!/usr/bin/env bash
set -euo pipefail
API=https://api.resourcepack.ai/v1
AUTH="Authorization: Bearer $RPAI_KEY"
pack=$(curl -s -X POST "$API/packs" -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"name":"Script Test"}' | jq -r .pack.slug)
job=$(curl -s -X POST "$API/packs/$pack/textures" -H "$AUTH" -H 'Content-Type: application/json' \
-d '{"prompt":"cracked obsidian with faint purple veins","mode":"vanilla","vanillaTarget":"stone","size":16}' \
| jq -r .job)
until [ "$(curl -s "$API/jobs/$job" -H "$AUTH" | jq -r .status)" != "generating" ]; do
sleep 2
done
curl -s "$API/packs/$pack/export" -H "$AUTH" -o "$pack.zip"Check the status you stopped on
That loop exits on ready or error. In real code, read the status
rather than assuming success — a failed generation refunds the credit and
leaves the asset in the pack with an error on it.