Ошибки
Все ошибки API — в формате RFC 9457 application/problem+json:
{
"type": "https://castbase.ru/docs/errors#validation_failed",
"title": "Данные не прошли проверку",
"status": 422,
"detail": "Подпись длиннее 2200 символов (передано 2301).",
"code": "validation_failed",
"errors": [
{"field": "caption", "code": "too_long", "message": "Подпись длиннее 2200 символов (передано 2301)."}
]
}
| Поле | Значение |
|---|---|
type |
ссылка на описание кода в этом каталоге |
title, detail |
краткий заголовок и текст для человека (на русском); для логики не используйте, их формулировки могут меняться |
status |
HTTP-статус |
code |
машинный код: по нему принимайте решения в коде |
errors[] |
для 422: по записи на каждое неверное поле — field, code, message; сообщаются сразу все ошибки, а не только первая |
Дополнительные поля есть у ошибок лимитов (limit, plan, resets_at).
Заголовки: Retry-After — при 429, WWW-Authenticate — при 401.
Как реагировать
| Статус | Тактика |
|---|---|
400, 422 |
ошибка в запросе: исправьте и отправьте заново (повтор без изменений даст то же) |
401 |
проверьте ключ |
402 |
нужна смена тарифа |
404, 409 |
не тот ресурс или состояние: перечитайте ресурс |
429 |
подождите Retry-After секунд и повторите |
5xx |
временная проблема: повторите с тем же Idempotency-Key с нарастающей паузой |
Ниже — полный каталог кодов. Первая группа — code ответа; остальные — коды вторых уровней: ошибки полей, причины
отказа публикации и причины статусов канала.
Ошибки запроса
Поле code ответа application/problem+json. По нему программа решает, что делать дальше; detail — текст для человека.
| Код | HTTP | Что значит | Что делать |
|---|---|---|---|
bad_request |
400 | Тело запроса не JSON-объект или запрос некорректен. | Отправьте JSON-объект с заголовком Content-Type: application/json. |
idempotency_key_required |
400 | На POST не передан заголовок Idempotency-Key. | Добавьте Idempotency-Key (уникальная строка до 255 символов) к каждому POST. |
invalid_idempotency_key |
400 | Idempotency-Key длиннее 255 символов или содержит пробелы и непечатные символы. | Используйте UUID или другую строку из печатных ASCII-символов без пробелов. |
unauthorized |
401 | Ключ не передан, неверен или отозван. | Передайте действующий ключ: Authorization: Bearer cb_live_… Новый ключ — в кабинете. |
payment_required |
402 | Действие доступно только на платном тарифе. | Смените тариф в кабинете (раздел «Тарифы»). |
channels_limit_exceeded |
402 | Достигнут лимит каналов тарифа. В ответе есть поля limit и plan. | Отключите ненужный канал или перейдите на тариф с большим лимитом. Повтор запроса не поможет. |
forbidden |
403 | Доступ к ресурсу запрещён. | Проверьте, что ресурс принадлежит проекту вашего ключа. |
not_found |
404 | Нет такого ресурса в проекте ключа (чужие ресурсы выглядят так же). | Проверьте id и что используете ключ нужного проекта. |
method_not_allowed |
405 | Метод HTTP не поддерживается этим адресом. | Сверьтесь со справочником API. |
conflict |
409 | Состояние ресурса не позволяет действие. | Прочитайте ресурс заново и повторите, если действие ещё актуально. |
external_ref_taken |
409 | Пост с таким external_ref уже есть в проекте (id поста — в detail). | Это ваш же пост: возьмите его по id. external_ref освобождается отменой поста. |
post_not_cancellable |
409 | Пост уже отправлен в публикацию — отменить нельзя. | Дождитесь результата в событиях. Отмена возможна только пока все цели в статусе scheduled. |
target_not_failed |
409 | Повторить можно только цель в статусе failed. | Для deferred повтор делает сам сервис; для outcome_unknown не повторяйте вручную (см. раздел «Статусы и события»). |
channel_not_active |
409 | Канал отключён или требует переподключения, а нового подключения того же аккаунта нет — повтор цели невозможен. | Подключите тот же аккаунт заново и повторите цель: она уйдёт через новый канал. |
unsupported_media_type |
415 | Неподдерживаемый Content-Type. | JSON — application/json, файлы — multipart/form-data. |
validation_failed |
422 | Данные не прошли проверку. Подробности по каждому полю — в массиве errors[] (см. ниже). | Исправьте поля из errors[] и отправьте запрос заново. |
idempotency_key_reused |
422 | Этот Idempotency-Key уже использован с другим запросом. | Для нового запроса возьмите новый ключ; для повтора — отправьте то же тело. |
rate_limited |
429 | Слишком много запросов с одного ключа. Заголовок Retry-After — через сколько секунд повторить. | Подождите Retry-After секунд. Не ретрайте в цикле без паузы. |
posts_limit_exceeded |
429 | Исчерпан лимит постов в месяц по тарифу. В ответе: limit, plan, resets_at; заголовок Retry-After. | Дождитесь resets_at или смените тариф. |
internal_error |
500 | Внутренняя ошибка сервиса. | Повторите запрос с тем же Idempotency-Key. Если не проходит — напишите в поддержку. |
service_unavailable |
503 | Сервис подключения каналов временно недоступен. | Повторите позже. |
Коды в errors[] (ошибки полей)
При validation_failed каждая запись errors[] — это {field, code, message}. Поле field указывает, что именно не так (media[1].media_id, options.audio_name, slots[0].time); код ниже уточняет причину.
| Код | Что значит | Что делать |
|---|---|---|
required |
Обязательное поле не передано (file, url, access_token, channel_ids). | Передайте поле. |
invalid |
Значение не подходит: status, cursor, external_ref (непустая строка до 128 символов). | Сверьтесь с описанием поля в справочнике API. |
invalid_type |
Неверный тип значения (caption не строка, options не объект, share_to_feed не boolean, audio_name длиннее 200 символов). | Передайте значение нужного типа. |
not_found |
Канал (channel_ids[i]) или медиа (media[i].media_id) не найдены в этом проекте. | Проверьте id и что канал/медиа из того же проекта. |
duplicate |
Один и тот же канал или медиа указан дважды. | Уберите дубль. |
too_many |
Слишком много элементов: каналов в посте (channel_ids) или слотов сетки (slots). | Уменьшите список. |
channel_not_active |
Канал ещё подключается, отключён или требует переподключения (статус в message). | Дождитесь статуса active или переподключите канал. |
empty |
Пусто: нет медиа в посте или файл нулевого размера. | Передайте хотя бы одно медиа / непустой файл. |
no_items |
В media нет ни одного элемента с role=item (только обложки). | Добавьте основной элемент. |
invalid_role |
role медиа — не item и не cover. | Используйте item или cover. |
media_expired |
Срок хранения файла истёк. | Загрузите файл заново. |
too_many_items |
В карусели больше 20 элементов. | Разбейте на несколько постов. |
video_not_reels |
Видео вместе с другими элементами. Видео публикуется только как Reels: один элемент. | Отправьте видео отдельным постом. |
cover_not_allowed |
Обложка (role=cover) указана не у Reels. | Уберите обложку или опубликуйте видео как Reels. |
invalid_cover |
Обложка должна быть одной картинкой. | Оставьте одну картинку с role=cover. |
too_long |
Подпись длиннее 2200 символов либо видео длиннее 15 минут. | Сократите подпись или видео. |
too_many_hashtags |
В подписи больше 30 хэштегов. | Оставьте не больше 30. |
unsupported_option |
Опция в options не поддерживается (доступны share_to_feed, audio_name, dry_run). | Уберите опцию. |
no_schedule |
publish_at="next_slot", а у проекта нет сетки слотов. | Задайте сетку через PUT /v1/schedule или укажите время явно. |
no_free_slot |
Нет свободного слота в ближайшие 75 дней. | Добавьте слоты в сетку или укажите время явно. |
invalid_datetime |
publish_at не разобрать: нужен ISO-8601 (2026-12-01T10:00:00+03:00) или "next_slot". | Исправьте формат. |
too_far |
publish_at дальше чем через 75 дней. | Выберите более раннюю дату. |
invalid_weekday |
weekday слота — не число от 1 (понедельник) до 7 (воскресенье). | Исправьте слот. |
invalid_time |
time слота — не время HH:MM. | Исправьте слот. |
too_large |
Файл больше допустимого: картинка 8 МБ, видео 300 МБ (и для импорта по ссылке). | Сожмите файл. |
too_short |
Видео короче 3 секунд. | Возьмите ролик подлиннее. |
unreadable |
Файл повреждён или это не картинка/видео. | Проверьте файл и загрузите заново. |
unsupported_type |
Тип файла не подходит Instagram. Картинки: JPEG, PNG, WebP; видео: MP4, MOV. | Конвертируйте файл. |
upload_failed |
Файл не дошёл до сервера целиком. | Повторите загрузку. |
invalid_url |
Нужна ссылка http(s) без логина и пароля, на порт 80 или 443. | Исправьте ссылку. |
unsafe_url |
Ссылка ведёт на внутренний или недоступный из интернета адрес. | Используйте публично доступный адрес. |
fetch_failed |
Не удалось скачать файл по ссылке (код ответа не 200, таймаут, слишком много перенаправлений). | Проверьте ссылку или загрузите файл напрямую (POST /v1/media). |
unsupported_platform |
Платформа не поддерживается (сейчас только instagram). | Передайте platform=instagram. |
invalid_token_format |
Токен пустой, слишком длинный или содержит пробелы. | Скопируйте токен целиком. |
Коды ошибок цели публикации (error.code)
Приходят в targets[].error и в событиях post.failed / post.deferred / post.outcome_unknown (поля error_code, error_message). Это причина, по которой Instagram не принял публикацию или сервис не смог её завершить.
| Код | Что значит | Что делать |
|---|---|---|
reauth_required |
Токен канала недействителен или у него нет прав. Канал переведён в reauth_required. | Подключите тот же аккаунт заново и повторите цель через :retry — она уйдёт через новый канал. |
rate_limited |
Instagram ограничил частоту запросов. Цель в статусе deferred, retry_at — когда сервис попробует снова. | Ничего: сервис повторит сам. |
quota_exhausted |
Исчерпана квота публикаций аккаунта за 24 часа. Цель deferred до освобождения окна. | Ничего: сервис повторит сам. Планируйте меньше постов в сутки. |
media_fetch_failed |
Instagram не смог скачать медиа (временно). | Сервис повторит сам; если исчерпал попытки, цель станет failed — повторите через :retry. |
platform_unavailable |
Instagram временно недоступен или ответил ошибкой сервера. | Сервис повторит сам (до 6 попыток). |
network_error |
Сбой сети на пути к Instagram. | Сервис повторит сам. Если ответ Instagram на публикацию потерян, статус будет outcome_unknown. |
no_egress |
Нет здорового исходящего узла до Instagram. | Сервис повторит сам; при затянувшемся сбое напишите в поддержку. |
container_error |
Instagram не смог обработать медиа (контейнер в статусе ERROR). | Проверьте файл: формат, кодек, соотношение сторон. Затем создайте пост заново. |
container_timeout |
Instagram слишком долго обрабатывает медиа (видео). | Сервис повторит сам; при исчерпании попыток — :retry. |
expired |
Прошло 24 часа от publish_at, а опубликовать не удалось. | Создайте пост заново с новым временем. |
invalid_media |
Описание медиа в запросе на публикацию неверно. | Создайте пост заново; если повторяется — поддержка. |
channel_not_connected |
У канала нет действующего подключения к Instagram. | Подключите тот же аккаунт заново и повторите цель через :retry. |
platform_rejected |
Instagram отклонил публикацию окончательно (текст — в error_message). | Исправьте креатив по тексту ошибки и создайте пост заново. |
not_received |
Публикационный сервис не получал эту цель (потерянная команда). | Повторите цель через :retry. |
Причины статусов канала (status_reason, reason_code)
Канал в статусе failed (подключить не удалось) или reauth_required (нужен новый токен) содержит status_reason и понятный status_message. Те же коды — в reason_code события channel.reauth_required.
| Код | Что значит | Что делать |
|---|---|---|
invalid_token |
Токен неверный или просрочен. | Сгенерируйте новый токен в Meta («Generate token») и подключите канал заново. |
token_rejected |
Instagram отклонил токен при проверке. | Сгенерируйте новый токен, проверьте, что аккаунт добавлен тестером приложения. |
not_professional |
Аккаунт не Professional (Business или Creator). | Переключите тип аккаунта в настройках Instagram. |
platform_unavailable |
Instagram недоступен во время проверки токена. | Повторите подключение через несколько минут. |
token_unreadable |
Токен не удалось расшифровать на нашей стороне. | Подключите канал заново. |
oauth_denied |
При входе через Instagram (managed) доступ не выдан. | Повторите вход и разрешите доступ. |
oauth_failed |
При входе через Instagram (managed) токен не получен. | Повторите вход. |
duplicate_account |
Этот аккаунт уже подключён к проекту более новым подключением (новое подключение того же аккаунта заменяет старое, а запоздавшее старое отклоняется). | Используйте подключённый канал. |
invalid_event |
Сервис публикации прислал неполные данные аккаунта (нет id или username). | Подключите канал заново; если повторяется — напишите в поддержку. |
token_expired |
Срок токена истёк, продлить не удалось. Канал в статусе reauth_required. | Подключите канал заново с новым токеном. |
token_invalid |
Токен отозван или недействителен. Канал в статусе reauth_required. | Подключите канал заново с новым токеном. |
refresh_failed |
Продлить токен пока не удалось; сервис продолжает пробовать (reauth_due_at — срок). | Ничего, пока канал active. Если срок близок — переподключите. |