# List generations

Source: https://docs.foodshot.ai/reference/list-generations

> Lists your generations from the last 90 days, newest first.

`GET https://api.foodshot.ai/v1/generations`

While `has_more` is `true`, pass the `id` of the last item as `starting_after` to get the next page.

## Parameters

| Name | In | Type | Required | Description |
| --- | --- | --- | --- | --- |
| `status` | query | "queued" \| "processing" \| "succeeded" \| "failed" | no | Only generations with this status. |
| `created_gte` | query | string | no | Only generations created at or after this time (RFC 3339). |
| `created_lt` | query | string | no | Only generations created before this time (RFC 3339). |
| `limit` | query | integer | no | How many generations to return, 1 to 100. |
| `starting_after` | query | string | no | The `id` of the last generation on the previous page. |

## Responses

### 200

One page of generations, newest first.

```json
{
  "object": "list",
  "data": [
    {
      "id": "gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw",
      "object": "generation",
      "environment": "live",
      "status": "succeeded",
      "created_at": "2026-10-18T10:42:07.512Z",
      "started_at": "2026-10-18T10:42:09.031Z",
      "completed_at": "2026-10-18T10:42:42.870Z",
      "style_id": "pure-shot",
      "instruction": null,
      "aspect_ratio": "1:1",
      "resolution": "4k",
      "format": "jpeg",
      "metadata": {
        "dish_id": "d_456",
        "vendor_id": "v_1029"
      },
      "credits_charged": 1,
      "output": {
        "url": "https://api.foodshot.ai/v1/files/gen_4Kq9xT2mVb7Zp1Ls8Hc3Rw/image.jpg?exp=1792406595&sig=VT5DMYyFzJsUzoKdU9fob--vTZ1Nx5PFShO290vXCjc",
        "url_expires_at": "2026-10-19T10:43:15.000Z",
        "available_until": "2026-11-17T10:42:42.870Z",
        "content_type": "image/jpeg",
        "width": 4096,
        "height": 4096,
        "bytes": 8734516
      },
      "error": null,
      "delivery": {
        "status": "delivered",
        "attempts": 1,
        "last_status_code": 200,
        "last_attempt_at": "2026-10-18T10:42:43.402Z"
      }
    },
    {
      "id": "gen_rYSdrrqV4cHBg9RlVFImuf",
      "object": "generation",
      "environment": "live",
      "status": "failed",
      "created_at": "2026-10-18T10:40:02.117Z",
      "started_at": "2026-10-18T10:40:03.540Z",
      "completed_at": "2026-10-18T10:40:31.176Z",
      "style_id": "white-hero",
      "instruction": null,
      "aspect_ratio": "4:5",
      "resolution": "4k",
      "format": "jpeg",
      "metadata": {
        "dish_id": "d_457"
      },
      "credits_charged": 0,
      "output": null,
      "error": {
        "code": "content_refused",
        "message": "The photo or the instruction was refused by the content checks."
      },
      "delivery": {
        "status": "delivered",
        "attempts": 1,
        "last_status_code": 200,
        "last_attempt_at": "2026-10-18T10:40:31.655Z"
      }
    }
  ],
  "has_more": true
}
```

### 400

A query parameter is wrong or unknown.

```json
{
  "error": {
    "code": "invalid_request",
    "message": "The query parameter named in param is invalid.",
    "param": "limit",
    "request_id": "req_daJCWaeLcd6uXjfMaJeplG"
  }
}
```

### 401

The key is missing, wrong or revoked.

```json
{
  "error": {
    "code": "invalid_api_key",
    "message": "The API key is missing, malformed, unknown or revoked.",
    "param": null,
    "request_id": "req_NPfzXU77n1f2QYM559fGL8"
  }
}
```

### 403

This key may not make this request.

```json
{
  "error": {
    "code": "permission_denied",
    "message": "Live keys work only from your server.",
    "param": null,
    "request_id": "req_NPfzXU77n1f2QYM559fGL8"
  }
}
```

### 429

Over the request limit of this key. Retry after `Retry-After` seconds.

```json
{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Retry after the number of seconds in Retry-After.",
    "param": null,
    "request_id": "req_BTBBPZA0oirxnw23MU0t7E"
  }
}
```

### 500

Something went wrong on our side. Retry; for a `POST`, with the same `Idempotency-Key` and body.

```json
{
  "error": {
    "code": "internal_error",
    "message": "Something went wrong on our side. Retry the request; for POST /v1/generations, use the same Idempotency-Key.",
    "param": null,
    "request_id": "req_8d4DxP5n53EgewaJFOqGyS"
  }
}
```

### 503

Temporarily unavailable. Retry after `Retry-After` seconds.

```json
{
  "error": {
    "code": "service_unavailable",
    "message": "The service is temporarily unavailable. Retry after the number of seconds in Retry-After.",
    "param": null,
    "request_id": "req_8d4DxP5n53EgewaJFOqGyS"
  }
}
```

## Code samples

### curl

```bash
curl -sS -G https://api.foodshot.ai/v1/generations \
  --max-time 60 \
  -H "Authorization: Bearer $FOODSHOT_API_KEY" \
  --data-urlencode 'status=succeeded' \
  --data-urlencode 'created_gte=2026-10-01T00:00:00Z' \
  --data-urlencode 'limit=100'
```

### Node

```js
const params = new URLSearchParams({
  status: 'succeeded',
  created_gte: '2026-10-01T00:00:00Z',
  limit: '100',
});
let startingAfter;
do {
  if (startingAfter) params.set('starting_after', startingAfter);
  const res = await fetch(`https://api.foodshot.ai/v1/generations?${params}`, {
    headers: { Authorization: `Bearer ${process.env.FOODSHOT_API_KEY}` },
    signal: AbortSignal.timeout(60_000),
  });
  if (!res.ok) throw new Error(`FoodShot ${res.status}: ${await res.text()}`);
  const page = await res.json();
  for (const generation of page.data) console.log(generation.id, generation.metadata);
  startingAfter = page.has_more ? page.data.at(-1).id : undefined;
} while (startingAfter);
```

### Python

```python
import os

import requests

params = {"status": "succeeded", "created_gte": "2026-10-01T00:00:00Z", "limit": 100}
headers = {"Authorization": f"Bearer {os.environ['FOODSHOT_API_KEY']}"}
while True:
    response = requests.get(
        "https://api.foodshot.ai/v1/generations", params=params, headers=headers, timeout=60
    )
    response.raise_for_status()
    page = response.json()
    for generation in page["data"]:
        print(generation["id"], generation["metadata"])
    if not page["has_more"]:
        break
    params["starting_after"] = page["data"][-1]["id"]
```
