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.

0/17 hoàn thành

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.

EndpointDùng để làm gìAPI key
/tracksDanh 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-urlLink nghe thử đã ký còn hạn + expires_at. Gọi ngay trước khi phát.Không
/tracks/by-idsLàm mới hàng loạt, tối đa 50 UUID mỗi lượt.Không
/genresDanh sách thể loại đang dùng để dựng tab lọc.Không
/licensesDanh mục giấy phép sử dụng nhạc và điều khoản kèm theo.Không
/tracks/{id}/licenseThô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}/waveformDữ liệu sóng âm (điểm biên độ) của một bài nhạc.Không
/tracks/waveformsDữ liệu sóng âm cho nhiều bài, tối đa 50 UUID mỗi lượt.Không
/searchTìm kiếm thông minh: bỏ dấu, chịu sai chính tả, xếp hạng theo score.Không
/search/suggestGợi ý autocomplete cho bài nhạc, nghệ sĩ và thể loại.Không
/tracks/{id}/similarGợi ý bài tương tự kèm reason (cùng nghệ sĩ, thể loại, tiêu đề).Không
/trendingBảng xếp hạng theo lượt phát trong N ngày gần nhất.Không
/artistsDuyệt hoặc tìm nghệ sĩ, kèm track_count.Không
/artists/{id}/tracksNghệ sĩ + toàn bộ bài nhạc của họ trong một request.Không
/me/usageBá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}/watermarkedNghe thử có watermark, tính vào hạn mức riêng theo key.Có
/healthTrạng thái dịch vụ chi tiết kèm kết nối cơ sở dữ liệu.Không
/healthzKiểm tra kết nối và phiên bản API.Không
/readyzReadiness probe (GET và HEAD) cho load balancer.Không
/statusChỉ số vận hành và cấu hình rate limit hiện hành.Không
/metricsSố 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.

Request — danh sách nhạc
curl --request GET \
  --url 'https://xunibox.vn/api/public/tracks?sort=popular&page=1&limit=20' \
  --header 'Accept: application/json'
Response 200
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 }
}
Request — làm mới link nghe thử
curl --request GET \
  --url 'https://xunibox.vn/api/public/tracks/550e8400-e29b-41d4-a716-446655440000/audio-url' \
  --header 'Accept: application/json'
Response 200
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"
}
Response 429 — vượt hạn mức
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}/watermarked

Quy ướ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. 1. Tải file collection và import vào Postman (File → Import).
  2. 2. Mở tab Variables của collection, điền api_key.
  3. 3. Chạy request Danh sách bài nhạc, copy một id vào biến track_id.
  4. 4. Chạy Làm mới link nghe thử để xác nhận media hoạt động đầu-cuối.