# Повторы

Передавайте `Idempotency-Key` в каждом запросе, который создаёт задачу или вызывает чат.
Повтор после обрыва или таймаута вернёт ту же задачу без второго вызова модели и второго
списания.

Обрыв соединения задачу не отменяет, и без ключа повтор создаст вторую. SDK OpenAI сам
повторяет запрос после своего таймаута в 10 минут, поэтому ключ нужен и с SDK.

```bash tab="cURL"
curl https://api.souz.ai/v1/images/generations \
  -H "Authorization: Bearer $SOUZ_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: order-1842-cover" \
  -d '{"model": "nano-banana-pro", "prompt": "кот-космонавт на Луне"}'
```

```python tab="Python"
image = client.images.generate(
    model="nano-banana-pro",
    prompt="кот-космонавт на Луне",
    extra_headers={"Idempotency-Key": "order-1842-cover"},
)
```

```ts tab="TypeScript"
const image = await client.images.generate(
  { model: "nano-banana-pro", prompt: "кот-космонавт на Луне" },
  { headers: { "Idempotency-Key": "order-1842-cover" } },
);
```

## Выберите ключ

Ключ — строка до 255 символов, уникальная в аккаунте. Возьмите id своей операции: номер
заказа, id сообщения или UUID, сохранённый до отправки. Ключ навсегда закреплён за одной
задачей и не продлевает срок её файлов.

Ключ принимают картинки, видео, музыка, транскрибация, синтез речи и чат.

## Повторите запрос

Ответ на повтор зависит от того, что стало с первым запросом:

| Первый запрос | Что вернёт повтор |
|---|---|
| Ещё выполняется | Ту же задачу с текущим статусом, чат ждёт ответа первого вызова |
| Завершился успешно | Ту же задачу с результатом, чат получит тот же ответ или поток |
| Завершился с `failed` | Ту же проваленную задачу. Для новой попытки нужен новый ключ |
| Получил отказ до приёма | Ответ на новый запрос: задачи не было, ключ свободен |

Отказ до приёма — ответ с одним `error` без задачи: `400`, `401`, `402`, `403`, `429`, `503`.
Исправьте причину и повторите с тем же ключом.

Повтор возвращает задачу такой, какой её приняли, даже если настройки аккаунта изменились:
смотрите её `routing`, `max_price_multiplier` и `routing_options`.

## Что сравнивается

Повтор должен совпадать с первым запросом в полях, от которых зависят результат и цена. Поля
доставки можно поменять.

| Метод | Сравнивается | Не сравнивается |
|---|---|---|
| Картинки, видео, музыка | Модель, все поля генерации, референсы как вы их прислали, `size` | `store`, `callback_url`, `response_format` |
| Синтез речи | Модель, `input`, голос, формат звука, `instructions`, диалог | `store`, `callback_url`, `stream_format` |
| Транскрибация | Модель, звук, язык, таймкоды, таймкоды слов (`timestamp_granularities`) | `store`, `callback_url`, формат ответа в пределах «с таймкодами или без» |
| Чат | Тело запроса целиком, байт в байт | Ничего |

Поля роутинга сравниваются так, как указаны в запросе: отсутствующее поле и поле со
значением из настроек аккаунта дают разные запросы.

## Повтор чата

Повтор чата ждёт первый вызов и получает его ответ, JSON или поток. Ответ хранится 1 сутки
и не сохраняется, если он больше 16 МиБ или вызов оборвался на нашей стороне. Тогда повтор
получит `502 generation_failed` со ссылкой на задачу, а итог и цену покажет
`GET /v1/jobs/{id}` с `id` ответа.

## Ошибки повторов

| Код | Когда | Что делать |
|---|---|---|
| `400 invalid_request` | Ключ длиннее 255 символов, `detail[].reason: too_long` | Сократите ключ |
| `409 idempotency_key_conflict` | Тот же ключ пришёл с другим запросом | Не берите новый ключ автоматически: найдите, какое поле изменилось |
| `502 generation_failed` | Повтор чата, а сохранённого ответа нет | Прочитайте итог в `GET /v1/jobs/{id}` |

**Дальше**

- [Результат задачи](https://souz.ai/docs/jobs.md) — как получить результат после `202`.
- [Ошибки](https://souz.ai/docs/errors.md) — какие ошибки стоит повторять.
- [Лимиты](https://souz.ai/docs/limits.md) — сроки ответа, после которых нужен повтор.

---

Оглавление документации: https://souz.ai/llms.txt. Всё руководство одним файлом: https://souz.ai/llms-full.txt. Справочник методов: https://souz.ai/docs/api-reference.md.
