Lỗi & giới hạn tần suất

Lỗi và giới hạn tần suất

Mọi endpoint báo lỗi theo cùng một cấu trúc, kèm một mã mà máy đọc được và một ID yêu cầu.

Phản hồi lỗi

Lệnh gọi thất bại trả về success: false. code ổn định và dành cho chương trình, error là một thông báo ngắn bằng tiếng Anh dành cho người đọc, còn request_id xác định lệnh gọi trong log của chúng tôi. param nêu tên tham số gây lỗi khi vấn đề nằm ở đầu vào.

Ví dụ thật

Đây là các phản hồi trực tiếp, lấy từ API tại thời điểm trang này được dựng.

Thiếu tham số bắt buộc · GET /api/sd/oi · HTTP 400
{
  "success": false,
  "error": "coin required",
  "code": "INVALID_PARAM",
  "request_id": "cb-mwefrrfk-a2085edebc"
}
Endpoint không tồn tại · HTTP 404
{
  "success": false,
  "code": "NOT_FOUND",
  "error": "unknown endpoint: GET /api/this-endpoint-does-not-exist",
  "request_id": "cb-mwefrrfl-20f247bdbc"
}

Mã lỗi

MãHTTPÝ nghĩaCách xử lý
INVALID_PARAM400Thiếu một tham số bắt buộc hoặc một giá trị không được chấp nhận. `param` nêu tên tham số khi xác định được.Đừng thử lại với yêu cầu y nguyên; hãy sửa yêu cầu.
UNAUTHORIZED401Header `CB-API-KEY` đã được gửi nhưng khóa không tồn tại hoặc đã bị thu hồi. Dữ liệu công khai không cần khóa — hãy bỏ header hoặc dùng một khóa hợp lệ.Đừng thử lại với yêu cầu y nguyên.
FORBIDDEN403Route này không thuộc API công khai (nội bộ hoặc chỉ dành cho tài khoản).Đừng thử lại.
NOT_FOUND404Route không xác định, hoặc coin / sàn / quỹ được yêu cầu không tồn tại.Đừng thử lại; hãy đối chiếu đường dẫn và các mã định danh với danh mục.
RATE_LIMITED429Số yêu cầu vượt quá giới hạn mỗi phút. `Retry-After` cho biết số giây cần chờ.Chờ theo `Retry-After`, rồi thử lại có backoff.
INTERNAL500Lỗi máy chủ không mong đợi. Thông báo được cố ý viết chung chung; hãy trích dẫn `request_id` khi báo lỗi.Thử lại một lần sau vài giây; nếu lỗi vẫn tiếp diễn, hãy báo cáo kèm ID yêu cầu.
UPSTREAM_FAILED503Nguồn dữ liệu đứng sau endpoint này không trả lời kịp thời. Không có số liệu quá hạn hay số liệu thay thế nào được trả về thay cho nó.Thử lại có backoff; xem trang trạng thái.
UNAVAILABLE501 / 503Bộ dữ liệu tạm thời chưa sẵn sàng (cache đang được làm nóng) hoặc endpoint chưa có nguồn công khai hợp pháp.Thử lại sau; danh mục có đánh dấu những endpoint không khả dụng theo thiết kế.
REQUEST_FAILED200Một số endpoint cũ hơn trả về HTTP 200 với `success: false`. Hãy luôn kiểm tra `success`, không chỉ trạng thái HTTP.Tùy vào thông báo; hãy coi là một yêu cầu thất bại.
Các endpoint cũ hơn có thể trả về HTTP 200 với success: false và code REQUEST_FAILED khi không tìm thấy mục được yêu cầu. Hãy kiểm tra success ở mọi phản hồi.

ID yêu cầu

Mỗi phản hồi đều mang header X-Request-Id. Phản hồi lỗi lặp lại giá trị này trong phần nội dung dưới tên request_id. Phản hồi được phục vụ từ cache biên ngắn hạn lặp lại ID của yêu cầu đã tạo ra chúng, vì vậy ID giống nhau ở các lệnh gọi liên tiếp nghĩa là bạn đã nhận một bản sao từ cache.

Giới hạn tần suất

Giới hạn được tính theo phút, theo địa chỉ IP với lệnh gọi ẩn danh và theo khóa khi có header CB-API-KEY hợp lệ. Giới hạn là 1200 yêu cầu mỗi phút. Yêu cầu lấy icon dưới /api/coin-icon không bị tính.

Header giới hạn tần suất

TênMô tả
X-Request-IdMã định danh của yêu cầu này. Hãy trích dẫn nó khi báo lỗi.
X-RateLimit-LimitSố yêu cầu được phép trong khung một phút hiện tại.
X-RateLimit-RemainingSố yêu cầu còn lại trong khung hiện tại.
X-RateLimit-ResetThời điểm khung được đặt lại, tính bằng giây theo Unix time.
Retry-AfterGửi kèm HTTP 429: số giây cần chờ trước khi thử lại.
X-CacheHIT, STALE hoặc MISS đối với cache phản hồi phía máy chủ.

Khi bạn vượt giới hạn

API trả về HTTP 429 với code RATE_LIMITED. Hãy chờ đủ số giây nêu trong Retry-After rồi thử lại. Polling nhanh hơn TTL cache của endpoint chỉ nhận lại cùng một phản hồi đã cache, vì vậy hãy đặt chu kỳ polling khớp với TTL ghi trên từng trang tham chiếu.

Thử lại có backoff

JavaScript
async function getJson(url, tries = 4) {
  for (let i = 0; i < tries; i++) {
    const res = await fetch(url);
    if (res.status === 429 || res.status >= 500) {
      const wait = Number(res.headers.get("Retry-After")) || 2 ** i;
      await new Promise((r) => setTimeout(r, wait * 1000));
      continue;
    }
    const body = await res.json();
    if (body.success === false) {
      throw new Error(body.code + ": " + body.error + " (" + body.request_id + ")");
    }
    return body;
  }
  throw new Error("gave up after " + tries + " attempts");
}

Không có dữ liệu không phải là lỗi

Khi tham số hợp lệ nhưng không có nguồn công khai hợp pháp cho dữ liệu, lệnh gọi vẫn thành công với HTTP 200: các trường giá trị là null, meta.quality là UNAVAILABLE và coverage.unavailable nêu lý do. Hãy hiển thị bằng dấu gạch ngang. Đừng chuyển thành 0.

Dữ liệu quá hạn

Nếu một trình thu thập bị chậm, các endpoint tiếp tục phục vụ giá trị đã lưu gần nhất kèm meta.is_stale: true cho đến khi chúng vượt quá khung còn dùng được; sau đó chúng bị loại khỏi số liệu tổng hợp và được liệt kê trong coverage.stale_excluded.