API Notiondesk trả lời mọi lỗi bằng cùng một gói JSON và một tiêu đề code có thể đọc được bằng máy, giới hạn mỗi khóa ở mức 120 lần đọc và 20 lần ghi mỗi phút, và cho phép bạn thử lại bất kỳ thay đổi nào một cách an toàn với tiêu đề Idempotency-Key. Bài viết này liệt kê mọi mã lỗi của API Notiondesk, giải thích các giới hạn tốc độ và tiêu đề của chúng, và chỉ ra cách xây dựng các lần thử lại mà không bao giờ thay đổi bất cứ điều gì hai lần.
Phong bì lỗi API Notiondesk
Mọi lỗi đều có cùng hình dạng và mọi trường dữ liệu đều luôn hiện diện:
{
"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."}
]
}| Cánh đồng | Nghĩa |
|---|---|
object | Luôn luôn __ĐƯỢC BẢO TỒN_78__ |
code | Lỗi có thể đọc được bằng máy. Chỉ rẽ nhánh mã của bạn tại trường này. |
message | Một lời giải thích dễ hiểu đối với con người. Nó có thể thay đổi, vì vậy đừng bao giờ phân tích nó một cách chi tiết. |
request_id | Xác định yêu cầu khi bạn liên hệ với bộ phận hỗ trợ. null khi yêu cầu thất bại trước khi đến được tuyến đường, ví dụ như trên một đường dẫn không xác định. |
errors | Các sự cố ở cấp độ trường, mỗi sự cố đều có field và message. Trống khi lỗi không liên quan đến một đầu vào cụ thể. |
Cách field đặt tên cho một giá trị
- Tên của trường cấp cao nhất là:
page_size.
- Một trường bên trong danh sách đặt tên cho danh sách, mục trong ngoặc, sau đó là tên trường:
items[fr].page_title.
- Dấu ngoặc vuông chứa mã định danh của mục nhập như bạn đã gửi (
localetrongitems,category_idtrongchangelog_categories) khi mỗi mục nhập có một mã định danh riêng biệt. Nếu không, nó sẽ chứa vị trí dựa trên chỉ số 0 của mục nhập:items[0].locale.
- Có vấn đề với toàn bộ yêu cầu đã được
"field": nullkhắc phục.
Mã lỗi API Notiondesk
code | Trạng thái HTTP | Nghĩa | Nên làm gì |
|---|---|---|---|
authentication_error | 401 | Khóa hoặc mã truy cập bị thiếu hoặc không thể sử dụng được. | Kiểm tra khóa, thời hạn hết hạn và gói dịch vụ. Xem phần Xác thực bằng API Notiondesk |
insufficient_scope | 403 | Thông tin xác thực này thiếu phạm vi mà tuyến đường yêu cầu. | Sử dụng khóa có phạm vi được đặt tên trong WWW-Authenticate |
permission_denied | 402, 403 | Thông tin xác thực không thể thực hiện hành động này trên tài nguyên này, ví dụ như vì gói dịch vụ thiếu tính năng đó. | Kiểm tra gói cước và cài đặt trung tâm trợ giúp. Không thử lại nếu chưa thay đổi. |
invalid_version | 400 | Tiêu đề nd-version chỉ định một phiên bản không xác định. | Gửi 2026-10-16 hoặc bỏ qua phần tiêu đề. |
validation_error | 400, 422 | Một tham số hoặc trường dữ liệu không hợp lệ, không xác định hoặc nằm ngoài phạm vi cho phép. | Sửa các trường được liệt kê trong errors |
not_found | 404, 405 | Đường dẫn, tài nguyên hoặc phương thức đó không tồn tại. | Kiểm tra ID và phương thức. |
conflict_error | 409 | Yêu cầu này xung đột với trạng thái hiện tại, ví dụ như quá trình đồng bộ hóa đang diễn ra. | Chờ một lát rồi thử lại. |
idempotency_key_invalid | 400 | Tiêu đề Idempotency-Key trống hoặc dài hơn 255 ký tự. | Gửi từ 1 đến 255 ký tự |
idempotency_key_reused | 422 | Mã Idempotency-Key đã được sử dụng cho một yêu cầu khác. | Sử dụng khóa mới cho yêu cầu mới |
request_in_progress | 409 | Một yêu cầu có cùng mã Idempotency-Key vẫn đang được xử lý. | Chờ một chút, sau đó thử lại với cùng một phím. |
rate_limited | 429 | Quá nhiều yêu cầu | Chờ Retry-After giây |
internal_error | 500 trở lên | Notiondesk thất bại | Hãy thử lại sau và trích dẫn mã request_id nếu bạn liên hệ với bộ phận hỗ trợ. |
Yêu cầu truy cập trung tâm trợ giúp hoặc tài nguyên bên ngoài không gian làm việc của bạn sẽ trả về mã lỗi 404 not_found, vì vậy API sẽ không bao giờ tiết lộ liệu nó có tồn tại hay không.
Giới hạn tốc độ API Notiondesk
Mỗi khóa API và mỗi lần cấp quyền OAuth đều có hai ngân sách yêu cầu, được tính toán trong khoảng thời gian một phút trượt:
| Ngân sách | Tuyến đường | Số yêu cầu mỗi phút |
|---|---|---|
| Đọc | GET routes | 120 |
| Viết | Các tuyến đường POST, PATCH và DELETE | 20 |
Các báo cáo phân tích cũng được tính vào ngân sách 30 yêu cầu mỗi phút cho mỗi trung tâm trợ giúp , được chia sẻ bởi mọi khóa và ứng dụng OAuth của không gian làm việc.
Phản hồi có ba tiêu đề:
| Tiêu đề | Nghĩa |
|---|---|
X-RateLimit-Limit | Các yêu cầu được cho phép trong khoảng thời gian hiện tại |
X-RateLimit-Remaining | Các yêu cầu còn lại trong cửa sổ hiện tại |
Retry-After | Số giây cho đến khi yêu cầu tiếp theo được chấp nhận; 0 trong khi vẫn còn yêu cầu |
Yêu cầu về ngân sách trả lời 429 rate_limited. Chờ số giây trong Retry-After trước khi gửi yêu cầu tiếp theo.
Thử lại một cách an toàn với Idempotency-Key
Lỗi hết thời gian chờ mạng khiến bạn không chắc chắn liệu thay đổi đã được thực hiện thành công hay chưa. Tiêu đề Idempotency-Key cho phép bạn gửi lại cùng một yêu cầu mà không cần thay đổi bất cứ điều gì hai lần.
Mọi tuyến đường thay đổi đều chấp nhận điều này: thay đổi chuyển hướng trang, cập nhật cài đặt và thương hiệu, thay đổi tích hợp và các trình kích hoạt đồng bộ hóa. Hãy gửi một giá trị duy nhất từ 1 đến 255 ký tự, chẳng hạn như UUID, trong lần thử đầu tiên và gửi cùng một giá trị đó trong mỗi lần thử lại:
Điều gì xảy ra khi thử lại:
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"}'| Thử lại | Kết quả |
|---|---|
| Cùng một khóa, cùng một nội dung, cùng một đường dẫn, sau khi yêu cầu đầu tiên hoàn tất. | Phản hồi đầu tiên vẫn như cũ, bao gồm cả trạng thái và nội dung, với X-Idempotent-Replay: true. Không có gì thay đổi. |
| Sử dụng cùng một khóa trong khi yêu cầu đầu tiên vẫn đang chạy. | 409 request_in_progress. Chờ và thử lại. |
| Cùng một khóa nhưng khác nhau về ID thân khóa, tuyến đường hoặc đường dẫn. | 422 __ĐƯỢC BẢO QUẢN_24__ |
| Cùng một khóa và cùng một nội dung sau yêu cầu đầu tiên đã trả về lỗi. | Yêu cầu được chạy lại |
Phản hồi thành công sẽ mang theo X-Idempotent-Replay: false lần đầu tiên và true khi phát lại. Notiondesk giữ khóa trong ít nhất 24 giờ. Khóa thuộc về khóa API hoặc cấp quyền OAuth đã gửi nó, và cấp quyền OAuth giữ nguyên khóa của nó ngay cả khi làm mới mã thông báo.
Nếu không có tiêu đề, yêu cầu chỉ được thực hiện một lần, và khi thử lại sẽ thực hiện lại lần nữa.
Một chiến lược thử lại hiệu quả
- Tạo một
Idempotency-Keycho mỗi thay đổi logic và sử dụng lại nó cho mỗi lần thử lại thay đổi đó.
- Tại
429 rate_limited, chờRetry-Aftergiây, sau đó thử lại.
- Trên
409 request_in_progress, hãy đợi vài giây, sau đó thử lại với cùng một phím. Trên409 conflict_error, quá trình đồng bộ hóa trung tâm trợ giúp đang chạy: hãy đợi vài phút trước khi bạn kích hoạt lại, hoặc bỏ qua lần chạy này.
- Trên
500trở lên, hoặc khi xảy ra lỗi mạng, hãy thử lại với phương pháp lùi thời gian theo cấp số nhân, ví dụ sau 1, 2, 4 và 8 giây.
- Không bao giờ thử lại
400,401,403,404hoặc422mà không thay đổi. Hãy sửa yêu cầu trước.
Trong JavaScript, đối với bất kỳ tuyến đường nào thay đổi một giá trị nào đó, nó sẽ dừng lại ở conflict_error và để lại quyết định đó cho mã của bạn:
Câu hỏi thường gặp
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`);
} Giới hạn tốc độ của API Notiondesk là gì?
Mỗi khóa API hoặc cấp quyền OAuth cho phép 120 yêu cầu đọc và 20 yêu cầu ghi mỗi phút, cộng thêm 30 yêu cầu phân tích mỗi phút cho mỗi trung tâm trợ giúp. Yêu cầu vượt quá ngân sách sẽ trả về mã lỗi 429 với tiêu đề Retry-After.
Mã của tôi nên kiểm tra trường nào khi xảy ra lỗi?
code. Đây là bộ phân loại duy nhất ổn định và có thể đọc được bằng máy. message dành cho con người và có thể thay đổi.
Tôi nên gửi gì cho bộ phận hỗ trợ khi yêu cầu không thành công?
Thông tin request_id từ phản hồi lỗi, tuyến đường bạn đã gọi và thời gian yêu cầu.
Liệu việc thử lại thao tác đồng bộ hóa có an toàn không?
Vâng, với Idempotency-Key. Thử lại với cùng một khóa sẽ trả về kết quả đầu tiên và không có gì được xếp vào hàng đợi. Nếu không có khóa, việc kích hoạt đồng bộ hóa trang web thứ hai trong khi trang web đầu tiên đang chạy sẽ trả về lỗi 409 conflict_error.