Chuyển đến nội dung
HILLS API v1

Hướng dẫn

Lỗi

Định dạng lỗi, mọi mã trạng thái và code mà API trả về, lỗi nào nên thử lại, và một hàm xử lý lỗi Node bạn có thể sao chép ngay.

Cập nhật

Khi một request thất bại, API trả về mã trạng thái 4xx hoặc 5xx và một body JSON với code ổn định. Hãy rẽ nhánh theo code. Nội dung error dành cho con người và có thể thay đổi.

Định dạng

{
  "error": "This API key doesn't have the earnings:read scope.",
  "code": "insufficient_scope",
  "scope": "earnings:read"
}
Trường Luôn có Ý nghĩa
error Có Mô tả sự cố bằng lời. Có thể ghi log hoặc hiển thị cho người vận hành.
code Có Một code ổn định. Xem các bảng bên dưới.
field Khi là invalid Parameter hoặc trường trong body gây lỗi.
scope Khi là insufficient_scope Scope mà key cần có.

Một vài lỗi có thêm trường riêng. Ví dụ, 409 upload_incomplete liệt kê các phần missing và wrong_size.

Lỗi mà mọi endpoint đều có thể trả về

Mã trạng thái code Ý nghĩa Thử lại?
400 invalid Một parameter bị sai. field cho biết parameter nào. Không. Hãy sửa request.
401 unauthenticated Không có header Authorization: Bearer. Không
401 invalid_key Key không tồn tại. Không
401 key_revoked Key đã bị thu hồi. Hãy tạo key mới. Không
401 key_expired Key đã hết hạn. Hãy tạo key mới. Không
401 test_keys_retired Một key hm_test_, đã ngừng sử dụng từ 12/10/2026. Hãy dùng key hm_live_. Không
403 insufficient_scope Key thiếu scope mà endpoint này cần. scope cho biết scope nào. Không
403 account_inactive Tài khoản của bạn không hoạt động. Không
403 api_not_in_plan Gói của bạn không bao gồm API. API đi kèm Enterprise và Custom. Không
404 not_found Không có endpoint này, hoặc đối tượng không thuộc về bạn. Không
429 rate_limited Vượt giới hạn mỗi phút của key này. Có, sau Retry-After giây
500 server_error Có sự cố ở phía chúng tôi. Có, với backoff

404 not_found bao gồm cả trường hợp “không tồn tại” lẫn “thuộc về tài khoản khác”. API không bao giờ cho bạn biết một bản phát hành của người khác có tồn tại hay không.

Lỗi của từng endpoint cụ thể

Mã trạng thái code Ở đâu Ý nghĩa
409 exists POST /members/invite Đã có tài khoản với email này.
413 too_large POST /ddex/validate Lớn hơn mức một lần kiểm thử nhận được. Hãy phân phối bằng POST /ddex.
413 too_large POST /ddex Quá 20 GB (body thô) hoặc 512 MB (multipart). Hãy dùng tải lên trực tiếp.
429 busy POST /ddex/validate Quá nhiều lần kiểm thử cùng lúc. Hãy thử lại sau ít phút.
409 upload_incomplete POST /ddex/uploads/{id}/commit Thiếu phần hoặc phần sai kích thước. Hãy tải chúng lên, rồi commit lại.
409 already_committed Tải lên trực tiếp Đã commit trước đó. status_url trỏ đến lần phân phối.
409 commit_in_progress POST /ddex/uploads/{id}/commit Một lần commit khác của bản tải lên này đang chạy.
400 invalid_url POST /webhooks, PATCH /webhooks/{id} Không phải URL https công khai trên cổng 443.
409 too_many POST /webhooks Bạn đã có 20 endpoint.
409 endpoint_disabled Gửi test và gửi lại webhook Endpoint đang tắt. Hãy bật nó trước.

Mỗi trang tham chiếu liệt kê lỗi của từng endpoint. Scope và lỗi có các lỗi dùng chung.

Lỗi kiểm tra dữ liệu

Một lỗi 400 invalid nêu vấn đề đầu tiên mà API tìm thấy:

{
  "error": "updated_since is an ISO date or time.",
  "code": "invalid",
  "field": "updated_since"
}

Mỗi lần chỉ báo một trường. Hãy sửa rồi gửi lại. Nếu bạn xây dựng biểu mẫu trên API, hãy hiển thị error cạnh ô nhập được nêu trong field.

Tệp DDEX thì khác. Một lô DDEX có vấn đề không phải là lỗi 400. Lần kiểm thử trả về 200 với mọi bước kiểm tra và một kết luận, còn một lần phân phối trả về 202 và báo vấn đề theo từng bản phát hành. Xem Phân phối DDEX.

Nên thử lại lỗi nào

  • Thử lại 429 và 5xx, cùng các lỗi mạng như timeout và reset.
  • Không thử lại các lỗi 4xx khác. Cùng một request sẽ nhận cùng một phản hồi. Hãy sửa request, key hoặc scope của key trước.

Với 429, hãy chờ số giây ghi trong Retry-After. Với 5xx, hãy chờ lâu hơn sau mỗi lần thử (1 giây, 2 giây, 4 giây…) và dừng lại sau vài lần. Xem Rate limit.

Thao tác đọc có thể thử lại an toàn. Hãy cân nhắc trước khi thử lại một thao tác ghi. Gửi lại POST /ddex sau khi mất phản hồi có thể đưa lô vào hàng đợi hai lần. Hãy kiểm tra GET /ddex trước.

Hàm xử lý lỗi cho Node

export class HillsError extends Error {
  constructor(status, body, headers) {
    super(body.error ?? `HTTP ${status}`);
    this.status = status;
    this.code = body.code;
    this.field = body.field;
    this.scope = body.scope;
    this.retryAfter = Number(headers.get("Retry-After")) || null;
  }
}

const sleep = (ms) => new Promise((r) => setTimeout(r, ms));

export async function hills(path, init = {}, tries = 4) {
  for (let i = 1; ; i++) {
    const res = await fetch("https://api.hillsmusic.com/v1" + path, {
      ...init,
      headers: { ...init.headers, Authorization: `Bearer ${process.env.HILLS_API_KEY}` },
    });
    const body = await res.json().catch(() => ({}));
    if (res.ok) return body;
    const err = new HillsError(res.status, body, res.headers);
    const retryable = res.status === 429 || res.status >= 500;
    if (!retryable || i >= tries) throw err;
    await sleep(err.retryAfter ? err.retryAfter * 1000 : 1000 * 2 ** (i - 1));
  }
}

try {
  await hills("/earnings");
} catch (err) {
  if (err.code === "insufficient_scope") console.error(`Add ${err.scope} to this key.`);
  else if (err.code === "api_not_in_plan") console.error("The plan doesn't include the API.");
  else throw err;
}

Với curl, thêm -w '%{http_code}' để xem mã trạng thái, hoặc -i để xem các header:

curl -i "https://api.hillsmusic.com/v1/releases/999999" \
  -H "Authorization: Bearer $HILLS_API_KEY"
# HTTP/2 404
# {"error":"…","code":"not_found"}

Sẵn sàng tích hợp?

Đăng ký quyền truy cập API, chúng tôi sẽ phản hồi bạn trong vòng 1–3 ngày làm việc.