Dành cho team kỹ thuật đối tác
Hướng dẫn tích hợp đối tác XuniBOX
Tài liệu một trang giúp đội kỹ thuật của bạn tích hợp kho nhạc XuniBOX vào màn hình “Chọn nhạc” trong khoảng một buổi làm việc: checklist theo giai đoạn, ví dụ request/response thật và bộ Postman collection tải về chạy ngay.
Checklist tích hợp
Tick từng mục khi hoàn thành. Tiến độ chỉ lưu trong phiên làm việc này.
1. Chuẩn bị truy cập
2. Tích hợp dữ liệu
3. Xử lý media
4. Vận hành & độ bền
Bảng endpoint tra nhanh
Phần lớn đều là GET, base URL https://xunibox.vn/api/public. Toàn bộ endpoint đọc dữ liệu là API công khai, không cần header X-API-Key. Header này chỉ bắt buộc với 3 endpoint dành riêng cho đối tác: báo cáo mức sử dụng, quản lý webhook và nghe thử có watermark.
| Endpoint | Dùng để làm gì | API key |
|---|---|---|
| /tracks | Danh sách nhạc: q, title, artist, genre, artist_id, bpm/energy/key/license/commercial/explicit, sort, page, limit (tối đa 100). | Không |
| /tracks/{id} | Metadata đầy đủ của một bài. Không tăng play_count. | Không |
| /tracks/{id}/audio-url | Link nghe thử đã ký còn hạn + expires_at. Gọi ngay trước khi phát. | Không |
| /tracks/by-ids | Làm mới hàng loạt, tối đa 50 UUID mỗi lượt. | Không |
| /genres | Danh sách thể loại đang dùng để dựng tab lọc. | Không |
| /licenses | Danh mục giấy phép sử dụng nhạc và điều khoản kèm theo. | Không |
| /tracks/{id}/license | Thông tin bản quyền và dòng ghi nguồn dựng sẵn cho một bài. | Không |
| /tracks/{id}/waveform | Dữ liệu sóng âm (điểm biên độ) của một bài nhạc. | Không |
| /tracks/waveforms | Dữ liệu sóng âm cho nhiều bài, tối đa 50 UUID mỗi lượt. | Không |
| /search | Tìm kiếm thông minh: bỏ dấu, chịu sai chính tả, xếp hạng theo score. | Không |
| /search/suggest | Gợi ý autocomplete cho bài nhạc, nghệ sĩ và thể loại. | Không |
| /tracks/{id}/similar | Gợi ý bài tương tự kèm reason (cùng nghệ sĩ, thể loại, tiêu đề). | Không |
| /trending | Bảng xếp hạng theo lượt phát trong N ngày gần nhất. | Không |
| /artists | Duyệt hoặc tìm nghệ sĩ, kèm track_count. | Không |
| /artists/{id}/tracks | Nghệ sĩ + toàn bộ bài nhạc của họ trong một request. | Không |
| /me/usage | Báo cáo mức sử dụng hạn mức của API key theo ngày. | Có |
| /webhooks | Đăng ký, xem hoặc xóa webhook nhận sự kiện (GET/POST/DELETE). | Có |
| /tracks/{id}/watermarked | Nghe thử có watermark, tính vào hạn mức riêng theo key. | Có |
| /health | Trạng thái dịch vụ chi tiết kèm kết nối cơ sở dữ liệu. | Không |
| /healthz | Kiểm tra kết nối và phiên bản API. | Không |
| /readyz | Readiness probe (GET và HEAD) cho load balancer. | Không |
| /status | Chỉ số vận hành và cấu hình rate limit hiện hành. | Không |
| /metrics | Số liệu Prometheus để hệ thống giám sát scrape. | Không |
| /openapi.v1.json | Đặc tả OpenAPI 3.1 để sinh SDK, ghim cho production. | Không |
Mỗi response 200 kèm ETag, Cache-Control và các header X-RateLimit-Limit / Remaining / Reset. Riêng /tracks/{id}/audio-url luôn no-store vì link media chỉ sống 1 giờ.
Ví dụ request / response
Mọi ví dụ dưới đây đều phải gửi header X-API-Key. Thay xnb_live_your_key bằng khóa đối tác của bạn. Tất cả endpoint đều trả JSON UTF-8.
curl --request GET \
--url 'https://xunibox.vn/api/public/tracks?sort=popular&page=1&limit=20' \
--header 'Accept: application/json'HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
Cache-Control: public, max-age=60, s-maxage=300, stale-while-revalidate=600
ETag: "8f2a1c0b9d..."
X-RateLimit-Policy: unmetered
{
"data": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"title": "Nắng Sài Gòn",
"artist": "Minh Anh",
"artist_id": "3fbb9a2e-3b2e-4f34-9a56-6e5c9b2a1234",
"artists": [{ "id": "3fbb9a2e-3b2e-4f34-9a56-6e5c9b2a1234", "name": "Minh Anh" }],
"genre": "Indie Pop",
"duration": "3:24",
"audio_url": "https://.../preview.webm?token=...",
"preview_audio_url": "https://.../preview.webm?token=...",
"preview_start_seconds": 42,
"preview_duration_seconds": 30,
"cover_url": "https://.../cover.webp?token=...",
"play_count": 1240,
"like_count": 356,
"bpm": 96,
"musical_key": "C major",
"energy": 0.62,
"loudness_db": -9.4,
"license_code": "xunibox-standard",
"attribution_required": true,
"commercial_use_allowed": true,
"territory": "worldwide",
"is_explicit": false,
"isrc": "VNA2Z2600001",
"release_date": "2026-01-15"
}
],
"meta": { "total": 128, "page": 1, "limit": 20, "total_pages": 7, "media_expires_in": 3600 }
}curl --request GET \
--url 'https://xunibox.vn/api/public/tracks/550e8400-e29b-41d4-a716-446655440000/audio-url' \
--header 'Accept: application/json'HTTP/1.1 200 OK
Cache-Control: no-store
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"audio_url": "https://.../preview.webm?token=...",
"cover_url": "https://.../cover.webp?token=...",
"media_expires_in": 3600,
"expires_at": "2026-08-05T11:03:00.000Z"
}HTTP/1.1 429 Too Many Requests
Retry-After: 37
X-RateLimit-Remaining: 0
{
"error": "rate_limit_exceeded",
"message": "Vượt hạn mức gọi API. Vui lòng thử lại sau.",
"retry_after_seconds": 37
}
// Chỉ áp dụng cho endpoint dùng API key: /tracks/{id}/watermarkedQuy ước lỗi
- 401 — thiếu header X-API-Key khi gọi /me/usage, /webhooks hoặc /tracks/{id}/watermarked.
- 403 — key sai, bị vô hiệu hoặc hết hạn (chỉ áp dụng cho 3 endpoint cần key ở trên).
- 404 — track/nghệ sĩ không tồn tại.
- 429 — vượt hạn mức, chờ theo Retry-After.
- 5xx — retry tối đa 3 lần với backoff 1s / 2s / 4s.
Chạy thử bằng Postman
- 1. Tải file collection và import vào Postman (File → Import).
- 2. Mở tab Variables của collection, điền api_key.
- 3. Chạy request Danh sách bài nhạc, copy một id vào biến track_id.
- 4. Chạy Làm mới link nghe thử để xác nhận media hoạt động đầu-cuối.