Jobs & images
Generation is asynchronous. Submit, poll, then download. Jobs are stored in memory and evicted beyond the 12 most recent.
- Pull-based
GET /jobs/:id performs the upstream poll and returns the freshest state.
- In-memory
The job store lives in memory; restarting the server wipes jobs.
- Capped
Oldest jobs are evicted beyond the 12 most recent.
- Proxied
Output URLs are served through the API, upstream presigned URLs stay hidden.
{
"id": "3f2a...",
"status": "done", // queued | done | failed | cancelled
"model": "gpt-image-2.5-flare",
"prompt": "a red fox in snow",
"createdAt": 1739000000000, // epoch ms
"latencyMs": 12300, // null while queued
"progress": 100, // 0..100
"outputs": [
{
"index": 0,
"seed": 441293,
"url": "/v1/images/3f2a.../0", // /v1/videos/3f2a.../0 for video outputs
"width": 1024,
"height": 1024,
"contentType": "image/png",
"bytes": 624797
}
],
"error": null,
"raw": { ... }
}/v1/jobsList jobs
List recent jobs, newest first. Jobs are kept in memory (max 12).
curl https://api-studio.lumorislabs.com/v1/jobs \
-H "Authorization: Bearer sk-lumoris-..." \
-H "Content-Type: application/json"{ "jobs": [ <job>, ... ] }/v1/jobs/:idPoll job
Poll a job. Calling this advances queued jobs (polls upstream).
curl https://api-studio.lumorislabs.com/v1/jobs/:id \
-H "Authorization: Bearer sk-lumoris-..." \
-H "Content-Type: application/json"{
"id": "3f2a...",
"status": "queued",
"model": "gpt-image-2.5-flare",
"prompt": "a red fox in snow",
"createdAt": 1739000000000,
"latencyMs": null,
"progress": 45
}/v1/jobs/:id/cancelCancel job
Cancel a queued or in-flight job. 400 if no cancel link exists for the job.
curl https://api-studio.lumorislabs.com/v1/jobs/:id/cancel \
-X POST \
-H "Authorization: Bearer sk-lumoris-..." \
-H "Content-Type: application/json"{ "status": 200 }/v1/jobsClear jobs
Clear the job log.
curl https://api-studio.lumorislabs.com/v1/jobs \
-X DELETE \
-H "Authorization: Bearer sk-lumoris-..." \
-H "Content-Type: application/json"{ "ok": true }/v1/images/:jobId/:idxDownload output
Output bytes for index :idx of :jobId. Images via /images/:jobId/:idx, videos via /videos/:jobId/:idx. Proxied, so upstream presigned URLs stay hidden.
curl https://api-studio.lumorislabs.com/v1/images/:jobId/:idx \
-H "Authorization: Bearer sk-lumoris-..." \
-H "Content-Type: application/json"<image/png | video/mp4 bytes>
Cache-Control: private, max-age=86400