Phân trang, tính bất biến và xử lý lỗi
API Ody sử dụng phân trang con trỏ không rõ ràng trên các điểm cuối danh sách của nó, tiêu đề Idempotency-Key để thử lại gửi tin nhắn an toàn và một phong bì lỗi thống nhất với ID yêu cầu trên mọi phản hồi — hướng dẫn này bao gồm cả ba.
Phân trang bằng con trỏ
GET /v1/api/contacts và GET /v1/api/conversations phân trang bằng ?limit= và ?cursor=:
curl "https://api.ody.co/v1/api/contacts?limit=100" \
-H "Authorization: Bearer ody_live_…"
Phản hồi bao gồm một nextCursor — hãy truyền lại nó dưới dạng ?cursor= để lấy trang tiếp theo và dừng lại khi nó là null:
{ "contacts": [ … ], "nextCursor": "eyJ…" }
- Con trỏ là không rõ ràng — luôn truyền chúng lại nguyên văn; một con trỏ đã sửa đổi hoặc lỗi thời sẽ trả về
400 invalid_argument. - Giới hạn kích thước trang: danh bạ mặc định 50, tối đa 200; cuộc trò chuyện mặc định 50, tối đa 100.
GET /v1/api/messages/search(mặc định 25, tối đa 100) vàGET /v1/api/calls(mặc định 50, tối đa 200) chỉ chấp nhận?limit=, không có con trỏ. - Các SDK chính thức sẽ theo dõi
nextCursorcho bạn bằnglistAll()/list_all()— xem Bắt đầu nhanh SDK: TypeScript và Python.
Gửi tin nhắn bất biến
Lỗi mạng sau khi bạn POST /v1/api/messages khiến bạn không biết liệu tin nhắn đã được gửi đi hay chưa — việc thử lại một cách mù quáng có nguy cơ gửi hai lần. Gửi tiêu đề Idempotency-Key (bất kỳ chuỗi nào tối đa 200 ký tự, duy nhất cho mỗi lần gửi logic) và việc thử lại sẽ trở nên an toàn:
curl https://api.ody.co/v1/api/messages \
-H "Authorization: Bearer ody_live_…" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: order-1042-shipped" \
-d '{"to":"+15125550123","body":"Your order shipped!"}'
- Phản hồi thành công đầu tiên được lưu trữ trong 24 giờ; bất kỳ lần thử lại nào với cùng một khóa trong khoảng thời gian đó sẽ phát lại nguyên văn thay vì gửi lại, với tiêu đề phản hồi
Idempotency-Replayed: true. - Tạo khóa từ sự kiện kinh doanh của riêng bạn ("order-1042-shipped"), không phải một giá trị ngẫu nhiên cho mỗi lần thử — toàn bộ mục đích là để các lần thử lại chia sẻ khóa này.
Phong bì lỗi
Mọi phản hồi lỗi đều sử dụng cùng một định dạng:
{ "error": { "code": "permission_denied", "message": "This API key is missing the 'messages:send' scope", "requestId": "req_…" } }
| Trạng thái | Mã | Cách xử lý |
|---|---|---|
400 |
invalid_argument |
Sửa yêu cầu — thông báo cho biết lỗi là gì |
401 |
unauthenticated |
Khóa bị thiếu, không hợp lệ hoặc đã bị thu hồi. Không thử lại; thông báo cho chủ sở hữu tích hợp |
403 |
permission_denied |
Thông báo nêu rõ phạm vi bị thiếu — tạo một khóa có phạm vi đó |
404 |
not_found |
Tài nguyên không tồn tại trong không gian làm việc này |
409 |
failed_precondition |
Không gian làm việc chưa thể thực hiện điều này (ví dụ: không có số hoạt động để gửi đi). Hiển thị lỗi, không thử lại |
429 |
resource_exhausted |
Giới hạn tốc độ — đợi số giây của Retry-After, sau đó thử lại với chiến lược lùi lũy thừa |
500 |
internal |
Thử lại với chiến lược lùi lũy thừa và jitter; giới hạn số lần thử lại |
ID yêu cầu
Mọi phản hồi — thành công hay lỗi — đều mang tiêu đề X-Request-Id, được lặp lại dưới dạng requestId trong phần thân lỗi. Hãy ghi lại nó cùng với nhật ký yêu cầu của riêng bạn và trích dẫn nó khi bạn liên hệ với bộ phận hỗ trợ: nó giúp xác định chính xác yêu cầu ở phía chúng tôi. Bạn cũng có thể cung cấp X-Request-Id của riêng mình (tối đa 64 ký tự, chữ cái/chữ số/_/-) và Ody sẽ lặp lại nó, điều này giúp dễ dàng tương quan các lần thử lại.
Bài viết liên quan
Các câu hỏi thường gặp
Làm cách nào để lấy trang kết quả tiếp theo?
Truyền `nextCursor` của phản hồi trước đó dưới dạng `?cursor=` trong yêu cầu tiếp theo. `nextCursor` rỗng có nghĩa là bạn đã đến cuối.
Điều gì xảy ra nếu tôi thử lại một lần gửi với cùng một Idempotency-Key?
Trong vòng 24 giờ, Ody sẽ phát lại phản hồi đầu tiên đã lưu thay vì gửi lại và thêm tiêu đề `Idempotency-Replayed: true`.
Tôi nên gửi gì cho bộ phận hỗ trợ khi có lỗi xảy ra?
ID yêu cầu (`requestId`) từ phần thân lỗi (cũng là tiêu đề phản hồi `X-Request-Id`) — nó cho phép chúng tôi tìm thấy yêu cầu chính xác trong nhật ký của mình.