Notiondesk API は、すべてのエラーに対して同じ JSON エンベロープと機械可読な code ヘッダーで応答し、各キーの読み取り回数を 1 分あたり 120 回、書き込み回数を 20 回に制限し、Idempotency-Key ヘッダーを使用して変更を安全に再試行できるようにします。この記事では、すべての Notiondesk API エラー コードの一覧、レート制限とそのヘッダーの説明、および同じ操作を二度行わない再試行方法を示します。
Notiondesk API エラーエンベロープ
すべてのエラーは同じ形状に対応し、すべてのフィールドは常に存在します。
{
"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 | 常にerror |
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となっています。
Notiondesk APIエラーコード
code | HTTPステータス | 意味 | 何をするか |
|---|---|---|---|
authentication_error | 401 | キーまたはアクセストークンが見つからないか、使用できません。 | キー、その有効期限、およびプランを確認してください。__ ND_TERM_5bcd8dee__ API を使用した認証を参照してください。 |
insufficient_scope | 403 | 認証情報には、ルートに必要なスコープがありません。 | WWW-Authenticate で指定されたスコープを持つキーを使用してください。 |
permission_denied | 402、403 | この認証情報では、このリソースに対してこの操作を実行できません。たとえば、プランにその機能が欠けているためです。 | プランとヘルプセンターの設定を確認してください。変更せずに再試行しないでください。 |
invalid_version | 400 | nd-version ヘッダーは不明なバージョンを指定しています | 2026-10-16 を送信するか、ヘッダーを省略してください。 |
validation_error | 400、422 | パラメータまたはボディフィールドが無効、不明、または範囲外です | errorsに記載されているフィールドを修正してください。 |
not_found | 404、405 | パス、リソース、またはメソッドが存在しません | IDとメソッドを確認してください |
conflict_error | 409 | リクエストが現在の状態と競合しています。たとえば、同期処理が既に実行中です。 | 待ってからもう一度試してください。 |
idempotency_key_invalid | 400 | Idempotency-Key ヘッダーが空であるか、255 文字を超えています | 1~255文字を送信 |
idempotency_key_reused | 422 | Idempotency-Key は既に別のリクエストで使用されています | 新しいリクエストには新しいキーを使用してください |
request_in_progress | 409 | 同じ Idempotency-Key を持つリクエストがまだ実行中です | しばらく待ってから、同じキーで再試行してください。 |
rate_limited | 429 | リクエストが多すぎます | Retry-After秒間待機します |
internal_error | 500以上 | Notiondesk が失敗しました | 後でもう一度試してください。サポートに問い合わせる場合は、request_id を引用してください。 |
ワークスペース外のヘルプセンターやリソースへのリクエストは404 not_foundという応答を返すため、APIはそれが存在するかどうかを公開しません。
Notiondesk APIレート制限
各APIキーと各OAuthグラントには、1分間のスライディングウィンドウでカウントされる2つのリクエストバジェットがあります。
| 予算 | ルート | 1分あたりのリクエスト数 |
|---|---|---|
| 読む | GET ルート | 120 |
| 書く | POST、PATCH、およびDELETEルート | 20 |
分析レポートも、ワークスペース内のすべてのキーとOAuthアプリで共有される、ヘルプセンターごとに1分あたり30件のリクエストという予算にカウントされます。
回答には3つのヘッダーが含まれます。
| ヘッダ | 意味 |
|---|---|
X-RateLimit-Limit | 現在のウィンドウで許可されているリクエスト |
X-RateLimit-Remaining | 現在のウィンドウに残されたリクエスト |
Retry-After | 次のリクエストが受け入れられるまでの秒数。0 リクエストが残っている間 |
予算を超えるリクエストに対しては、429 rate_limited という応答が返されます。次のリクエストを送信する前に、Retry-After で指定された秒数だけ待機してください。
Idempotency-Key を使用して安全に再試行してください。
ネットワークタイムアウトが発生すると、変更が正しく反映されたかどうかが不明確になります。Idempotency-Key ヘッダーを使用すると、何も変更せずに同じリクエストを再度送信できます。
何らかの変更を加えるすべてのルートは、その変更を受け入れます。ページリダイレクトの変更、設定やブランディングの更新、統合の変更、同期トリガーなどです。最初の試行では、UUIDなどの1~255文字の一意の値を送信し、再試行のたびに同じ値を送信します。
再試行時に何が起こるか:
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。しばらく待ってから再試行してください。 |
| 同じキーでも、本体、ルート、またはパスIDが異なる | 422 idempotency_key_reused |
| 最初の要求でエラーが返された後も、同じキーと本文を使用しています。 | リクエストが再度実行されます |
応答が成功した場合、初回はX-Idempotent-Replay: false、再送信時はtrueが渡されます。Notiondeskはキーを少なくとも24時間保持します。キーは、それを送信したAPIキーまたはOAuthグラントに属し、OAuthグラントはトークンの更新後もキーを保持します。
ヘッダーがない場合、リクエストは一度実行され、再試行は再度実行されます。
効果的な再試行戦略
- 論理的な変更ごとに
Idempotency-Keyを 1 つ生成し、その変更を再試行するたびにそれを再利用します。
429 rate_limitedの場合、Retry-After秒間待機してから再試行します。
409 request_in_progressでは、数秒待ってから同じキーで再試行してください。409 conflict_errorでは、ヘルプセンターの同期が既に実行中です。数分待ってから再度トリガーするか、この実行をスキップしてください。
500以上、またはネットワークエラーが発生した場合は、1秒、2秒、4秒、8秒などの指数バックオフで再試行します。
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`);
} Notiondesk APIのレート制限は何ですか?
各APIキーまたはOAuth認証につき、1分あたり120件の読み取りリクエストと20件の書き込みリクエスト、さらに各ヘルプセンターにつき1分あたり30件の分析リクエストが制限されます。制限を超えるリクエストに対しては、429番のレスポンスにRetry-Afterヘッダーが付加されます。
エラー発生時に、私のコードはどのフィールドをチェックすべきでしょうか?
code。これは唯一安定した、機械可読な分類器です。messageは人間用であり、変更される可能性があります。
リクエストが失敗した場合、サポートに何を送信すればよいですか?
エラー応答に含まれるrequest_id、呼び出したルート、およびリクエストの時刻。
同期トリガーを再試行しても安全ですか?
はい、Idempotency-Key が返されます。同じキーで再試行すると、最初の結果が再び返され、何もキューに追加されません。キーがない場合、最初のサイト同期トリガーが実行中に 2 番目のサイト同期トリガーを実行すると、409 conflict_error が返されます。