Коды ошибок
Ответы API с ошибками и что с ними делать.
Если запрос не удался, API отвечает кодом HTTP 4xx или 5xx и телом в едином формате. Логику стройте на поле code: оно стабильно, а текст message может уточняться.
Формат ошибки
{
"error": {
"code": "validation_error",
"message": "Поле due_time нельзя задать без due_date.",
"details": {
"fields": [
{ "field": "due_time", "issue": "requires_due_date" }
]
},
"request_id": "req_3Mb8Rf"
}
}| Поле | Что это |
|---|---|
code | Машиночитаемый код из таблицы ниже. На него можно завязывать логику. |
message | Описание на русском для человека и логов. Текст может меняться — не разбирайте его программно. |
details | Подробности. Для validation_error — массив fields, для unprocessable — reason, для rate_limited — retry_after, для forbidden — missing_scope или required_plan. Бывает пустым объектом. |
request_id | Идентификатор запроса, тот же, что в заголовке X-Request-Id. Приложите его к письму в поддержку. |
Коды ошибок
| Код | Причина | Что делать |
|---|---|---|
400 validation_error | Тело или параметры не прошли проверку: нет обязательного поля, неверный тип, дата без часового пояса, неизвестное значение. | Исправьте запрос по details.fields. Повтор без изменений не поможет. |
401 unauthorized | Нет заголовка Authorization, токен неверный или отозван, его владельца удалили из пространства. | Проверьте токен. Если он утёк — отзовите и выпустите новый в Настройки → API. |
403 forbidden | Токен верный, но прав не хватает: нет нужного скоупа, роль не позволяет действие или тариф без доступа к API. | Выпустите токен с нужным скоупом, проверьте роль владельца токена и тариф. |
404 not_found | Объекта нет, он недоступен владельцу токена или в пути опечатка. | Проверьте id и что владелец токена состоит в нужном списке. |
409 conflict | Idempotency-Key уже использован с другим телом, или первый запрос с этим ключом ещё выполняется. | Для нового действия — новый ключ. Для повтора — тот же ключ и то же тело; при in_progress подождите пару секунд. |
413 payload_too_large | Тело запроса больше 1 МБ. | Сократите тело. Описание задачи — до 20 000 символов. |
422 unprocessable | Запрос корректен, но действие невозможно: список в архиве, достигнут лимит, исполнитель не состоит в списке. | Смотрите details.reason — таблица причин ниже. Повтор без изменения данных не поможет. |
429 rate_limited | Превышен лимит: 300 запросов в минуту на Команде, 1 200 на Бизнесе. | Подождите Retry-After секунд и повторите. Подробнее о лимитах. |
500 internal_error | Ошибка на стороне DoneBy. | Повторите с экспоненциальной паузой. Если ошибка не уходит — напишите на support@doneby.app и приложите request_id. |
503 maintenance | Плановые работы или кратковременная перегрузка. | Повторите после Retry-After. О плановых работах администраторы пространства узнают письмом заранее. |
400 или 422
400 значит, что запрос собран неправильно и сервер даже не пытался его выполнить: это чинится в коде интеграции. 422 значит, что с форматом всё в порядке, но текущее состояние данных не даёт выполнить действие: это обычно чинится в самих данных — вернуть список из архива, добавить человека в список, разгрузить переполненный список.
{
"error": {
"code": "unprocessable",
"message": "Список «Релиз 2.3» в архиве: задачи в нём нельзя менять.",
"details": { "reason": "list_archived", "list_id": "lst_Vb1Qe6" },
"request_id": "req_2Wd8Lz"
}
}| details.reason | Когда бывает |
|---|---|
list_archived | Задачу в архивном списке пытаются изменить, выполнить или создать. |
limit_reached | Достигнут лимит из раздела Лимиты: например, 5 000 задач в списке или 100 подзадач. В details.limit — какой именно. |
assignee_not_in_list | Исполнитель — участник пространства, но не состоит в этом списке. |
subtask_depth | Подзадачу пытаются создать у подзадачи — вложенность только один уровень. |
repeat_requires_due_date | У задачи есть repeat, но нет due_date, от которого считать повторения. |
recurring_reopen | reopen для повторяющейся задачи — следующее повторение уже назначено. |
Какие ошибки повторять
| Ответ | Повторять? |
|---|---|
429, 503 | Да, после паузы из Retry-After. |
500 | Да, с экспоненциальной паузой, не больше пяти попыток. |
| Таймаут, обрыв соединения | Да. POST — только с тем же Idempotency-Key. |
409 с in_progress | Да, через пару секунд, с тем же ключом и телом. |
400, 401, 403, 404, 413, 422 | Нет. Сначала исправьте запрос, токен или данные. |
Важно
Не повторяйте POST без Idempotency-Key. Если первый запрос на самом деле выполнился, а не дошёл только ответ, повтор создаст вторую задачу.
Готовый код с паузами и повторами — в разделе Лимиты.
Пример ответа 401
HTTP/1.1 401 Unauthorized
Content-Type: application/json; charset=utf-8
X-Request-Id: req_5Nf1Bt
{
"error": {
"code": "unauthorized",
"message": "Токен не найден или отозван.",
"details": {},
"request_id": "req_5Nf1Bt"
}
}Пример ответа 403
{
"error": {
"code": "forbidden",
"message": "У токена нет права tasks:write.",
"details": { "missing_scope": "tasks:write" },
"request_id": "req_8Qs4Jd"
}
}Если ничего не помогает
Напишите на support@doneby.app: метод и путь, примерное время запроса, request_id и тело ответа. Сам токен в письмо не вкладывайте — для разбора он не нужен, а по request_id мы найдём запрос в журналах.
Совет
Логируйте X-Request-Id каждого неудачного запроса вместе с кодом ответа. Когда что-то пойдёт не так, разбор займёт минуты, а не переписку на день.