Обработка ошибок API Notiondesk, ограничений скорости и повторных попыток.

Notiondesk Коды ошибок API и их обертка, ограничения скорости чтения 120 и записи 20 в минуту, функция «Повторить попытку» и безопасные повторные попытки с ключом идемпотентности.

2 мин чтения

API Notiondesk обрабатывает каждую ошибку с помощью одного и того же JSON-конверта и машиночитаемого заголовка code, ограничивает количество операций чтения и записи для каждого ключа до 120 в минуту и ​​позволяет безопасно повторить любое изменение с помощью заголовка Idempotency-Key. В этой статье перечислены все коды ошибок API Notiondesk, объясняются ограничения скорости и их заголовки, а также показано, как создавать сценарии повторных попыток, которые никогда не изменят ничего дважды.

Ошибка API Notiondesk

Каждая ошибка имеет одинаковую форму, и каждое поле всегда присутствует:

{
  "object": "error",
  "code": "validation_error",
  "message": "The request parameters are invalid.",
  "request_id": "0f2c1e94-7a1b-4c2d-9e3f-5a6b7c8d9e0f",
  "errors": [
    {"field": "page_size", "message": "This value should be between 1 and 100."}
  ]
}
Поле Значение
objectВсегда __СОХРАНЕНО_78__
codeМашинночитаемая ошибка. Разверните свой код, используя только это поле.
messageОбъяснение, понятное человеку. Оно может меняться, поэтому никогда не пытайтесь его расшифровать.
request_idИдентифицирует запрос при обращении в службу поддержки. null, если запрос не удался до достижения маршрута, например, по неизвестному пути.
errorsПроблемы на уровне полей, каждая с field и message. Пусто, если ошибка не связана с конкретным входным параметром.

Как field обозначает значение

  • Поле верхнего уровня имеет свое название: page_size.
  • Внутри списка поле задает имя списка, затем в скобках указывается запись, а затем само поле: items[fr].page_title.
  • В скобках хранится идентификатор записи в том виде, в котором вы его отправили (locale в items, category_id в changelog_categories), если каждая запись имеет свой уникальный идентификатор. В противном случае в скобках хранится позиция записи, начиная с нуля: items[0].locale.
  • Проблема с запросом в целом имеет код "field": null.

Коды ошибок API Notiondesk

codeHTTP-статус Значение Что делать
authentication_error401 Ключ или токен доступа отсутствует или не может быть использован. Проверьте ключ, срок его действия и план. См. раздел «Аутентификация с помощью API Notiondesk».
insufficient_scope403 Данные учетные данные не соответствуют требованиям маршрута. Используйте ключ с областью действия, указанной в WWW-Authenticate
permission_denied402, 403 Учетные данные не могут выполнить это действие с данным ресурсом, например, потому что в плане отсутствует соответствующая функция. Проверьте тарифный план и настройки справочного центра. Не повторяйте попытку без изменений.
invalid_version400 Заголовочный файл nd-version указывает на неизвестную версию. Отправьте 2026-10-16 или опустите заголовок.
validation_error400, 422 Параметр или поле тела запроса недопустимы, неизвестны или выходят за пределы допустимого диапазона. Исправьте поля, перечисленные в errors
not_found404, 405 Путь, ресурс или метод не существуют. Проверьте идентификаторы и метод.
conflict_error409 Запрос противоречит текущему состоянию, например, синхронизация уже выполняется. Подождите, затем попробуйте снова.
idempotency_key_invalid400 Заголовок Idempotency-Key пуст или содержит более 255 символов. Отправьте от 1 до 255 символов
idempotency_key_reused422 Номер Idempotency-Key уже был использован для другого запроса. Используйте новый ключ для нового запроса.
request_in_progress409 Запрос с тем же номером Idempotency-Key всё ещё выполняется. Подождите, затем попробуйте снова с тем же ключом.
rate_limited429 Слишком много запросов Подождите Retry-After секунд
internal_error500 и выше Notiondesk failed Попробуйте позже и укажите код request_id при обращении в службу поддержки.

Запрос к справочному центру или ресурсу за пределами вашего рабочего пространства приводит к ошибке 404 not_found, поэтому API никогда не раскрывает информацию о его существовании.

Notiondesk Ограничения скорости API

Каждый API-ключ и каждое разрешение OAuth имеют два лимита запросов, отсчитываемых в течение скользящего минутного окна:

Бюджет Маршруты Запросов в минуту
Читает __СОХРАНЕННЫЕ_38__ маршруты 120
Пишет маршруты POST, PATCH и DELETE 20

Аналитические отчеты также учитываются в рамках бюджета в 30 запросов в минуту на каждый центр поддержки , который распределяется между всеми приложениями Key и OAuth в рабочем пространстве.

Ответы содержат три заголовка:

Заголовок Значение
X-RateLimit-LimitЗапросы, разрешенные в текущем окне
X-RateLimit-RemainingЗапросы, оставленные в текущем окне
Retry-AfterСекунды до принятия следующего запроса; 0 пока остаются запросы

Запрос, превышающий бюджет, отвечает 429 rate_limited. Подождите количество секунд в Retry-After, прежде чем отправлять следующий запрос.

Примечание: Ограничения скорости рассчитываются для каждого ключа или каждого разрешения OAuth, а не для рабочего пространства. Две интеграции с отдельными ключами не замедляют друг друга, за исключением общего бюджета аналитики.

