> For clean Markdown of any page, append .md to the page URL.
> For a complete documentation index, see https://docs.beatapi.io/llms.txt.
> For AI client integration (Claude Code, Cursor, etc.), connect to the MCP server at https://docs.beatapi.io/_mcp/server.

# Как подключить BeatAPI — быстрый старт с API и агентом

> Подключите ИИ-ассистента к BeatAPI или создайте API-ключ, отправьте первую задачу и получите результат. Настройка URL, проверка баланса и помощь при insufficient funds.

# Быстрый старт с BeatAPI

Один API-ключ BeatAPI подходит для текстовых запросов, генерации изображений, видео и эффектов, рабочих процессов и видео в реальном времени. Храните ключ на сервере. Вы можете подключить ИИ-агента или обращаться к API напрямую. Платные запросы списывают средства с баланса в USD, поэтому перед запуском проверьте [цену выбранной модели](https://beatapi.io/ru/pricing).

## Подключить ИИ-ассистента

Вставьте строку целиком **в чат ИИ-ассистента или агента в IDE, не в Google**:

```text
set up https://beatapi.io/SKILL.md
```

Агент прочитает общедоступную инструкцию и поможет настроить подключение, если его среда это поддерживает. Одного чтения инструкции недостаточно для авторизации: создайте ключ в [панели управления](https://beatapi.io/dashboard/apikeys) и сохраните его в защищённом хранилище учётных данных клиента. Не отправляйте ключ в чат. Попросите агента проверить подключение и показать доступные модели и инструменты, не запуская платную задачу.

Если агент не может открыть ссылку, настроить MCP или отправить HTTPS-запрос, воспользуйтесь [руководством по настройке](https://beatapi.io/ru/skill) и [документацией клиента](/integrations). Если в чате нет доступа к внешним инструментам, эта строка сама по себе не подключит его к BeatAPI.

## Первая задача за три шага

### 1. Создайте API-ключ

Откройте [Dashboard → API Keys](https://beatapi.io/dashboard/apikeys). В терминале введите ключ так, чтобы он не попал в историю команд:

```bash
read -rsp "BeatAPI API key: " BEATAPI_API_KEY && echo
export BEATAPI_API_KEY
```

Базовый адрес API — `https://api.beatapi.io`. Для авторизации передавайте заголовок:

```http
Authorization: Bearer <BEATAPI_API_KEY>
```

Если настраиваете OpenAI SDK, укажите `https://api.beatapi.io/v1`; для Anthropic SDK — `https://api.beatapi.io`. Как правильно указать `/v1`, объясняется в [FAQ по подключению](/ru/faq/connection-usage).

### 2. Создайте задачу

Пример генерации изображения через `POST /v1/images/tasks`. Его выполнение оплачивается по тарифу модели:

```bash
curl https://api.beatapi.io/v1/images/tasks \
  -X POST \
  -H "Authorization: Bearer $BEATAPI_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nano-banana",
    "prompt": "Editorial product photograph on a warm stone pedestal."
  }'
```

Корректный запрос возвращает `201 Created`. Сохраните `data.id`.

### 3. Получите результат

```bash
curl https://api.beatapi.io/v1/tasks/task_8K2qA \
  -H "Authorization: Bearer $BEATAPI_API_KEY"
```

Замените `task_8K2qA` на `data.id` из шага 2. Между проверками ждите `data.poll_after_seconds`: 5 секунд для изображений, 8 для видео и эффектов, 10 для данных и рабочих процессов. Поле присутствует, пока задача выполняется.

Когда статус станет `succeeded`, получите файлы из `data.output.media` и прекратите опрос. При `failed` проверьте `data.error_code`, `data.error_message` и `data.retryable`, затем также прекратите опрос. Если уже принятая задача завершилась ошибкой, запрос её статуса всё равно возвращает HTTP `200`; ошибка указана в теле ответа.

> **Note**
>
> Постоянные API-ключи храните только на доверенных серверах. Не помещайте их в код браузерного или мобильного приложения, исходные файлы, логи и скриншоты. Для видео в реальном времени браузер получает только краткоживущий `client_secret`, созданный вашим сервером.

## Выберите API

| API             | Создание                         | Входные данные                                                                           | Результат                                          |
| --------------- | -------------------------------- | ---------------------------------------------------------------------------------------- | -------------------------------------------------- |
| Текст (GPT-5.6) | `POST /v1/responses`             | Текст, изображения, инструменты, параметры рассуждения                                   | Синхронный JSON или поток ответа                   |
| Music Video     | `POST /v1/music-video/tasks`     | Аудио и визуальные референсы выбранного уровня                                           | Музыкальное видео и раскадровка                    |
| Ecommerce       | `POST /v1/ecommerce-video/tasks` | Изображения товара, длительность, описание                                               | Видео товара                                       |
| Video Analysis  | `POST /v1/video-analysis/tasks`  | Загруженное видео, запрос анализа, глубина                                               | Текст анализа и число токенов                      |
| Realtime        | `POST /v1/realtime/sessions`     | Источник браузерного запроса (`origin`), фиксированная длительность, затем `MediaStream` | Видеопоток WebRTC, генерируемый в реальном времени |
| Видео           | `POST /v1/videos/tasks`          | Промпт и референсы для выбранной модели                                                  | Видео по URL                                       |
| Изображение     | `POST /v1/images/tasks`          | Промпт и необязательные референсы                                                        | Изображение по URL                                 |
| Эффект          | `POST /v1/effects/tasks`         | Опубликованный ID эффекта, изображения, параметры                                        | Изображение или видео                              |

Ответ на текстовый запрос возвращается синхронно или потоком SSE. Realtime создаёт краткоживущую сессию. При запуске рабочего процесса, генерации видео, изображения или эффекта создаётся асинхронная задача: сохраните `data.id` и проверяйте её статус через общий метод `GET /v1/tasks/{task_id}`. Для этого метода нет ограничения частоты запросов, но между проверками следует выдерживать интервал `poll_after_seconds`.

Форматы GPT, выбор модели и потоковые примеры: [справочник GPT](/text-api/gpt/responses).

## Проверка статуса задачи

`GET /v1/tasks/{task_id}` принимает обязательный строковый `task_id` в пути. Используйте `data.id` из ответа создания.

| Статус             | Значение                                        | Действие                                                                           |
| ------------------ | ----------------------------------------------- | ---------------------------------------------------------------------------------- |
| `queued`           | Принята, ожидает выполнения                     | Продолжайте опрос                                                                  |
| `processing`       | Генерация выполняется                           | Продолжайте опрос                                                                  |
| `storyboard_ready` | Раскадровка Music Video готова                  | Автоматический процесс может продолжиться; при необходимости проверьте раскадровку |
| `requires_action`  | Music Video ожидает вашего действия             | Отредактируйте отдельные сцены или запустите сборку видео                          |
| `editing`          | Редактируется кадр Music Video                  | Продолжайте опрос                                                                  |
| `composing`        | Собирается Music Video                          | Продолжайте опрос                                                                  |
| `succeeded`        | Результат готов                                 | Прочитайте `data.output`, прекратите опрос                                         |
| `failed`           | Задача завершилась ошибкой; HTTP остаётся `200` | Прочитайте ошибку и `retryable`, прекратите опрос                                  |

Задачи генерации изображений и видео используют только `queued`, `processing`, `succeeded` и `failed`. Остальные состояния относятся к Music Video.

### Общие поля задачи

| Поле                          | Тип              | Значение                                                                                                                                                      |
| ----------------------------- | ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `id`                          | string           | Постоянный ID задачи                                                                                                                                          |
| `object`                      | string           | `task`                                                                                                                                                        |
| `task_kind`                   | string           | `workflow`, `effect`, `image`, `video` или `data`                                                                                                             |
| `capability_id`               | string           | Постоянный ID рабочего процесса, эффекта или модели генерации                                                                                                 |
| `capability_version`          | integer          | Всегда `1`                                                                                                                                                    |
| `workflow`                    | string           | У задач рабочих процессов: `music-video` или `ecommerce-video`                                                                                                |
| `effect_id`, `effect_version` | string, integer  | У эффектов: ID и неизменяемая выбранная версия                                                                                                                |
| `media_type`, `model`         | string           | У изображений и видео: тип и ID модели                                                                                                                        |
| `status`, `stage`             | string           | Текущее состояние; `stage` повторяет `status` для совместимости                                                                                               |
| `storyboard`                  | object           | Раскадровка Music Video, когда доступна                                                                                                                       |
| `created_at`, `updated_at`    | integer          | Временные метки Unix                                                                                                                                          |
| `completed_at`                | integer или null | Временная метка завершения в формате Unix                                                                                                                     |
| `poll_after_seconds`          | integer          | Интервал опроса, пока задача выполняется                                                                                                                      |
| `typical_seconds`             | object           | При достаточном объёме статистики: `p50`, `p90`, `samples`, `window`; если задача выполняется дольше `p90`, её выполнение занимает больше времени, чем обычно |
| `output`                      | object или null  | `null` до успешного завершения                                                                                                                                |
| `usage`                       | object           | Расходы и оплачиваемая длительность                                                                                                                           |
| `request_id`                  | string           | ID для диагностики и поддержки                                                                                                                                |
| `error_code`, `error_message` | string или null  | Код и описание ошибки                                                                                                                                         |
| `retryable`                   | boolean          | Только при `failed`: есть ли смысл отправить задачу повторно                                                                                                  |

### Расходы и выходные файлы

Поля `credits_*` сохранены для совместимости. Все значения баланса и расходов — десятичные суммы USD: \*\*1 Credit = $1 USD**. Панель управления показывает те же суммы со знаком `$\`.

| Поле                              | Значение                                                       |
| --------------------------------- | -------------------------------------------------------------- |
| `usage.credits_reserved`          | Зарезервированная сумма USD                                    |
| `usage.credits_charged`           | Списанная сумма; `0` при ошибке                                |
| `usage.billable_duration_seconds` | Необязательная длительность для расчёта стоимости              |
| `usage.credits_settled`           | Итоговая сумма после успеха; `0` при ошибке                    |
| `usage.credits_refunded`          | Возвращённая сумма при ошибке                                  |
| `output.media`                    | Массив файлов результата                                       |
| `output.media[].type`             | `image` или `video`                                            |
| `output.media[].url`              | URL файла; скачайте нужные результаты для постоянного хранения |
| `output.media[].mime_type`        | MIME-тип результата                                            |
| `output.r2_url`                   | Основной URL результата                                        |

Если задача завершилась ошибкой, `credits_reserved` показывает зарезервированную сумму, `credits_charged` и `credits_settled` равны `0`, а `credits_refunded` содержит сумму возврата. При `content_policy_violation` и `bad_request` повторять ту же задачу без изменений не следует. При `processing_unavailable`, `processing_timeout`, `processing_failed` и `result_transfer_failed` повторная отправка может помочь. См. [ошибки](/errors#where-a-failure-shows-up).

## Загрузка входного файла

Используйте `POST /v1/files`, если файл находится на вашем устройстве и ещё не доступен по общедоступной HTTPS-ссылке. Запрос должен содержать точный `Content-Length`; curl, браузеры и SDK обычно задают его автоматически. Загрузка с передачей по частям (chunked) без указанной длины отклоняется до чтения тела запроса в буфер.

В multipart-запросе поле `file` обязательно. Необязательное поле `purpose` игнорируется: в ответе оно всегда равно `input`.

```bash
curl https://api.beatapi.io/v1/files \
  -X POST \
  -H "Authorization: Bearer $BEATAPI_API_KEY" \
  -F "file=@./song.mp3" \
  -F "purpose=input"
```

Можно также передать содержимое файла непосредственно в теле запроса, указав его MIME-тип в заголовке `Content-Type`.

| Файл        | Расширения          | MIME-типы                                                               | Максимум |
| ----------- | ------------------- | ----------------------------------------------------------------------- | -------- |
| Изображение | PNG, JPG/JPEG, WebP | `image/png`, `image/jpeg`, `image/webp`                                 | 50 MB    |
| Аудио       | MP3, WAV, AAC, M4A  | `audio/mpeg`, `audio/wav`, `audio/aac`, `audio/mp4`                     | 50 MB    |
| Субтитры    | SRT                 | `application/x-subrip`; `text/plain` только в multipart с именем `.srt` | 50 MB    |
| Видео       | MP4, MOV            | `video/mp4`, `video/quicktime`                                          | 100 MB   |

Допустимые альтернативные MIME-типы приводятся к стандартным: `image/jpg` — к `image/jpeg`, `audio/mp3` — к `audio/mpeg`, а `text/plain` для файла `.srt` — к `application/x-subrip`. PDF, произвольные текстовые файлы, octet-stream, неподдерживаемые видеоконтейнеры и ZIP отклоняются с `400 bad_request`. Если у файла есть расширение, оно должно соответствовать объявленному `Content-Type`. При загрузке проверяется объявленный тип, но не содержимое файла, его длительность или размеры изображения. Поэтому модель или рабочий процесс могут отклонить уже загруженный файл при создании задачи, например из-за длительности или размера. Ссылки на входные файлы рабочих процессов не могут указывать на localhost или адреса частной сети; data URL также не поддерживаются.

При отказе в загрузке возвращается `400 bad_request`. Текст сообщения остаётся на английском, чтобы его можно было сопоставить с ответом API:

| Сообщение API                                                                                               | Причина                                                                                    |
| ----------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------ |
| `Content-Length is required for file uploads.`                                                              | Не указан размер тела запроса.                                                             |
| `Content-Length must be a positive integer.`                                                                | Указан недопустимый размер.                                                                |
| `File exceeds the declared upload limit.`                                                                   | Указанный размер превышает лимит загрузки.                                                 |
| `No file provided. Use multipart "file" field or a raw body.`                                               | В запросе нет файла.                                                                       |
| `The uploaded file is empty.`                                                                               | Файл пустой.                                                                               |
| `Unsupported file type. Supported uploads are png, jpg, jpeg, webp, mp3, wav, aac, m4a, mp4, mov, and srt.` | Тип или расширение файла не поддерживается.                                                |
| `File exceeds the 50 MB limit.`                                                                             | Размер превышает 50 MB; для видео используется сообщение `File exceeds the 100 MB limit.`. |
| `File exceeds the 100 MB upload limit.`                                                                     | Размер отдельной части multipart-запроса превышает 100 MB.                                 |
| `Could not read the uploaded file.`                                                                         | Не удалось прочитать содержимое файла.                                                     |
| `Could not read the multipart upload.`                                                                      | Не удалось разобрать multipart-запрос.                                                     |

Если файл не удалось сохранить, возвращается `503 processing_unavailable` или `503 result_transfer_failed`. Ничего не сохранено; повторите запрос позже, увеличивая задержку между попытками.

### Пример ответа при загрузке

```json
{
  "data": {
    "id": "file_6f1c2b9e-4d0a-4c58-9a57-2f0a8f3d7b11",
    "object": "file",
    "url": "https://files.beatapi.io/u/6f1c2b9e4d0a4c589a572f0a8f3d7b11.mp3",
    "key": "u/6f1c2b9e4d0a4c589a572f0a8f3d7b11.mp3",
    "mime_type": "audio/mpeg",
    "size_bytes": 1048576,
    "purpose": "input",
    "created_at": 1782210000
  }
}
```

Ответ содержит `data.id` вида `file_<uuid>`, `object: "file"`, HTTPS-ссылку `url`, ключ хранения `key`, стандартный `mime_type`, размер в байтах `size_bytes`, `purpose: "input"` и временную метку Unix `created_at`. Передайте `data.url` в запрос к модели или рабочему процессу. Ограничения конкретного процесса проверяются при создании задачи: например, Standard Music Video принимает аудио длительностью 10–180 секунд, а Premium — 10–300 секунд.

## Проверка баланса и использования

Для `GET /v1/usage` требуется API-ключ. У метода нет параметров:

```bash
curl https://api.beatapi.io/v1/usage \
  -H "Authorization: Bearer $BEATAPI_API_KEY"
```

| Поле                                                       | Значение                                                                                                                             |
| ---------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `object`                                                   | `usage`                                                                                                                              |
| `credit_balance`                                           | Текущий баланс USD; может быть отрицательным                                                                                         |
| `total_tasks`                                              | Число задач аккаунта                                                                                                                 |
| `credits_settled`, `credits_refunded`                      | Итоговые расходы и возвраты USD                                                                                                      |
| `concurrency.limit`, `concurrency.active`                  | Максимальное число одновременно выполняемых задач и число задач, выполняемых сейчас                                                  |
| `realtime.sessions`, `realtime.credits`, `realtime.active` | Необязательная статистика Realtime: общее число сессий, расходы в USD и число сессий в состояниях `ready`, `connecting` или `active` |
| `by_workflow`                                              | Разбивка: `workflow`, `tasks`, `credits_settled`                                                                                     |
| `by_capability`                                            | Разбивка: `task_kind`, `capability_id`, `tasks`, `credits_settled`                                                                   |
| `by_model`                                                 | Разбивка: `media_type`, `model`, `tasks`, `credits_settled`                                                                          |
| `by_api_key`                                               | Разбивка: `api_key_id`, `title`, `key_prefix`, `tasks`, `credits_settled`                                                            |

Для задачи Music Video в состоянии `storyboard_ready` или `requires_action` уже могут быть списаны средства, хотя она не учитывается в числе одновременно выполняемых задач.

## Ошибки и повторные попытки

```json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Rate limit exceeded: at most 60 successful requests per 1 minute(s). Retry after 60 seconds.",
    "retryable": true,
    "request_id": "req_abc123",
    "retry_after_seconds": 60
  }
}
```

Ответ с ошибкой содержит `code`, описание причины на английском в поле `message` и идентификатор `request_id`. При обработке ошибки ориентируйтесь на `code`, а не на текст сообщения: клиент может показать его перевод.

### Коды ошибок

BeatAPI возвращает стабильные публичные коды, не раскрывая поставщика модели и не передавая его исходный ответ об ошибке. Код указан в `error.code`; если асинхронная задача уже была принята, код её итоговой ошибки также может находиться в `error_code`. Различия между ошибками при создании задачи, её выполнении и текстовом вызове описаны в [справочнике ошибок](/errors).

| Код                             | Что означает                                                                                                                                                                      | Что делать                                                                                             |
| ------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------ |
| `bad_request`                   | Некорректный JSON, поле, сочетание параметров, формат, URL или превышение допустимого значения. Возможен и у принятой задачи, если модель отклонила параметры или входные данные. | Исправьте поле, указанное в сообщении.                                                                 |
| `missing_api_key`               | API-ключ не передан.                                                                                                                                                              | Добавьте `Authorization: Bearer <key>`.                                                                |
| `invalid_api_key`               | Ключ неверен, срок действия истёк, он отключён или его лимит расходов исчерпан.                                                                                                   | Проверьте ключ в панели управления.                                                                    |
| `unauthorized`                  | Прежнее обозначение ошибки `401`, заменённое 29 сентября 2026 года на `missing_api_key` и `invalid_api_key`; иногда ещё встречается.                                              | Обрабатывайте как `invalid_api_key`.                                                                   |
| `forbidden`                     | Операция запрещена для ключа или аккаунта: например, модель недоступна за счёт бонуса либо действуют ограничения по IP-адресам или группе моделей.                                | Прочитайте сообщение; если модель недоступна за счёт бонуса, пополните баланс.                         |
| `not_found`                     | Неизвестная модель или возможность, несуществующий ресурс либо ресурс другого аккаунта.                                                                                           | Проверьте ID и принадлежность ресурса аккаунту ключа.                                                  |
| `insufficient_credits`          | Баланс равен нулю или меньше стоимости запроса.                                                                                                                                   | Пополните баланс перед новым платным запросом.                                                         |
| `idempotency_conflict`          | Ключ идемпотентности уже использован для другого тела запроса.                                                                                                                    | Для нового запроса используйте новый ключ.                                                             |
| `rate_limit_exceeded`           | Превышен лимит частоты запросов, в том числе к бесплатным моделям.                                                                                                                | Подождите время, указанное в `Retry-After` или `retry_after_seconds`.                                  |
| `content_policy_violation`      | Промпт, входные материалы или результат отклонены модерацией.                                                                                                                     | Измените промпт или материалы перед новой отправкой.                                                   |
| `processing_unavailable`        | Модель временно недоступна или перегружена; это не лимит частоты ваших запросов.                                                                                                  | Повторите позже с увеличивающейся задержкой. Если задача уже принята, продолжайте проверять её статус. |
| `processing_failed`             | Обработка завершилась ошибкой на стороне сервиса.                                                                                                                                 | Прекратите опрос, проверьте `error_message` и возврат средств, затем повторите позже.                  |
| `processing_timeout`            | Задача не завершилась за отведённое время.                                                                                                                                        | Прекратите опрос, проверьте возврат средств и при необходимости создайте новую задачу.                 |
| `result_transfer_failed`        | BeatAPI не удалось сохранить результат в собственном хранилище.                                                                                                                   | Прекратите опрос, проверьте возврат средств и при необходимости повторите операцию.                    |
| `result_expired`                | `POST /v1/capabilities/run` с `operation: "result"` не нашёл сохранённый результат; срок хранения — один час, HTTP-код — `404`.                                                   | Выполните вызов заново.                                                                                |
| `not_implemented`               | Метод API опубликован, но пока не поддерживается данным шлюзом (`501`).                                                                                                           | Не повторяйте запрос.                                                                                  |
| `realtime_disabled`             | Видео в реальном времени не включено на данном сервере.                                                                                                                           | Обратитесь в поддержку: самостоятельно включить его нельзя.                                            |
| `realtime_capacity_unavailable` | Для Realtime временно нет свободных ресурсов.                                                                                                                                     | Повторите позже с увеличивающейся задержкой; точное время ожидания не указано.                         |
| `realtime_session_expired`      | Сессию Realtime больше нельзя использовать.                                                                                                                                       | Создайте новую сессию и получите новый клиентский секрет.                                              |
| `origin_not_allowed`            | Источник браузерного запроса (`origin`) не разрешён для этой сессии.                                                                                                              | Используйте точное значение HTTPS origin из настроек.                                                  |
| `invalid_client_secret`         | Клиентский секрет Realtime неверен или больше не действует.                                                                                                                       | Создайте новую сессию и используйте её клиентский секрет.                                              |
| `transport_not_allowed`         | Запрошенный транспорт Realtime не разрешён.                                                                                                                                       | Используйте транспорт, указанный в документации Realtime API.                                          |
| `internal_error`                | Непредвиденная ошибка BeatAPI.                                                                                                                                                    | Сохраните `request_id`; повторяйте запрос только если это безопасно, либо обратитесь в поддержку.      |

| HTTP  | Код                                                                                           | Действие                                                                                                  |
| ----- | --------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------- |
| `400` | `bad_request`, `content_policy_violation`                                                     | Исправьте запрос или входные материалы; без изменений не повторяйте                                       |
| `401` | `missing_api_key`, `invalid_api_key`                                                          | Передайте или замените ключ                                                                               |
| `402` | `insufficient_credits`                                                                        | Пополните баланс перед новым платным запросом                                                             |
| `403` | `forbidden`, ошибка origin в Realtime                                                         | Проверьте права, ограничения ключа и точное значение HTTPS origin                                         |
| `404` | `not_found`, `result_expired`                                                                 | Проверьте ID и принадлежность ресурса аккаунту; результат вызова через Capabilities API хранится один час |
| `409` | `idempotency_conflict`                                                                        | Используйте ключ только с тем же логическим запросом                                                      |
| `429` | `rate_limit_exceeded`                                                                         | Соблюдайте `Retry-After` или `retry_after_seconds`                                                        |
| `500` | `internal_error`                                                                              | Сохраните `request_id`; повторите один раз, затем обратитесь в поддержку                                  |
| `501` | `not_implemented`                                                                             | Не повторяйте: этот метод API пока недоступен на данном шлюзе                                             |
| `503` | `processing_unavailable`, `processing_timeout`, `processing_failed`, `result_transfer_failed` | Повторяйте с увеличивающейся задержкой                                                                    |

`retryable: false` означает, что тот же запрос не сработает без изменений. Только `429 rate_limit_exceeded` содержит известную задержку `retry_after_seconds` и заголовок `Retry-After`. У `503` нет известного времени ожидания. `502` и `504` без JSON приходят от сетевого шлюза, а не BeatAPI; повторяйте их как `503`.

Поле `retryable` присутствует для всех кодов в таблице HTTP-ответов выше: оно равно `false` для `400`, `401`, `402`, `403`, `404`, `409` и `501`, и `true` для `429`, `500` и `503`.

Если клиент пишет «insufficient funds», начните с [FAQ по балансу](/ru/faq/account-billing). Если «не работает» или «не удалось подключиться» — с [FAQ по подключению](/ru/faq/connection-usage).

### Идемпотентность

* Создание задач Workflow, Image, Video, Effect и `POST /v1/capabilities/run` принимают необязательный ключ идемпотентности. Для создания Realtime Session он обязателен.
* Ключ хранится 24 часа. Максимум 255 символов; превышение даёт `400 bad_request`.
* Тот же ключ с другим телом или путём возвращает `409 idempotency_conflict`. Такой же ответ возможен, пока первый запрос ещё выполняется.
* Повтор идентичного запроса возвращает сохранённый ответ с `Idempotent-Replayed: true`.
* Сохраняются только ответы `2xx`, поэтому после `400` или `402` можно повторить запрос с тем же ключом.

## Перед запуском в рабочей среде

* Отправляйте запросы на `https://api.beatapi.io` и храните постоянные ключи на сервере.
* Проверяйте обязательные поля, форматы, перечисления, ограничения и условия выбранного API.
* Сохраняйте ID задачи или сессии и `request_id` до запуска фоновой обработки.
* Выдерживайте интервал `poll_after_seconds`. Прекращайте опрос, если задача завершилась или ожидает вашего действия.
* Скачивайте результаты, которые нужно хранить постоянно.
* Соблюдайте HTTP-коды, `Retry-After` и `retry_after_seconds`.
* Проверяйте подпись вебхука по исходным байтам до разбора JSON. События — только `task.succeeded` и `task.failed`, всего 3 попытки: повторы через 1 и 5 минут. Задача, завершённая по тайм-ауту фоновым обработчиком, не отправляет событие: статус задачи остаётся источником истины.
* Учитывайте резервы, итоговые списания и возвраты, а также ошибки и URL результата.
* Перед обработкой камер, лиц, голосов и референсов прочитайте [политику конфиденциальности (EN)](https://beatapi.io/privacy-policy) и [условия использования (EN)](https://beatapi.io/terms-of-service).