Image API

Async image generation,
get results viacallback

Submit and get a task id back; poll the status, or configure a webhook to receive signed results. Authenticate with the same sk-lumen- key, billed in credits at the model and group unit price.

Quick start

Submit and fetch the result

First submit to get an id; then poll that id until status is succeeded or failed.

1 · Submit · POST /v1/images/generations

curl https://lumen.mengfanlab.top/v1/images/generations \
  -H "Authorization: Bearer sk-lumen-•••" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2-low",
    "prompt": "a cute cat on a windowsill",
    "size": "1024x1024",
    "n": 1
  }'

# 立即返回(异步):
# { "id": "a1b2c3...", "status": "queued", "created": 1700000000 }

2 · Query status · GET /v1/images/generations/{id}

curl https://lumen.mengfanlab.top/v1/images/generations/a1b2c3... \
  -H "Authorization: Bearer sk-lumen-•••"

# 处理中: { "id": "...", "status": "processing" }
# 成功:   { "id": "...", "status": "succeeded", "data": [ { "url": "https://img..." } ] }
# 失败:   { "id": "...", "status": "failed", "error": { "code": "...", "message": "..." } }

Image-to-image / inpainting

Editing and inpainting

Image-to-image passes reference images via image_urls; inpainting additionally passes mask_url (mask, white is the repaint area). Returns and queries are the same as above (async + status query / webhook).

Image-to-image · POST /v1/images/edits

curl https://lumen.mengfanlab.top/v1/images/edits \
  -H "Authorization: Bearer sk-lumen-•••" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2-low",
    "prompt": "把背景换成雪山",
    "image_urls": ["https://your.img/cat.png"],
    "size": "1024x1024"
  }'

Inpainting · POST /v1/images/inpaint

curl https://lumen.mengfanlab.top/v1/images/inpaint \
  -H "Authorization: Bearer sk-lumen-•••" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "fal-flux-pro-fill",
    "prompt": "把蒙版区域改成一只柯基",
    "image_urls": ["https://your.img/photo.png"],
    "mask_url": "https://your.img/mask.png"
  }'
  • · Both image-to-image and inpainting must pass image_urls (or image for a single one); inpainting must also pass mask_url.
  • · Inpainting requires a model that supports inpaint (e.g. fal-flux-pro-fill); other models support text-to-image / image-to-image only.
  • · After getting a task id, query with GET /v1/images/generations/{id}, or configure a webhook to receive the result.

Request parameters

POST /v1/images/generations fields

Currently text-to-image.

modelstringrequired

Image model code, e.g. gpt-image-2-low; the full list is in the console.

promptstringrequired

Image description.

image_urlsstring[]

Array of reference image URLs (or image for a single one). Required for image-to-image /edits and inpainting /inpaint.

mask_urlstring

Mask image URL, white is the repaint area. Required only for inpainting /inpaint.

ninteger

Number of images, 1–4, default 1.

sizestring

Size. Supports "1024x1024" pixel notation, or aspect ratios like "16:9"; default 1:1.

resolutionstring

Resolution tier 1K / 2K / 4K; inferred from size pixels if omitted.

qualitystring

Quality tier, model dependent (e.g. low / medium / high).

negative_promptstring

Negative prompt.

webhook_urlstring

Completion callback URL (http/https). Falls back to polling if omitted.

webhook_secretstring

Callback signing secret. Required once webhook_url is set (used for signature verification).

Status values: queued / processing / succeeded / failed / cancelled. On succeeded it returns data:[{url}], on failed it returns error.

Webhook

Signed callback on completion

With webhook_url set (must also include webhook_secret), when the task reaches a terminal state the server POSTs the result to your URL with an HMAC-SHA256 signature header for verification. Both success and failure are called back.

Submit with a webhook

curl https://lumen.mengfanlab.top/v1/images/generations \
  -H "Authorization: Bearer sk-lumen-•••" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-image-2-low",
    "prompt": "a cute cat",
    "webhook_url": "https://your.app/callback",
    "webhook_secret": "your-secret"
  }'

What you will receive

POST https://your.app/callback
Content-Type: application/json
X-Lumen-Signature: sha256=<hmac_hex>
X-Lumen-Timestamp: 1700000000

{ "id": "a1b2c3...", "status": "succeeded", "data": [ { "url": "https://img..." } ] }

Verify (use the same secret on the raw body)

# Python: 对收到的原始 body 用同一 secret 验签
import hmac, hashlib

def verify(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "sha256=" + hmac.new(secret.encode(), raw_body, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, signature_header)
  • · Signature = HMAC-SHA256(webhook_secret, raw response body), as hex, placed in X-Lumen-Signature: sha256=<hex>.
  • · Always verify against the raw bytes received; do not deserialize and re-serialize first (field order changes).
  • · X-Lumen-Timestamp is the delivery timestamp, usable for replay protection.
  • · Webhook is optional; without it, use GET polling to fetch the result.

Error codes

400

Invalid request body, or webhook_url was passed without webhook_secret.

401

Key missing, invalid, or revoked.

402

Insufficient account credits.

404

Task not found, or no such image model in this group.

429 / 5xx

Upstream rate limit or error. Failed tasks refund the deducted credits.

Questions or partnerships, email [email protected].