§ 11.1

Лимиты

Ограничения на задачи, вложения и запросы к API.

обновлено 18 сентября 20265 мин чтения

Лимиты держат DoneBy быстрым для всех. Обычные списки до них не доходят, но если вы строите интеграцию или переносите большой архив задач, лучше знать их заранее.

Задачи, списки и файлы

Что ограниченоЛимит
Задач в одном списке5 000
Подзадач у задачи100
Пунктов в чек-листе200
Размер одного вложения100 МБ
Длина названия задачи500 символов
Длина описания20 000 символов
Напоминаний у задачи5
Сохранённых подборок50 на участника

Если упереться в лимит в приложении, DoneBy покажет подсказку прямо в поле. Через API придёт 422 unprocessable с указанием лимита в details — см. Коды ошибок.

Совет

5 000 задач в списке — много, но выполненное копится годами. Раз в квартал переносите закрытые проекты в архивный список: рабочие списки останутся обозримыми, а история никуда не денется.

Лимиты по тарифам

ВозможностьСтартКомандаБизнес
Участники1до 50от 10, без верхнего лимита
Гостевой доступ—до 5 гостейбез лимита
Вложения5 ГБ10 ГБ на участника50 ГБ на участника
REST API—300 запросов/мин1200 запросов/мин
Вебхуки—до 20 адресовдо 100 адресов
История изменений30 дней90 дней1 год + журнал действий
Выгрузка по расписанию——есть

Полное сравнение — на странице Тарифы.

Лимиты API

ПараметрЗначение
Запросов в минуту, тариф Команда300
Запросов в минуту, тариф Бизнес1 200
Как считаетсяНа рабочее пространство, по всем токенам вместе
Размер страницы (limit)от 1 до 100, по умолчанию 50
Размер тела запроса1 МБ
Срок жизни Idempotency-Key24 часа
Время на ответ вебхуку10 секунд
Адресов вебхуковКоманда — до 20 адресов, Бизнес — до 100 адресов

Важно

Лимит общий для пространства. Ночная сверка, которая выбирает весь запас за минуту, оставит без запросов интеграцию, создающую задачи из CRM. Разносите тяжёлые фоновые задачи по времени или ограничивайте их скорость на своей стороне.

Заголовки X-RateLimit

Каждый ответ API сообщает, сколько запросов осталось:

ЗаголовокЗначение
X-RateLimit-LimitЛимит запросов в минуту для пространства: 300 или 1 200.
X-RateLimit-RemainingСколько запросов осталось в текущем окне.
X-RateLimit-ResetКогда окно обновится, — Unix-время в секундах.
Заголовки обычного ответа
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 287
X-RateLimit-Reset: 1758200460
X-Request-Id: req_4Hc9Qm

Если X-RateLimit-Remaining подходит к нулю, лучше притормозить заранее, чем ловить 429: подождите до X-RateLimit-Reset и продолжайте.

Что делать при 429

Ответ при превышении лимита
HTTP/1.1 429 Too Many Requests
Content-Type: application/json; charset=utf-8
Retry-After: 18
X-RateLimit-Limit: 300
X-RateLimit-Remaining: 0
X-RateLimit-Reset: 1758200460
X-Request-Id: req_7Yp2kX

{
  "error": {
    "code": "rate_limited",
    "message": "Слишком много запросов. Повторите через 18 секунд.",
    "details": { "retry_after": 18 },
    "request_id": "req_7Yp2kX"
  }
}
  1. Прочитайте Retry-After — сколько секунд подождать. Повтор раньше срока снова получит 429.
  2. Если заголовка нет (например, при 500), ждите по экспоненте: 1, 2, 4, 8 секунд и так далее, с небольшим случайным разбросом и не дольше минуты.
  3. Ограничьте число попыток — пяти обычно хватает — и записывайте в лог X-Request-Id неудачных запросов.
  4. Повторяйте POST с тем же Idempotency-Key, что и в первой попытке: тогда повтор не создаст дубль.
withRetry.js
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
const RETRYABLE = new Set([429, 500, 503]);

export async function withRetry(send, { attempts = 5, maxDelayMs = 60000 } = {}) {
  for (let attempt = 0; ; attempt++) {
    let res;
    try {
      res = await send();
    } catch (networkError) {
      if (attempt + 1 >= attempts) throw networkError;
    }
    if (res && !RETRYABLE.has(res.status)) return res;
    if (attempt + 1 >= attempts) return res;

    const retryAfter = res ? Number(res.headers.get('Retry-After')) : 0;
    const backoff = Math.min(1000 * 2 ** attempt, maxDelayMs);
    const delay = retryAfter > 0 ? retryAfter * 1000 : backoff;
    await sleep(delay + Math.random() * 250);
  }
}
Создать задачу с повторами
const key = crypto.randomUUID();

const res = await withRetry(() =>
  fetch(process.env.DONEBY_API_URL + '/tasks', {
    method: 'POST',
    headers: {
      Authorization: `Bearer ${process.env.DONEBY_TOKEN}`,
      'Content-Type': 'application/json',
      'Idempotency-Key': key,
    },
    body: JSON.stringify({
      title: 'Передать показания счётчиков',
      due_date: '2026-09-25',
    }),
  })
);

В скриптах на curl достаточно флага --retry: curl сам повторяет 429 и 503 и учитывает Retry-After.

bash
curl --retry 5 --retry-max-time 120 \
  "https://doneby.app/api/v1/tasks?limit=100" \
  -H "Authorization: Bearer $DONEBY_TOKEN"

Как тратить меньше запросов

  • Вебхуки вместо опроса. Проверка раз в 5 секунд — это 12 запросов в минуту на одну задачу интеграции, даже когда ничего не меняется. Вебхук приходит только тогда, когда есть что сообщить.
  • `updated_since` вместо полной выборки. При синхронизации забирайте только изменённые задачи.
  • `limit=100`. Полная выгрузка займёт вдвое меньше запросов, чем со страницами по 50.
  • Кэш для редко меняющегося. Участников и списки достаточно перечитывать по вебхукам member.joined, list.created и list.archived.
см. также
Статья помогла?Отметьте галочкой — так мы понимаем, какие статьи дописать первыми.