# Lấy metadata một bộ phim

Trả về mọi thứ Wandura biết về một bộ cho CMS của bạn: tên và tóm tắt theo ngôn ngữ, thẻ thể loại và chủ đề có mã, độ tuổi, diễn viên hoặc nhân vật chính, ảnh kèm kích thước, ngôn ngữ âm thanh, cờ đã ra hết tập, và các tập đã phát hành kèm video ID và file phụ đề. Gọi endpoint này khi [Liệt kê bộ phim](https://docs.wandura.ai/vi/v1/developers/reference/series-list) trả một `content_version` bạn chưa lưu.

```
GET /api/delivery/v1/series/{code}
```

**Scope:** `metadata:read`

## Mô tả
Giá trị thiếu là `null` hoặc rỗng: không bao giờ chặn giấy phép. Bộ không tồn tại và bộ bạn không được stream trả về cùng một `404`, nên bạn không phân biệt được hai trường hợp này. Response thành công được bọc trong envelope `{code, message, data, server_time}`; lỗi dùng cùng envelope nhưng không có `data`, trừ `429` và `400` `unsupported_version` dùng định dạng phẳng. Endpoint này dùng chung bộ đếm rate limit với [catalog](https://docs.wandura.ai/vi/v1/developers/reference/catalog).

CMS của bạn được sửa đè bất kỳ trường nào. Wandura không bao giờ ghi đè bản sửa của bạn.

## Tham số request
| Tên | Vị trí | Kiểu | Bắt buộc | Mô tả |
|---|---|---|---|---|
| `Authorization` | header | string | Có | `Bearer <API key>` của một key có scope `metadata:read`. |
| `code` | path | string | Có | Mã bộ, ví dụ `WD000016` (`code` trong catalog hoặc danh sách). |
| `Wandura-Version` | header | string | Không | Tuỳ chọn. Một phiên bản API theo ngày (YYYY-MM-DD) dùng cho request này thay cho bản ghim vào API key của bạn. Giá trị lạ hoặc đã ngừng trả 400 với `error_code` `unsupported_version`. |

## Ví dụ request
```bash
curl -s https://www.wandura.ai/api/delivery/v1/series/WD000016 \
  -H "Authorization: Bearer $WANDURA_API_KEY"
```

## Response
`200 OK`. Trường mới có thể được thêm bất cứ lúc nào: bỏ qua trường bạn không biết.

| Trường | Kiểu | Mô tả |
|---|---|---|
| `code` | integer | `0`. |
| `message` | string | `"ok"`. |
| `data` | object |  |
| `server_time` | integer | Giờ server tính bằng giây Unix epoch. |
| `links` | object | URL tuyệt đối dựng sẵn của chính tài nguyên này (link API, không phải file media). |

### Các trường của một bộ (`data`)
| Trường | Kiểu | Mô tả |
|---|---|---|
| `code` | string | Mã bộ, ví dụ `WD000016`. |
| `status` | string | Luôn là `active` (bộ bạn không được stream trả 404). |
| `updated_at` | integer | Lần đổi gần nhất tính bằng giây Unix epoch. |
| `content_version` | string hoặc null | Mã băm của toàn bộ response này. Lưu lại; danh sách trả cùng giá trị thì không có gì phải tải. |
| `language` | string hoặc null | Ngôn ngữ âm thanh, BCP-47 (giống `default_lang`). |
| `default_lang` | string hoặc null | Ngôn ngữ âm thanh, BCP-47. |
| `title_i18n` | object | Chữ theo ngôn ngữ: khoá là mã BCP-47, giá trị là chữ, ví dụ `{"en": "The Heiress Returns"}`. Hiện Wandura điền `en`; có thể có thêm ngôn ngữ. Thiếu khoá nghĩa là chưa có chữ ngôn ngữ đó: lùi về `en`. Object rỗng khi không có chữ. |
| `synopsis_short_i18n` | object | Chữ theo ngôn ngữ: khoá là mã BCP-47, giá trị là chữ, ví dụ `{"en": "The Heiress Returns"}`. Hiện Wandura điền `en`; có thể có thêm ngôn ngữ. Thiếu khoá nghĩa là chưa có chữ ngôn ngữ đó: lùi về `en`. Object rỗng khi không có chữ. |
| `synopsis_i18n` | object | Chữ theo ngôn ngữ: khoá là mã BCP-47, giá trị là chữ, ví dụ `{"en": "The Heiress Returns"}`. Hiện Wandura điền `en`; có thể có thêm ngôn ngữ. Thiếu khoá nghĩa là chưa có chữ ngôn ngữ đó: lùi về `en`. Object rỗng khi không có chữ. |
| `genres` | mảng string | Nhãn thể loại chữ tự do (cũ). Nên dùng `tags`. |
| `poster` | object hoặc null | Ảnh bìa 9:16 dạng `{url}`, hoặc `null`. Cùng ảnh có trong `images` kèm kích thước. |
| `content_rating` | string hoặc null | Độ tuổi, hoặc `null` khi chưa chấm. |
| `is_completed` | boolean hoặc null | `true` khi mọi tập dự kiến đã ra. |
| `release_date` | string hoặc null | Ngày phát hành gốc, hoặc `null`. |
| `planned_episodes` | integer hoặc null | Tổng số tập dự kiến, hoặc `null`. |
| `tags` | array |  |
| `tags[].slug` | string | Mã ổn định của thẻ, ví dụ `romance` hoặc `enemies-to-lovers`. Ánh xạ sang danh sách thẻ của bạn theo giá trị này, không theo `name`. |
| `tags[].name` | string | Tên hiển thị tiếng Anh. |
| `tags[].name_i18n` | object | Chữ theo ngôn ngữ: khoá là mã BCP-47, giá trị là chữ, ví dụ `{"en": "The Heiress Returns"}`. Hiện Wandura điền `en`; có thể có thêm ngôn ngữ. Thiếu khoá nghĩa là chưa có chữ ngôn ngữ đó: lùi về `en`. Object rỗng khi không có chữ. |
| `tags[].type` | string | `genre`, `theme` hoặc `system`. Có thể có loại mới. |
| `tags[].is_main` | boolean | `true` với thể loại chính của phim (tối đa một). |
| `people` | array |  |
| `people[].name` | string | Tên diễn viên hoặc nhân vật. |
| `people[].role` | string | `lead` hoặc `support`. |
| `people[].description` | string hoặc null | Mô tả một câu, hoặc `null`. |
| `people[].avatar_url` | string hoặc null | URL ảnh `https` tuyệt đối, hoặc `null`. |
| `images` | array |  |
| `images[].kind` | string | Ảnh dùng cho việc gì: `poster_3_4` (poster thẻ 3:4), `cover_9_16` (ảnh bìa toàn màn hình 9:16, cùng ảnh với `poster_url`), `hero_16_9` (banner 16:9) hoặc `title_treatment` (tên phim dạng ảnh). Có thể có loại mới: bỏ qua loại bạn không biết. |
| `images[].lang` | string hoặc null | Ngôn ngữ của chữ in sẵn trong ảnh (BCP-47), hoặc `null` khi ảnh dùng được cho mọi ngôn ngữ. Ưu tiên phần tử khớp ngôn ngữ người dùng, không có thì lấy phần tử `null`. |
| `images[].url` | string | URL `https` tuyệt đối của ảnh trên host của Wandura. Tải thẳng được, không cần ký. |
| `images[].width` | integer hoặc null | Chiều rộng tính bằng pixel, đo từ chính file. `null` khi Wandura chưa ghi kích thước. |
| `images[].height` | integer hoặc null | Chiều cao tính bằng pixel, đo từ chính file. `null` khi Wandura chưa ghi kích thước. |
| `trailer` | object hoặc null | Video ID trailer trong media space của Wandura, hoặc `null`. Luôn `null` khi bạn có space riêng. |
| `metadata_version` | string hoặc null | Mã băm của riêng metadata phim (cùng giá trị như trong catalog). |
| `metadata_updated_at` | integer hoặc null | Lúc `metadata_version` đổi gần nhất (giây epoch). |
| `media` | object | Video nằm ở đâu: `space` là media space (của bạn nếu bạn có space riêng) và `playlist_name` là playlist chứa các tập theo thứ tự (bằng `code`). |
| `episodes` | array | Các tập đã phát hành, theo `ep_number`. |
| `episodes[].ep_number` | integer | Số tập, bắt đầu từ 1. Thứ tự playlist theo số này. |
| `episodes[].vid` | string hoặc null | Video ID của tập trong media space ghi ở `media.space` (space riêng của bạn nếu có). `null` khi tập chưa có trong space đó. |
| `episodes[].ready` | boolean | `true` khi tập phát được từ space đó. |
| `episodes[].title_i18n` | object | Chữ theo ngôn ngữ: khoá là mã BCP-47, giá trị là chữ, ví dụ `{"en": "The Heiress Returns"}`. Hiện Wandura điền `en`; có thể có thêm ngôn ngữ. Thiếu khoá nghĩa là chưa có chữ ngôn ngữ đó: lùi về `en`. Object rỗng khi không có chữ. |
| `episodes[].duration_sec` | integer hoặc null | Thời lượng tính bằng giây, chỉ để đối chiếu. |
| `episodes[].subtitles[].lang` | string | Mã BCP-47. |
| `episodes[].subtitles[].url` | string | URL file WebVTT. Tải về và tự lưu bản của bạn. |
| `episodes[].subtitles[].updated_at` | integer | Lần đổi file gần nhất (giây epoch). |

URL ảnh và phụ đề là URL `https` tuyệt đối trên host của Wandura. Tải file phụ đề về và tự lưu bản của bạn.

## Ví dụ response
```json
{
  "code": 0,
  "message": "ok",
  "data": {
    "code": "WD000016",
    "status": "active",
    "updated_at": 1790390000,
    "content_version": "c3f1a9e07b2d4c5e8f9a0b1c2d3e4f50",
    "language": "en",
    "default_lang": "en",
    "title_i18n": { "en": "The Hidden Alpha Bride" },
    "synopsis_short_i18n": { "en": "Rejected by her mate, a runaway omega returns as the bride of his rival." },
    "synopsis_i18n": { "en": "Rejected by her mate on the night of the bond, Luna runs. Three years later she returns as the bride of his rival." },
    "genres": ["Werewolf", "Romance"],
    "poster": { "url": "https://static.example.com/wd000016/cover.jpg" },
    "content_rating": "13+",
    "is_completed": true,
    "release_date": null,
    "planned_episodes": 60,
    "tags": [
      { "slug": "werewolf", "name": "Werewolf", "name_i18n": { "en": "Werewolf" }, "type": "genre", "is_main": true },
      { "slug": "fated-mates", "name": "Fated Mates", "name_i18n": { "en": "Fated Mates" }, "type": "theme", "is_main": false }
    ],
    "people": [{ "name": "Luna", "role": "lead", "description": "A rejected omega who returns to claim her place.", "avatar_url": null }],
    "images": [
      { "kind": "poster_3_4", "lang": null, "url": "https://static.example.com/wd000016/poster-3x4.jpg", "width": 1080, "height": 1440 },
      { "kind": "cover_9_16", "lang": null, "url": "https://static.example.com/wd000016/cover.jpg", "width": 1080, "height": 1920 }
    ],
    "trailer": null,
    "metadata_version": "9a0b1c2d3e4f5061728394a5b6c7d8e9",
    "metadata_updated_at": 1790380000,
    "media": { "space": "your-space", "playlist_name": "WD000016" },
    "episodes": [
      {
        "ep_number": 1,
        "vid": "v0d2f8c1a9e4b7",
        "ready": true,
        "title_i18n": { "en": "The Night of the Bond" },
        "duration_sec": 137,
        "subtitles": [{ "lang": "en", "url": "https://static.example.com/wd000016/1.en.vtt", "updated_at": 1790380000 }]
      }
    ]
  },
  "server_time": 1790400000
}
```

## Header của response
| Header | Response | Mô tả |
|---|---|---|
| `Wandura-API-Status` | mọi response | Trạng thái API. Hiện là `beta`, ở mọi response, thành công hay lỗi. |
| `Wandura-Version` | 200 | Phiên bản API theo ngày (YYYY-MM-DD) mà response này dùng: bản ghim vào API key của bạn, hoặc bản bạn gửi trong header request `Wandura-Version`. Key tạo trước khi có phiên bản ngày dùng `2026-10-02`. |
| `Wandura-Request-Id` | 200 | Mã định danh mờ của request này (`req_` và 26 ký tự). Mọi response đều có, kể cả lỗi, và body lỗi lặp lại nó ở `request_id`. Hãy ghi log nó, và gửi kèm khi liên hệ Wandura về một request: nó tìm đúng request đó trong log của chúng tôi. Đừng phân tích chuỗi này. |
| `Cache-Control` | 200 | Luôn là `no-store`. Đừng lưu các response này trong cache dùng chung. |
| `Retry-After` | 429 | Số giây cần chờ trước khi thử lại. Có ở response 429 và các response 503 nên thử lại. |

## Lỗi
| Status | `code` | Khi nào |
|---|---|---|
| 400 | không có | Header `Wandura-Version`, hoặc bản ghim của key, là bản lạ hay đã ngừng. |
| 401 | 4010 | Thiếu header `Authorization: Bearer`. |
| 401 | 4011 | Key không tồn tại hoặc đã bị thu hồi. |
| 403 | 4030 | Key thiếu scope `metadata:read`. |
| 403 | 4031 | Quyền truy cập của tổ chức bạn đang bị tạm ngưng. |
| 404 | 4040 | Không có bộ này, hoặc tổ chức của bạn không được stream nó (cố ý trả cùng một câu). |
| 429 | không có | Đã chạm rate limit. |
| 503 | 5030 | Bộ phim tạm thời không khả dụng. |
| 503 | 5031 | Wandura chưa kiểm được API key kịp thời. |

Xem [Lỗi](https://docs.wandura.ai/vi/v1/developers/concepts/errors#series-get-errors) để biết cách xử lý từng trường hợp.
