# Generations

Source: https://docs.foodshot.ai/guides/generations

> Create a generation, follow it, and download the result.

A generation is one job: one photo in, one finished image out.

## Create a generation

```bash
curl https://api.foodshot.ai/v1/generations \
  -H "Authorization: Bearer $FOODSHOT_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 5f0c2b7e-9a4d-4c1b-8e3f-6d2a1b9c7e40" \
  -d '{
    "image_url": "https://docs.foodshot.ai/samples/dish.jpg",
    "style_id": "pure-shot",
    "metadata": { "dish_id": "d_456" }
  }'
```

| Field                         | What to send                                                                                                             |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------ |
| `image_url` or `image_base64` | The photo: an `https` URL, or the file in base64. JPEG, PNG, WebP or HEIC.                                               |
| `style_id`                    | A style id from [`GET /v1/styles`](https://docs.foodshot.ai/guides/styles).                                                                      |
| `instruction`                 | Optional. A short note in plain words, such as `Keep the blue bowl`. See [Instructions](#instructions).                  |
| `aspect_ratio`                | Optional. `1:1` (default), `2:3`, `3:2`, `3:4`, `4:3`, `4:5`, `5:4`, `9:16`, `16:9` or `21:9`.                           |
| `resolution`                  | Optional. `4k` (default) or `2k`. Both cost 1 credit. See the [result sizes](https://docs.foodshot.ai/reference/create-generation#result-sizes). |
| `format`                      | Optional. `jpeg` (default) or `png`: the file type of the result.                                                        |
| `metadata`                    | Optional. Up to 10 string pairs, such as your dish id. We send them back with the result.                                |

Send one of `image_url` or `image_base64`, and a `style_id`, an `instruction` or both.

The answer is `202 Accepted` with the new generation, in `queued` status. It usually comes within seconds. Use a client timeout of 60 seconds.

## Idempotency

Every create needs an `Idempotency-Key` header: one new UUID per photo.

* Retry with the same key and the same body. Within 24 hours you get the same generation back, and nothing is charged again.
* The same key with a different body gets `409 idempotency_conflict`.
* After a failed job, use a new key to try again.

## Statuses

`queued` → `processing` → `succeeded` or `failed`

`succeeded` and `failed` are final. A failed job is refunded, and `error.code` says why.

Our objective is about 30-40 seconds once a job starts; it is an objective, not a promise, and 4K jobs usually take a little longer than 2K. Up to 5 jobs per account run at the same time; the others wait in your queue.

## Get the result

The best way is a [webhook](https://docs.foodshot.ai/guides/webhooks). To poll instead, get the generation about 20 seconds after you created it, then every 5 seconds until it is final.

```bash
curl https://api.foodshot.ai/v1/generations/$GENERATION_ID \
  -H "Authorization: Bearer $FOODSHOT_API_KEY"
```

A succeeded generation, shortened:

```json
{
  "id": "gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw",
  "status": "succeeded",
  "metadata": { "dish_id": "d_456" },
  "output": {
    "url": "https://api.foodshot.ai/v1/files/gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw/image.jpg?exp=…&sig=…",
    "content_type": "image/jpeg",
    "width": 4096,
    "height": 4096
  },
  "error": null
}
```

The fields you need most:

* **`output.url`** is a link to the file. It needs no key and works for 24 hours; every `GET` returns a fresh one.
* **`output.content_type`** is `image/jpeg` or `image/png`. Name the file by it.
* **`error.code`** says why a job failed. See [Errors](https://docs.foodshot.ai/guides/errors#failed-generations).
* **`metadata`** is what you sent.

Download the file from your server and keep your own copy: we delete it after 30 days. A download is cut off after 60 seconds, and an expired link answers `403 permission_denied`: get the generation again for a fresh link. Every field is in the [API reference](https://docs.foodshot.ai/reference/get-generation).

To catch up after downtime, [list your generations](https://docs.foodshot.ai/reference/list-generations) by `status` and `created_gte`.

## Instructions

`instruction` is a short note in plain words, such as `Keep the blue bowl` or `Make the background darker`.

* With a `style_id`, it adjusts the style.
* Without a `style_id`, it describes the whole look. Results are less predictable than with a style.
* Don't use it to add food that isn't in the photo, or for personal information.
