> ## Documentation Index
> Fetch the complete documentation index at: https://dripart-willie-des-1087-router-migration-block.mintlify.site/llms.txt
> Use this file to discover all available pages before exploring further.

# Use GPT Image 2.5 Flare with Comfy Router

> Call openai/gpt-image-2.5-flare through Comfy Router: endpoint, request shape and the response Router returns.

API Reference for `openai/gpt-image-2.5-flare`, served by Comfy Router from OpenAI.

## Quick start

Create a key in [your Comfy workspace](https://platform.comfy.org/profile/api-keys) and export it as `COMFY_API_KEY`. The Python and TypeScript snippets use the Comfy SDKs (`pip install comfy-sdk`, `npm install @comfyorg/sdk`); the cURL snippet is the same call over raw HTTP.

**Model ID:** `openai/gpt-image-2.5-flare`

**Endpoint:** `POST https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare`

<Tabs>
  <Tab title="Wait for the result">
    <CodeGroup>
      ```python Python theme={null}
      from comfy_sdk import Comfy

      # Reads COMFY_API_KEY from the environment.
      # The SDK automatically creates an idempotency key and reuses it for automatic retries.
      with Comfy() as client:
          result = client.models.run(
              "openai/gpt-image-2.5-flare",
              {
                  "prompt": "a rocketship on a launchpad",
                  "quality": "low",
                  "size": "1024x1024",
              },
          )

      print(result)
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // Reads COMFY_API_KEY from the environment.
      // The SDK automatically creates an idempotency key and reuses it for automatic retries.
      const { data } = await comfy.models.run("openai/gpt-image-2.5-flare", {
        prompt: "a rocketship on a launchpad",
        quality: "low",
        size: "1024x1024",
      });

      console.log(data);
      ```

      ```bash cURL theme={null}
      curl https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"prompt\": \"a rocketship on a launchpad\", \"quality\": \"low\", \"size\": \"1024x1024\"}"
      ```
    </CodeGroup>
  </Tab>

  <Tab title="Queue and collect later">
    The same body, sent to `POST https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare/requests`. Router answers `201` with a `request_id` as soon as the run is admitted, and the result is collected once it is ready, from this process or another one. [Queued delivery](/development/comfy-router/queue) walks through status, cancellation and collection.

    <CodeGroup>
      ```python Python theme={null}
      from comfy_sdk import Comfy

      # Reads COMFY_API_KEY from the environment.
      # Each submit() call mints its own Idempotency-Key and reuses it for automatic retries.
      with Comfy() as client:
          handle = client.models.submit(
              "openai/gpt-image-2.5-flare",
              {
                  "prompt": "a rocketship on a launchpad",
                  "quality": "low",
                  "size": "1024x1024",
              },
          )
          print("request_id:", handle.request_id)  # with the model ID, all another process needs

          # Poll until the request completes, waiting the Retry-After the server names.
          for update in handle.iter_events():
              print(update.status, update.queue_position)

          # The provider's own payload, the same value models.run() returns.
          # A request that failed or was cancelled raises the typed Router error here.
          result = handle.get()

      print(result)
      ```

      ```typescript TypeScript theme={null}
      import { comfy } from "@comfyorg/sdk";

      // Reads COMFY_API_KEY from the environment.
      // Each submit() call mints its own Idempotency-Key and reuses it for automatic retries.
      const handle = await comfy.models.submit("openai/gpt-image-2.5-flare", {
        prompt: "a rocketship on a launchpad",
        quality: "low",
        size: "1024x1024",
      });
      console.log("requestId:", handle.requestId); // with the model ID, all another process needs

      // Poll until the request completes, waiting the Retry-After the server names.
      for await (const update of handle.events()) {
        console.log(update.status, update.queuePosition);
      }

      // The same result models.run() returns. A request that failed or was cancelled rejects here.
      const result = await handle.get();

      console.log(result.data);
      ```

      ```bash cURL theme={null}
      # 1. Submit. Router answers 201 with request_id, status_url, response_url and cancel_url.
      curl https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare/requests \
        -H "X-API-Key: $COMFY_API_KEY" \
        -H "Idempotency-Key: $(uuidgen)" \
        -H "Content-Type: application/json" \
        -d "{\"prompt\": \"a rocketship on a launchpad\", \"quality\": \"low\", \"size\": \"1024x1024\"}"

      # 2. Poll until status is COMPLETED, waiting the Retry-After seconds each response names.
      REQUEST_ID="<request_id from the 201 body>"
      curl -i https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare/requests/$REQUEST_ID/status \
        -H "X-API-Key: $COMFY_API_KEY"

      # 3. Collect. 200 with the model's native output, 202 with the status body while it is still running.
      curl https://api.comfy.org/v2/models/openai/gpt-image-2.5-flare/requests/$REQUEST_ID \
        -H "X-API-Key: $COMFY_API_KEY"
      ```
    </CodeGroup>
  </Tab>
</Tabs>

## Schema

### Input

<ParamField body="background" type="string">
  Background transparency

  Possible values: `transparent`, `opaque`
</ParamField>

<ParamField body="image" type="string | string[]">
  The source image(s) to edit. PRESENCE OF THIS FIELD SELECTS THE EDIT OPERATION -- omit it entirely for text-to-image generation.
  The model's published example is the GENERATION call, which omits this field. Adding `image` is the whole of the difference between the two modes -- same endpoint, same model id -- except that an edit prompt describes the CHANGE you want rather than the scene, so the edit body below reads differently from the generation example even though only this field is structurally new.
  It is copyable exactly as printed: `{"prompt": "give the rocketship rainbow coloring", "image": ["data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mP8z8BQDwAEhQGAhKmMIQAAAABJRU5ErkJggg=="], "size": "1024x1024"}` -- the payload is a complete 1x1 PNG, not an abbreviation, and this body is pinned as an accepted case in Router's own request-validation tests. Swap in your own image's bytes.
  Accepts one image or an array of them; gpt-image-1 and later take up to 16, which Router enforces from this schema before dispatching.
</ParamField>

<ParamField body="mask" type="string">
  One image, as either an https URL Router fetches on the caller's behalf or a `data:image/<format>;base64,<payload>` URI carrying the bytes inline. Accepted image types are png, webp and jpeg, and that set is ENFORCED at resolve time rather than left to the provider -- an svg, gif, avif or tiff is refused here, naming the image you sent, instead of becoming a partner error two hops from the cause.
  Prefer the URL form. A base64 payload inflates roughly 4/3 and the whole request body is capped at 20 MiB, so the inline form caps out near a 15 MB source image; a URL sidesteps that entirely.
  THE URL MUST RESOLVE WITHOUT YOUR CREDENTIALS. Router fetches it server-side and sends no caller credential with the request, so a Comfy-signed asset URL -- one whose signature is in the query string -- is the supported form. An authenticated endpoint such as `/api/assets/{id}/content` answers Router 401 rather than the image; request that URL yourself and pass the signed URL it redirects to. The fetch is confined to Comfy's own asset buckets rather than the open internet, on every redirect hop as well as the URL you send, so a third-party or redirecting URL is refused.
  The example below shows the shape only: a real value also carries the signing query parameters, which are deliberately omitted here because a published example lives in the spec forever and a real signature is both a leaked credential and a link that stops working.
  Each image is capped at 25 MiB and one request's images at 64 MiB in total.
</ParamField>

<ParamField body="model" type="string">
  The gpt-image model to run. Router splices the addressed model id in, so a caller addressing /v2/models/openai/gpt-image-2 does not send this.
</ParamField>

<ParamField body="moderation" type="string">
  Content moderation setting

  Possible values: `low`, `auto`
</ParamField>

<ParamField body="n" type="integer">
  The number of images to generate (1-10).

  Range: `1` to `10`
</ParamField>

<ParamField body="output_compression" type="integer">
  Compression level for JPEG or WebP (0-100)

  Range: `0` to `100`
</ParamField>

<ParamField body="output_format" type="string">
  Format of the output image

  Possible values: `png`, `webp`, `jpeg`
</ParamField>

<ParamField body="prompt" type="string" required>
  A text description of the image to generate, or of the edit to make to `image`.
</ParamField>

<ParamField body="quality" type="string">
  The quality of the generated or edited image

  Possible values: `low`, `medium`, `high`, `standard`, `hd`
</ParamField>

<ParamField body="size" type="string">
  Size of the image (e.g., 1024x1024, 1536x1024, auto)
</ParamField>

<ParamField body="user" type="string">
  A unique identifier for end-user monitoring
</ParamField>

Generated from the schema Router serves at `GET /v2/models/openai/gpt-image-2.5-flare/openapi.json`, the same document it validates a call against before the request reaches the provider.

### Output

<ResponseField name="data" type="object[]" />

<ResponseField name="data[].b64_json" type="string">
  Base64 encoded image data
</ResponseField>

<ResponseField name="data[].revised_prompt" type="string">
  Revised prompt
</ResponseField>

<ResponseField name="data[].url" type="string">
  URL of the image
</ResponseField>

<ResponseField name="usage" type="object" />

<ResponseField name="usage.input_tokens" type="integer" />

<ResponseField name="usage.input_tokens_details" type="object" />

<ResponseField name="usage.input_tokens_details.image_tokens" type="integer" />

<ResponseField name="usage.input_tokens_details.text_tokens" type="integer" />

<ResponseField name="usage.output_tokens" type="integer" />

<ResponseField name="usage.output_tokens_details" type="object" />

<ResponseField name="usage.output_tokens_details.image_tokens" type="integer" />

<ResponseField name="usage.output_tokens_details.text_tokens" type="integer" />

<ResponseField name="usage.total_tokens" type="integer" />

<ResponseField name="background" type="string">
  Whether the generated image's background is opaque or transparent. Populated on the fal-served branch only, which reports `opaque`.
</ResponseField>

<ResponseField name="created" type="integer">
  Unix timestamp, in seconds, of when the generation completed. Declared `int64` because a present-day epoch value is close enough to 2^31 that an unformatted `integer` generates a 32-bit field in many SDK generators.

  Format: `int64`
</ResponseField>

<ResponseField name="output_format" type="string">
  The encoding of the bytes in `data[].b64_json` (for example `png`). Populated on the fal-served branch; absent on the OpenAI-served one, where the caller's requested `output_format` is authoritative.
</ResponseField>

<ResponseField name="quality" type="string">
  The quality tier the generation actually ran at. Populated on the fal-served branch when it can resolve one; absent otherwise.
</ResponseField>

<ResponseField name="size" type="string">
  The pixel dimensions the generation actually ran at, as `<width>x<height>`. Populated on the fal-served branch when it can resolve one; absent otherwise.
</ResponseField>

## Examples

### Input

```json theme={null}
{
  "prompt": "a rocketship on a launchpad",
  "quality": "low",
  "size": "1024x1024"
}
```

### Output

```json theme={null}
{
  "created": 1767225600,
  "data": [
    {
      "b64_json": "PGJhc2U2ND4="
    }
  ],
  "usage": {
    "input_tokens": 12,
    "output_tokens": 1056,
    "total_tokens": 1068
  }
}
```

## Before you ship

The SDKs create an `Idempotency-Key` and reuse it for automatic retries. For manual retries, reuse the original key. Router can hold the connection for up to 10 minutes.

When a request fails, Router sends an `X-Comfy-Error-Type` response header explaining why. A `422` means Router rejected the input before calling the provider, and a `413` means the request body was larger than Router accepts. Download generated assets promptly because [result URLs can expire](/development/comfy-router/reference#result-assets).

Any size limit named in a field description above is the provider's own bound on that field, quoted from the provider's specification. Router applies a separate cap to the whole request body, which base64-encoded media counts against: see [request body size](/development/comfy-router/limitations#request-bodies-are-capped).

<CardGroup cols={3}>
  <Card title="Headers" icon="list" href="/development/comfy-router/headers">
    Authentication, idempotency, request IDs, error buckets, retry pacing, spend limits.
  </Card>

  <Card title="Using the Router API" icon="code" href="/development/comfy-router/api">
    Model discovery, validation errors, retries, and billing.
  </Card>

  <Card title="Limitations" icon="triangle-exclamation" href="/development/comfy-router/limitations">
    What Router does not do today, and what to use instead.
  </Card>
</CardGroup>
