Tài liệu API XuniBOX
API chỉ đọc để lấy danh sách nhạc, nghệ sĩ và thể loại từ kho XuniBOX. Mỗi chủ đề dưới đây là một trang riêng, có đường dẫn riêng để bạn chia sẻ cho đội kỹ thuật.
Quy ước chung
Envelope
Mọi endpoint danh sách trả cùng một hình dạng: { data: [...], meta: { total, page, limit } }. Riêng /artists/:id/tracks có thêm khóa artist. Endpoint chi tiết trả thẳng object, không bọc data.
Phân trang
page bắt đầu từ 1 (tối đa 5000), limit mặc định 20 và trần 100. Dùng meta.total để biết khi nào dừng; đừng dựa vào việc mảng rỗng vì bạn sẽ tốn thêm một request.
async function fetchAllTracks(genre) {
const limit = 100; // trần cho phép
let page = 1;
const all = [];
while (true) {
const url = `https://xunibox.vn/api/public/tracks?genre=${encodeURIComponent(genre)}&sort=newest&page=${page}&limit=${limit}`;
const res = await fetch(url, { headers: { "X-API-Key": XUNIBOX_API_KEY } });
if (!res.ok) throw new Error(`HTTP ${res.status}`);
const { data, meta } = await res.json();
all.push(...data);
if (all.length >= meta.total || data.length === 0) break;
page += 1;
}
return all;
}Sắp xếp
Thứ tự luôn có tie-breaker theo id nên phân trang ổn định, không bị lặp hoặc rơi bản ghi giữa các trang.
| sort | Áp dụng cho | Thứ tự thực tế |
|---|---|---|
| newest (mặc định) | /tracks, /artists/:id/tracks | created_at giảm dần |
| oldest | /tracks, /artists/:id/tracks | created_at tăng dần |
| popular | /tracks, /artists/:id/tracks | play_count giảm dần, rồi created_at |
| title_asc / title_desc | /tracks, /artists/:id/tracks | Theo tên bài hát |
| name_asc (mặc định) / name_desc | /artists | Theo tên nghệ sĩ |
| newest / oldest | /artists | created_at của nghệ sĩ |
Bộ lọc và tìm kiếm
Tất cả bộ lọc chữ là tìm một phần (contains), không phân biệt hoa thường, có dấu tiếng Việt vẫn chạy. Ký tự cho phép: chữ, số, khoảng trắng và . ' ’ & + / -. Ký tự lạ như %, * hay dấu ngoặc sẽ bị trả 400 — nhớ encodeURIComponent giá trị người dùng nhập.
| Tham số | Endpoint | Giới hạn |
|---|---|---|
| q | /tracks, /artists | Tìm đồng thời title + artist + genre (với /artists là tên). Tối đa 100 ký tự. |
| title | /tracks | Tối đa 160 ký tự. |
| artist | /tracks | Tối đa 120 ký tự. |
| genre | /tracks | Tối đa 80 ký tự. |
| artist_id | /tracks | UUID chính xác, nhanh và chuẩn hơn lọc theo tên. |
?q=hè&genre=Pop nghĩa là “có chữ hè” và “thể loại chứa Pop”.Cache và ETag
Mọi response 200 đều có Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600 và một ETag yếu tính từ nội dung JSON. Gửi lại ETag qua If-None-Match, nếu dữ liệu chưa đổi bạn nhận 304 không body — nhanh hơn và không tốn băng thông. Lỗi (4xx/5xx) luôn là no-store.
let cached = { etag: null, body: null };
async function getGenres() {
const res = await fetch(`https://xunibox.vn/api/public/genres`, {
headers: {
"X-API-Key": process.env.XUNIBOX_API_KEY,
...(cached.etag ? { "If-None-Match": cached.etag } : {})
}
});
if (res.status === 304) return cached.body; // dữ liệu chưa đổi
cached = { etag: res.headers.get("ETag"), body: await res.json() };
return cached.body;
}Sẵn sàng tích hợp?
Gửi thông tin sản phẩm để admin XuniBOX xét duyệt và cấp API key.