# Quick start

> Create a key, submit a generation, poll for the result. About ten lines in any language.

Source: https://flux1.ai/api/docs/quick-start

### Create an API key

    Open [Settings → API Keys](https://flux1.ai/manage/api-keys), create a key and copy it. The full key is shown once; store it as `FLUX1_API_KEY`.

    ```bash
    export FLUX1_API_KEY="fx1_live_…"
    ```
  

  
    ### Submit a generation

    Choose a unique `Idempotency-Key` for this generation. Reuse it with the same body if the response is lost; use a new key only for another generation. See [safe retries](https://flux1.ai/api/docs/generations#idempotency).

    ```bash title="POST /v1/generations"
    curl https://flux1.ai/api/v1/generations \
      -H "Authorization: Bearer $FLUX1_API_KEY" \
      -H "Content-Type: application/json" \
      -H "Idempotency-Key: mug-532b29ab-f26e-426f-ab35-281a4ba24db8" \
      -d '{
        "model": "nano-banana-2",
        "prompt": "product photo of a ceramic mug, soft daylight",
        "aspect_ratio": "1:1",
        "resolution": "1K"
      }'
    ```

    ```http title="Response"
    HTTP/1.1 202 Accepted
    x-request-id: gen_7Hk2mP9qRtV3wXyZ1aBc4dEf

    {
      "id": "gen_7Hk2mP9qRtV3wXyZ1aBc4dEf",
      "status": "queued",
      "model": "nano-banana-2",
      "media_type": "image",
      "credits": 10,
      "credits_refunded": false,
      "input": { "prompt": "product photo of a ceramic mug, soft daylight", "aspect_ratio": "1:1", "resolution": "1K" },
      "output": null,
      "error": null,
      "created_at": "2026-09-06T03:00:00.000Z",
      "completed_at": null
    }
    ```
  

  
    ### Poll until it finishes

    Poll the id every 2–3 seconds until `status` is `succeeded` or `failed`, then download from `output.images[0].url`.

    ```bash title="GET /v1/generations/{id}"
    curl https://flux1.ai/api/v1/generations/gen_7Hk2mP9qRtV3wXyZ1aBc4dEf \
      -H "Authorization: Bearer $FLUX1_API_KEY"
    ```

    ```json title="Response when finished"
    {
      "id": "gen_7Hk2mP9qRtV3wXyZ1aBc4dEf",
      "status": "succeeded",
      "model": "nano-banana-2",
      "media_type": "image",
      "credits": 10,
      "credits_refunded": false,
      "input": { "prompt": "product photo of a ceramic mug, soft daylight", "aspect_ratio": "1:1", "resolution": "1K" },
      "output": {
        "images": [
          { "url": "https://r2.flux1.ai/result-apimart-….png", "width": 1024, "height": 1024 }
        ]
      },
      "error": null,
      "created_at": "2026-09-06T03:00:00.000Z",
      "completed_at": "2026-09-06T03:00:14.000Z"
    }
    ```
  

## Complete examples

Both examples submit one generation, poll until it leaves `queued`, and print the first image URL.

  
### Node.js

    ```js title="generate.mjs (Node.js 18+)"
    import { randomUUID } from "node:crypto";

    const BASE = "https://flux1.ai/api/v1";
    const headers = { Authorization: `Bearer ${process.env.FLUX1_API_KEY}` };
    // Generate once; save and reuse this value if you retry the POST.
    const idempotencyKey = randomUUID();

    const submit = await fetch(`${BASE}/generations`, {
      method: "POST",
      headers: { ...headers, "Content-Type": "application/json", "Idempotency-Key": idempotencyKey },
      body: JSON.stringify({
        model: "nano-banana-2",
        prompt: "isometric illustration of a tiny bookshop",
        aspect_ratio: "16:9",
      }),
    });
    if (!submit.ok) throw new Error((await submit.json()).error.message);
    const { id } = await submit.json();

    let generation;
    do {
      await new Promise((r) => setTimeout(r, 2500));
      generation = await (await fetch(`${BASE}/generations/${id}`, { headers })).json();
    } while (generation.status === "queued");

    if (generation.status !== "succeeded") throw new Error(generation.error.message);
    console.log(generation.output.images[0].url);
    ```
  

  
### Python

    ```python title="generate.py (Python 3, requests)"
    import os, time, uuid, requests

    BASE = "https://flux1.ai/api/v1"
    headers = {"Authorization": f"Bearer {os.environ['FLUX1_API_KEY']}"}
    # Generate once; save and reuse this value if you retry the POST.
    idempotency_key = str(uuid.uuid4())

    r = requests.post(f"{BASE}/generations", headers={**headers, "Idempotency-Key": idempotency_key}, json={
        "model": "nano-banana-pro",
        "prompt": "a lighthouse at dusk, film grain",
        "aspect_ratio": "3:2",
        "resolution": "2K",
    })
    r.raise_for_status()
    gen_id = r.json()["id"]

    while True:
        time.sleep(2.5)
        g = requests.get(f"{BASE}/generations/{gen_id}", headers=headers).json()
        if g["status"] != "queued":
            break

    if g["status"] != "succeeded":
        raise RuntimeError(g["error"]["message"])
    print(g["output"]["images"][0]["url"])
    ```
  

## Next

* [Generations](https://flux1.ai/api/docs/generations) lists every request field and what each `status` means.
* [Models](https://flux1.ai/api/docs/models) has the live catalog with prices and allowed aspect ratios.
* [Errors](https://flux1.ai/api/docs/errors) explains the error envelope and which failures are charged.

## Save your result

Download the returned image to your own storage before `expires_at`. API results expire 30 days after storage and are automatically cleaned up. A result URL is temporary; see [result retention](https://flux1.ai/api/docs/generations#result-retention).