Повторите попытку безопасно с помощью Idempotency-Key

Истекло время ожидания в сети, поэтому вы не уверены, были ли внесены изменения. Заголовок Idempotency-Key позволяет отправить тот же запрос повторно, не внося никаких изменений дважды.

Принимаются любые изменения маршрута: изменения перенаправления страницы, обновления настроек и фирменной символики, изменения интеграции и триггеры синхронизации. При первой попытке отправляется уникальное значение от 1 до 255 символов, например, UUID, и то же значение при каждой повторной попытке:

Что происходит при повторной попытке:

curl -X POST "https://api.notiondesk.so/sites/c74781f6-1aea-4e17-ab23-bbb8b4d174b6/page-redirects" \
  -H "Authorization: Bearer $NOTIONDESK_API_KEY" \
  -H "nd-version: 2026-10-16" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f0d6b1e-create-getting-started" \
  -d '{"type": "article", "source_path": "/legacy/getting-started", "target_id": "1761580412", "locale": "en"}'
Повторить попытку Результат
Тот же ключ, то же тело запроса, тот же маршрут после завершения первого запроса. Первый ответ снова, включая статус и текст, с X-Idempotent-Replay: true. Ничего не меняется.
Используйте тот же ключ, пока выполняется первый запрос. 409 request_in_progress. Подождите и повторите попытку.
Тот же ключ, но с другими идентификаторами тела запроса, маршрута или пути. 422 __СОХРАНЕНО_24__
Тот же ключ и то же тело запроса после первого ответа привели к ошибке. Запрос выполняется снова.

Успешный ответ в первый раз содержит X-Idempotent-Replay: false, а при повторном воспроизведении — true. Notiondesk хранит ключ не менее 24 часов. Ключ принадлежит API-ключу или OAuth-гранту, который его отправил, и OAuth-грант сохраняет свои ключи при обновлении токена.

Без заголовка запрос выполняется один раз, и повторяется.

Эффективная стратегия повторных попыток

  1. Для каждого логического изменения генерируйте один объект Idempotency-Key и используйте его повторно при каждой попытке повторного внесения этого изменения.
  1. При достижении 429 rate_limited подождите Retry-After секунд, затем повторите попытку.
  1. В 409 request_in_progress подождите несколько секунд, затем повторите попытку с тем же ключом. В 409 conflict_error уже запущена синхронизация справочного центра: подождите несколько минут, прежде чем запускать ее снова, или пропустите этот запуск.
  1. При возникновении ошибки 500 и выше, или сетевой ошибки, повторите попытку с экспоненциальной задержкой, например, через 1, 2, 4 и 8 секунд.
  1. Никогда не пытайтесь повторно отправить запросы 400, 401, 403, 404 или 422 без изменений. Сначала исправьте запрос.

В JavaScript для любого маршрута, который что-то изменяет, процесс останавливается на conflict_error и оставляет принятие решения вашему коду:

Часто задаваемые вопросы

import { randomUUID } from "node:crypto";

const sleep = (seconds) => new Promise((resolve) => setTimeout(resolve, seconds * 1000));

async function notiondeskRequest(method, path, body, attempts = 5) {
  const idempotencyKey = randomUUID();

  for (let attempt = 0; attempt < attempts; attempt++) {
    let response;
    try {
      response = await fetch(`https://api.notiondesk.so${path}`, {
        method,
        headers: {
          Authorization: `Bearer ${process.env.NOTIONDESK_API_KEY}`,
          "nd-version": "2026-10-16",
          "Content-Type": "application/json",
          "Idempotency-Key": idempotencyKey,
        },
        body: body ? JSON.stringify(body) : undefined,
      });
    } catch {
      await sleep(2 ** attempt);
      continue;
    }

    if (response.ok) {
      return response.status === 204 ? null : response.json();
    }

    const error = await response.json().catch(() => ({}));
    const retryable = response.status === 429 || response.status >= 500 || error.code === "request_in_progress";
    if (!retryable) {
      throw new Error(`${response.status} ${error.code}: ${error.message}`);
    }

    const retryAfter = Number(response.headers.get("Retry-After"));
    await sleep(retryAfter > 0 ? retryAfter : 2 ** attempt);
  }

  throw new Error(`Notiondesk request failed after ${attempts} attempts`);
}

Каковы ограничения скорости запросов к API Notiondesk?

120 запросов на чтение и 20 запросов на запись в минуту для каждого ключа API или разрешения OAuth, плюс 30 запросов на аналитику в минуту для каждого центра поддержки. Запрос, превышающий лимит, получает ответ 429 с заголовком Retry-After.

Какое поле должен проверять мой код при возникновении ошибки?

code. Это единственный стабильный машиночитаемый классификатор. message предназначен для людей и может изменяться.

Что мне следует отправить в службу поддержки, если запрос не удался?

Данные request_id из ответа об ошибке, вызванный вами маршрут и время запроса.

Безопасно ли повторять запуск синхронизации?

Да, с ключом Idempotency-Key. Повторная попытка с тем же ключом снова выдает первый результат и ничего не ставит в очередь. Без ключа запуск синхронизации второго сайта во время работы первого приводит к ошибке 409 conflict_error.

Что дальше?

Связанные статьи

Эта страница была полезной?

Still need help? Ask us