Lỗi & Phân trang
Trang này đề cập đến hai điều mà mọi tích hợp cần xử lý: một yêu cầu thất bại trông như thế nào và cách phân trang qua các điểm cuối trả về danh sách.
Cấu trúc lỗi
Khi một yêu cầu thất bại, phản hồi luôn là JSON với cùng một hình dạng — một cờ success được đặt thành false, một thông báo error dễ đọc đối với con người và một error_code dạng số khớp với trạng thái HTTP:
{
"success": false,
"error": "Invalid cursor",
"error_code": 400
}
Vì success và error_code luôn hiện diện, bạn có thể phân nhánh dựa trên chúng mà không cần kiểm tra mã trạng thái HTTP thô nếu muốn. Một phản hồi thành công luôn có success: true.
Mã trạng thái
| Status | error_code |
Meaning | What to do |
|---|---|---|---|
200 |
— | Success | Read the response data. |
201 |
— | Resource created | Save the returned ID (e.g. campaign_id, contactId). |
400 |
400 |
Bad request | A parameter is missing or invalid. Read the error message and fix the request. |
401 |
401 |
Unauthorized | Your API key is missing or invalid. Check the key and how you are sending it — see Authentication. |
403 |
403 |
Forbidden | Your plan does not include API access. See API Access or contact hi@youraiconnector.com. |
404 |
404 |
Not found | The resource (e.g. a contact, campaign, or task ID) does not exist on your account. |
409 |
409 |
Conflict | The resource already exists — for example, creating a contact whose phone number is already on your account. |
429 |
429 |
Rate limited | You have exceeded 300 requests per minute (or the wider 1,200/minute account ceiling). Back off and retry shortly. |
500 |
500 |
Server error | Something went wrong on our side. Retry after a short wait; email hi@youraiconnector.com if it persists. |
Một vài ví dụ về cách các lỗi này xuất hiện trong thực tế:
{
"success": false,
"error_code": 401,
"error": "Invalid API key"
}
{
"success": false,
"error": "A contact with this phone number already exists",
"error_code": 409
}
{
"success": false,
"error_code": 429,
"error": "Rate limit exceeded. Please try again later."
}
Xử lý lỗi hiệu quả
- Kiểm tra
success(hoặc mã trạng thái) trước khi đọc dữ liệu. Đừng giả định rằng nội dung phản hồi có trường mà bạn mong đợi. - Thử lại
429và500với thời gian chờ ngắn — đợi một chút, sau đó thử lại. Đừng thử lại400,401,403,404hoặc409; những lỗi đó sẽ tiếp tục thất bại cho đến khi bạn thay đổi yêu cầu. - Đọc thông báo
error. Nó thường cho bạn biết chính xác trường nào bị sai.
Phân trang
Các điểm cuối danh sách (chẳng hạn như GET /contacts, GET /campaigns và GET /tasks) trả về kết quả theo từng trang để một lệnh gọi duy nhất không bao giờ phải tải toàn bộ tài khoản của bạn. Phân trang sử dụng một con trỏ ẩn (opaque cursor).
Hai tham số truy vấn kiểm soát việc này:
| Tham số | Mô tả |
|---|---|
limit |
Số lượng mục cần trả về trên mỗi trang. Mặc định thay đổi tùy theo điểm cuối (thường là 50); tối đa là 100. |
cursor |
Một con trỏ ẩn đến trang tiếp theo. Để trống cho trang đầu tiên. |
Mỗi trang bao gồm một trường next_cursor trong phản hồi:
- Nếu
next_cursorlà một chuỗi, nghĩa là vẫn còn kết quả — hãy truyền nó dưới dạngcursortrong yêu cầu tiếp theo của bạn. - Nếu
next_cursorlànull, bạn đã đến trang cuối cùng. Hãy dừng lại.
Một trang danh bạ đơn lẻ trông như sau:
{
"success": true,
"contacts": [
{ "id": "abc123", "first_name": "Jane", "phone_number": "+15551234567" },
{ "id": "def456", "first_name": "John", "phone_number": "+15557654321" }
],
"next_cursor": "eyJsYXN0IjoiZGVmNDU2In0"
}
Lưu ý: Con trỏ (cursor) là dữ liệu mờ — đừng cố phân tích, xây dựng hoặc sửa đổi nó. Chỉ nên truyền lại giá trị next_cursor mà bạn đã nhận được từ phản hồi trước đó.
Phân trang tất cả danh bạ
Để thu thập toàn bộ danh sách, hãy bắt đầu mà không có con trỏ và tiếp tục gọi cho đến khi next_cursor trả về null.
cURL
Ví dụ này thực hiện thủ công việc duyệt qua hai trang đầu tiên. Chạy lệnh gọi đầu tiên, sao chép next_cursor từ phản hồi của nó vào CURSOR, sau đó chạy lệnh gọi thứ hai. Lặp lại cho đến khi next_cursor là null.
# First page
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100"
# Next page — paste the next_cursor from the previous response
CURSOR="eyJsYXN0IjoiZGVmNDU2In0"
curl "https://api.youraiconnector.com/v1/contacts?apiKey=YOUR_API_KEY&limit=100&cursor=$CURSOR"
JavaScript
async function getAllContacts() {
const all = [];
let cursor = null;
do {
const url = new URL("https://api.youraiconnector.com/v1/contacts");
url.searchParams.set("limit", "100");
if (cursor) url.searchParams.set("cursor", cursor);
const res = await fetch(url, {
headers: { "X-API-Key": "YOUR_API_KEY" },
});
const data = await res.json();
if (!data.success) throw new Error(data.error);
all.push(...data.contacts);
cursor = data.next_cursor;
} while (cursor);
return all;
}
Python
import requests
def get_all_contacts():
all_contacts = []
cursor = None
while True:
params = {"limit": 100}
if cursor:
params["cursor"] = cursor
res = requests.get(
"https://api.youraiconnector.com/v1/contacts",
params=params,
headers={"X-API-Key": "YOUR_API_KEY"},
)
data = res.json()
if not data["success"]:
raise Exception(data["error"])
all_contacts.extend(data["contacts"])
cursor = data["next_cursor"]
if not cursor:
break
return all_contacts
Vòng lặp tương tự hoạt động cho bất kỳ điểm cuối (endpoint) được phân trang nào — chỉ cần thay đổi đường dẫn và trường bạn đọc từ phản hồi (campaigns, tasks, v.v.).