Kênh, media và số liệu
Những endpoint chỉ đọc mà mọi luồng khác đều cần, cộng với tải tệp lên kho media và đăng thẳng video có sẵn.
Kênh đã nối
GET /channels?page=1&pageSize=25
Đây là nơi lấy id để truyền vào connectionIds ở mọi chỗ khác.
| Trường | Ý nghĩa |
|---|---|
platform | youtube, tiktok, facebook, instagram, … |
handle | Tên hiển thị trên nền tảng, ví dụ @kenhcuatoi |
tokenStatus | healthy = đăng được ngay. Giá trị khác nghĩa là kênh cần nối lại trên giao diện web. |
supportsComments | Nền tảng này có nhận bình luận tự động hay không |
followersCount | Số người theo dõi lần cập nhật gần nhất |
Nối kênh mới phải làm trên giao diện web
Việc đó đi qua màn hình cấp quyền của chính nền tảng. API chỉ đọc danh sách và dùng kênh đã nối.
Số dư credit
GET /credits
{ "available": 1250, "held": 36 }available— tiêu được ngay.held— đang giữ cho việc đang chạy, chưa quyết toán. Việc xong thì phần này trừ thật; việc hỏng thì trả lại.
Hỏi trước mỗi loạt tạo video nếu bạn muốn dừng sớm thay vì để từng lượt gọi hỏng vì thiếu tiền. Xem Cách tính credit.
Báo giá trước khi tạo
POST /credits/estimate
{ "moduleKey": "image-to-video", "serverTier": 1, "durationSec": 10 }Chỉ đọc bảng giá, không giữ hay trừ gì (quyền credits:read). total là số sẽ bị giữ khi tạo với đúng đầu vào này; serverTiers cho giá và trạng thái nhận việc của từng server. Bỏ trống serverTier là server 1; durationSec (1–300) chỉ ảnh hưởng loại billing = per-second.
| Endpoint tạo | moduleKey để báo giá |
|---|---|
POST /videos | news |
POST /knowledge/render | knowledge |
POST /storytelling/render | storytelling |
POST /comics/{id}/render | comic |
POST /video-talk/render | đúng moduleKey gửi lên |
POST /ai-video | moduleKey gửi lên (bỏ trống là image-to-video) |
POST /ad-video/render | variant của mẫu (product-review, tvc, ugc) |
jobs ai-presenter-render / video-clone-render | ai-presenter / video-clone, durationSec = số cảnh × 10 |
Khi nào số thật có thể khác báo giá
POST /ai-videovàPOST /ad-video/renderbỏ trốngserverTierthì tự chọn server rẻ nhất đang nhận việc, và thời lượng có thể được làm tròn lên theo độ dài clip của server đó. Muốn giá chắc chắn, truyềnserverTierkhi tạo.- AI avatar và điều khiển chuyển động tính theo thời lượng đo từ tệp gửi lên.
- Trạng thái server là trạng thái chung; lượt tạo thật còn phụ thuộc số ảnh gửi kèm.
Lịch sử credit và lịch sử gọi
GET /credits/transactions?type=spent&from=2026-09-01T00:00:00Z&videoId=… GET /usage-logs?channel=mcp&outcome=error&apiKeyId=… GET /usage-logs/stats?channel=api&timeZone=Asia/Ho_Chi_Minh
/credits/transactions(quyềncredits:read) — mỗi lần số dư đổi, kèm số dư ngay sau đó.typelàdeposited,spent,refundedhoặcrevoked; dòngnot_chargedghi nhận video hỏng mà không bị trừ tiền./usage-logs(quyềnusage:read) — mỗi lượt gọi API bằng khoá và mỗi lượt trợ lý AI dùng công cụ MCP: thao tác, mã HTTP, mã lỗi, khoá hoặc ứng dụng đã gọi, thời gian xử lý. Giữ 90 ngày, không lưu nội dung yêu cầu./usage-logs/stats(quyềnusage:read) — tổng lượt gọi, tỉ lệ lỗi, thời gian phản hồi trung bình/p50/p95, số liệu theo mốc thời gian và 10 thao tác gọi nhiều nhất. Mặc định 24 giờ gần nhất, tối đa 90 ngày; mốc chia theo phút, giờ hoặc ngày tuỳ độ dài khoảng, tính theotimeZone(IANA).
Khoảng from sau to bị từ chối với mã 422 thay vì trả danh sách rỗng — rỗng dễ bị đọc nhầm thành "không có gì xảy ra".
Kho media
Tải tệp lên đi qua ba bước. Tệp không đi qua máy chủ API — bạn gửi thẳng lên kho, nên tệp lớn không chiếm băng thông của API và không bị trần kích thước thân yêu cầu.
- 1
Xin phiếu tải lên
POST /media/upload-ticket { "contentType": "video/mp4" }Nhận về
url,fields,key,expiresAtvàmaxBytes. - 2
Gửi tệp lên đúng địa chỉ đó
POSTkiểu multipart tớiurl, kèm nguyên vẹn các trường trongfields, xếp trước phần tệp. Sai thứ tự là kho từ chối. - 3
Xác nhận
POST /media { "key": "…", "originalName": "clip.mp4" }Chỉ sau bước này tệp mới hiện trong kho và dùng được. Bỏ qua bước xác nhận thì tệp nằm mồ côi và sẽ bị dọn.
GET /media?limit=25&startingAfter={id}&folderId={id}
GET /media/{id}
DELETE /media/{id}Kho media phân trang bằng con trỏ: truyền id của phần tử cuối trang trước vào startingAfter. Lý do ở Quy ước chung.
Chỉ tệp video ở trạng thái ready mới đem đăng được
Video tải lên còn phải qua khâu xử lý. playbackStatus nói tệp đã sẵn sàng chưa — đẩy một tệp chưa ready vào lượt tạo video là hỏng ở tận khâu dựng.
Đăng video có sẵn lên kênh
Video đã tự dựng xong ở nơi khác thì đăng thẳng, không dựng lại và không trừ credit — giống trang Đăng video có sẵn trên giao diện.
POST /media/{id}/publish → 202
Idempotency-Key: …
{
"title": "Tiêu đề (dùng cho YouTube)",
"caption": "Mô tả bài đăng",
"hashtags": ["meo", "hay"],
"connectionIds": ["…"],
"scheduleAt": "2026-10-01T10:00:00+07:00",
"coverMediaId": "…"
}- Bắt buộc:
title,caption(được để chuỗi rỗng),hashtags(được để mảng rỗng) và ít nhất mộtconnectionIds. Tài khoản phải có gói Upload video; thiếu gói trả 403upload_video_not_entitled. {id}là tệp video trong kho, đã ở trạng tháiready. Bỏ trốngscheduleAtlà đăng ngay; hẹn giờ thì phải ở tương lai và không quá 30 ngày (schedule_in_past,schedule_too_far).coverMediaIdlà một ảnh trong kho làm ảnh bìa; bỏ trống thì lấy khung hình tự trích từ video.- Tuỳ chọn thêm giống
POST /videos/{id}/publish:allowComment,allowContentReuse(mặc địnhtrue),youtubeConfig,facebookConfig,comment. - Đòi quyền
posts:writevà headerIdempotency-Key: mỗi lượt gọi tạo một bài mới trên kênh thật, nên gửi lại cùng khoá sau khi mất mạng sẽ nhận về đúng bài cũ thay vì đăng trùng.
Phản hồi là một video mới, kèm warnings nếu kênh đã chạm mốc khuyến nghị số bài trong 24 giờ. Theo dõi kết quả từng kênh qua GET /videos/{id} (targets[]) — xem Video. Đăng nhiều tệp thì gọi lần lượt từng tệp.
Mẫu thương hiệu
GET /templates?page=1&pageSize=25
GET /templates/{id}Lấy id ở đây rồi truyền vào templateId lúc tạo video hoặc lúc dựng nguồn tin. Phản hồi cố ý gọn: name, kind, themeId và bgmEnabled.
Gần năm mươi trường toạ độ và màu sắc bên trong mẫu không có mặt: đó là cách khâu dựng vẽ ra khung hình, và mang chúng ra ngoài là trói hợp đồng của bạn vào một cách dựng cụ thể. Sửa mẫu làm trên giao diện web.
Số liệu hiệu quả
GET /analytics/overview GET /analytics/videos?sort=views&limit=20&channelIds=a,b
overviewtrả tổng lượt xem 30 ngày, tỷ lệ tương tác, số bài, người theo dõi mới, biểu đồ theo ngày, và phần chia theo từng kênh.videostrả bảng xếp hạng bài đăng.sortnhậnviews,likeshoặcrecent.channelIdsnhận cả kiểu lặp lại (?channelIds=a&channelIds=b) lẫn kiểu ngăn bằng dấu phẩy. Bỏ trống là gộp mọi kênh.
insightIssue nói vì sao số liệu của một kênh không đầy đủ
Trường này trả về mã, không phải câu mô tả — mã là thứ so sánh được, còn câu chữ tuỳ ngôn ngữ và sửa lúc nào cũng được. null nghĩa là lấy được hết.
platformVideoId trong bảng xếp hạng là id của bài trên chính nền tảng đó, không phải id video trong hệ này — đừng đem nó đi gọi GET /videos/{id}.
