---
title: Рекомендации
description: Практики для надёжной интеграции с Clipia API — идемпотентность на ретраях, вебхуки вместо опроса, обработка ошибок и 429 с backoff, оценка стоимости и хранение request_id.
---

Чтобы интеграция с Clipia API была надёжной и предсказуемой по стоимости, придерживайтесь пяти практик: делайте отправки идемпотентными, предпочитайте вебхуки опросу, обрабатывайте ошибки и `429` с экспоненциальной задержкой, оценивайте стоимость до отправки и сохраняйте `request_id` на своей стороне. Ниже — каждая практика отдельно.

## Идемпотентность на ретраях

Передавайте `Idempotency-Key` (уникальный UUID v4 на каждый **логический** запрос) при каждой отправке. При сетевом сбое повторите запрос с тем же ключом и теми же параметрами — вернётся **тот же** `request_id`, без повторной генерации и повторного списания. Ключ хранится 24 часа.

```bash
curl -X POST https://api.clipia.ai/v1/models/nano-banana-2 \
  -H "Authorization: Bearer clipia_live_xxx" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 8f3a1c7e-2b41-4d2a-9c0e-1200304cf45b" \
  -d '{ "input": { "prompt": "a sunset over mountains, cinematic" } }'
```

| Сценарий | Результат |
|----------|-----------|
| тот же ключ + те же параметры | тот же `request_id`, без повторного списания |
| тот же ключ + другие параметры | `409 idempotency_key_reuse` |
| повтор, пока первый ещё обрабатывается | `409 request_in_progress` |

<Callout type="warn" title="Генерируйте ключ на логический запрос">
Создавайте новый UUID v4 на каждую новую генерацию, а не на каждую сетевую попытку. Не кладите в ключ чувствительные данные (email и т.п.).
</Callout>

## Вебхуки вместо опроса

Передавайте `webhook_url` при отправке — Clipia сам пришлёт `POST` по завершении, и опрашивать статус не придётся. Опрос (polling) держите как запасной вариант. Если опрашиваете — делайте это разумно (например, раз в 1–3 секунды), а не в плотном цикле.

- Отвечайте `2xx` в течение 10 секунд, иначе будет ретрай (до 6 попыток с экспоненциальной задержкой).
- Проверяйте подпись `X-Clipia-Signature` (HMAC-SHA256) на каждой доставке.
- Обрабатывайте доставки **идемпотентно** по `request_id` — возможна повторная доставка.

## Обработка ошибок и 429 с backoff

Ошибки приходят в едином JSON-формате с полями `error.type`, `error.code`, `error.message`. Реагируйте по HTTP-коду.

| HTTP | `code` | Что делать |
|------|--------|-----------|
| `400` / `422` | `invalid_request` / `model_input_invalid` | исправить тело/параметры, не ретраить как есть |
| `401` / `403` | `invalid_api_key` / `insufficient_scope` | проверить ключ и scope |
| `402` | `insufficient_credits` | пополнить баланс |
| `429` | `rate_limit_exceeded` | подождать `Retry-After` секунд, затем повторить |
| `500` / `503` | `internal_error` / `service_unavailable` | ретрай с экспоненциальной задержкой |

При `429` ориентируйтесь на заголовок `Retry-After` и метрики `RateLimit-*`:

```http
RateLimit-Limit: 120
RateLimit-Remaining: 0
RateLimit-Reset: 37
Retry-After: 37
```

<Callout type="info" title="Экспоненциальная задержка с джиттером">
Для `429`, `500` и `503` повторяйте с растущей паузой и случайным джиттером (например 1с, 2с, 4с, 8с… плюс случайная добавка), чтобы не создавать всплесков. По умолчанию лимиты — 120 RPM и 10 параллельных генераций на ключ.
</Callout>

## Оценка стоимости до отправки

Цена операции фиксирована и известна заранее. Чтобы узнать стоимость конкретного набора параметров без постановки в очередь, используйте `POST /v1/models/{model}/estimate` — он вернёт `credits`. Так можно показать стоимость пользователю или отсечь дорогие запросы заранее. При отправке цена дублируется в поле `cost`; при нехватке кредитов отправка вернёт `402`.

## Хранение request_id

Сохраняйте `request_id` каждой отправки в своей БД сразу после ответа `submit`. Он нужен, чтобы:

- сопоставить пришедший вебхук с вашей сущностью;
- опросить `status_url` / `response_url` при необходимости;
- обеспечить идемпотентность на своей стороне (не обрабатывать одну доставку дважды).

<Callout type="warn" title="Связка request_id ↔ Idempotency-Key">
Храните пару `Idempotency-Key` → `request_id`: при потере ответа на `submit` повторный запрос с тем же ключом вернёт тот же `request_id`, и вы не создадите дубль генерации.
</Callout>
