FLUX 3 Image 503: read the JSON status before you retry

BFL says a FLUX 3 Image 503 may be retryable once you check the JSON status; 422, 400 and 402 are not. Sume sync failures return a 502 with a retryable flag.

4 min readSume
All posts

A 503 from the FLUX 3 Image endpoint is not automatically a retry. BFL's generate docs say a 503 may be retryable only after you check the status in the JSON body, and they list other errors that a retry will never fix: 422 for unknown fields, 400 for an oversized image and 402 for insufficient credits. Read the body first, then decide. FLUX 3 Image is not in the Sume image catalog today; check GET /v1/images/models for the live list. The catalog lists FLUX.2 Pro and FLUX.2 Flex.

What BFL documents

The table lists what the BFL page says about errors and job statuses. It gives no numeric concurrency limit, so do not hard-code one.

FLUX 3 Image errors and statuses, read 2026-10-05
SignalMeaning on the BFL pageResubmit?
422Unknown fields in the requestNo, fix the body
400Image too largeNo, shrink the image
402Insufficient creditsNo, add credits
503Check the JSON status firstMaybe, after reading the status
Pending / Reasoning / GeneratingJob still running at the polling_urlNo, keep polling
ReadyResult in result.sample; signed URLs expire within 1 hourNo, download now
Request Moderated / Content Moderated / ErrorTerminal statesNot unchanged; the same input is likely to fail again

Why a blind retry costs you

The last row is advice, not a BFL statement: BFL lists the moderation statuses as terminal outcomes, so a blind retry of the same prompt has little reason to succeed.

  • Polling a Pending or Generating job is safe; submitting the same prompt again starts a second job.
  • A 402 retried in a loop only repeats the failure.
  • Result links expire within 1 hour, so copy images to your own storage early.

How Sume job errors differ

Sume shapes failures differently. A synchronous call to POST /v1/images waits up to 30 seconds. If the job fails terminally inside that wait, you get a 502 with an error envelope that carries code, message, retryable and next_action. If the wait budget runs out, or you send mode: "async", you get a 202 job envelope and read the images from GET /v1/jobs/{id}/result. Branch on the status code, not on the body shape. Per the Sume docs, failed or cancelled generations are not billed.

Sume Image API outcomes, read 2026-10-05
StatusWhat it meansWhat to do
200Image response with data[].url and usage.costUse the URL
202Job envelope (slow job or async mode)Poll status_url, read result_url
502Terminal failure inside the wait, error envelopeCheck retryable and next_action

A retry loop that reads the flag

This loop retries only when Sume marks the failure retryable. It uses a FLUX.2 Pro id from the Sume catalog, because FLUX 3 Image is not listed.

import os, time, requests

H = {"Authorization": "Bearer " + os.environ["SUME_API_KEY"]}

def generate(prompt):
    for attempt in range(3):
        r = requests.post("https://api.sume.com/v1/images", headers=H, timeout=60,
                          json={"model": "black-forest-labs/flux.2-pro", "prompt": prompt})
        if r.status_code == 200:
            return r.json()["data"][0]["url"]
        if r.status_code == 202:
            return "slow job, poll " + r.json()["data"]["status_url"]
        err = r.json().get("error", {})
        print(attempt, err.get("code"), err.get("retryable"), err.get("next_action"))
        if not err.get("retryable"):
            raise RuntimeError(err.get("message"))
        time.sleep(2 ** attempt)
    raise RuntimeError("still failing after 3 tries")

print(generate("a ceramic mug on a wooden table, soft window light"))

Sources

Related posts

More in Developers

All Developers posts

Written by Sume