Tất cả bài viết
How-tos17 phút đọc

Hướng dẫn API MiniMax H3: tích hợp PoYo, giá và prompt

Dùng MiniMax H3 qua PoYo: tìm hiểu tham số video 2K, ba chế độ đầu vào và chi phí; gửi, tra cứu tác vụ bằng cURL, Python hoặc Node.js; tham khảo prompt cho video sản phẩm và nhân vật.

Với API MiniMax H3 của PoYo, bạn có thể tạo video 2K dài 5–15 giây từ văn bản, khung hình đầu và cuối hoặc tư liệu tham chiếu. Khi không dùng tư liệu tham chiếu, video 5 giây có chi phí ước tính là 105 credit ($0.525).

Hướng dẫn này bắt đầu từ yêu cầu đầu tiên, sau đó trình bày giá, chế độ đầu vào, ví dụ Python và Node.js cùng cách viết prompt cho từng cảnh. Tất cả endpoint và mức giá trong bài đều áp dụng cho PoYo.

Bắt đầu nhanh: gửi tác vụ và lấy video

1. Gửi tác vụ tạo video 5 giây

Lấy khóa API tại bảng điều khiển PoYo, thay YOUR_POYO_API_KEY bên dưới rồi chạy lệnh trong terminal hoặc trên máy chủ. Giữ khóa ở phía máy chủ; không đưa vào mã chạy trên trình duyệt hay kho mã công khai.

Trong yêu cầu gửi đến PoYo, giá trị model của MiniMax H3 là hailuo-03. Ví dụ sau sẽ gửi một tác vụ tạo video có tính phí.

export POYO_API_KEY="YOUR_POYO_API_KEY"

curl --fail-with-body --max-time 30 \
  --request POST 'https://api.poyo.ai/api/generate/submit' \
  --header "Authorization: Bearer ${POYO_API_KEY}" \
  --header 'Content-Type: application/json' \
  --data '{
    "model": "hailuo-03",
    "input": {
      "prompt": "A golden retriever walks through a sunlit autumn park. One slow tracking shot, natural movement, warm afternoon light.",
      "duration": 5,
      "resolution": "2K",
      "aspect_ratio": "16:9"
    }
  }'

Sau khi gửi thành công, đọc ID tác vụ từ data.task_id. Ví dụ dưới đây minh họa cấu trúc phản hồi với ID tác vụ là giá trị giữ chỗ:

{
  "code": 200,
  "message": "success",
  "data": {
    "task_id": "YOUR_TASK_ID"
  }
}

2. Tra cứu kết quả tác vụ

Gán ID nhận được cho TASK_ID và sử dụng cùng khóa API:

TASK_ID="YOUR_TASK_ID"

curl --fail-with-body --max-time 30 \
  --request GET "https://api.poyo.ai/api/generate/status/${TASK_ID}" \
  --header "Authorization: Bearer ${POYO_API_KEY}"

Gửi thành công có nghĩa là tác vụ đã được tiếp nhận; bạn vẫn cần chờ video tạo xong. Trường data.status trong phản hồi tra cứu có bốn giá trị:

Trạng thái Ý nghĩa Bước tiếp theo
not_started Đang chờ xử lý Tra cứu lại sau
running Đang tạo Tra cứu lại sau
finished Đã tạo xong Đọc data.files[].file_url
failed Tạo thất bại Kiểm tra data.error_message và dừng truy vấn định kỳ

Dưới đây là ví dụ phản hồi khi hoàn tất. URL và thời gian chỉ dùng để minh họa:

{
  "code": 200,
  "data": {
    "task_id": "YOUR_TASK_ID",
    "status": "finished",
    "credits_amount": 105,
    "files": [
      {
        "file_url": "https://example.com/generated/video.mp4",
        "file_type": "video"
      }
    ],
    "created_time": "2026-09-22T08:30:00",
    "progress": 100,
    "error_message": null
  }
}

Xem định nghĩa các trường và ví dụ cho trạng thái khác trong tài liệu tra cứu tác vụ PoYo. Nếu truy vấn tạm thời thất bại hoặc hết thời gian chờ, hãy giữ ID để tra cứu lại sau; không tự động gửi một tác vụ tạo video có tính phí khác.

Cách tính phí MiniMax H3 trên PoYo

Các mức giá dưới đây được kiểm tra vào ngày 21 tháng 9 năm 2026. Tất cả số tiền là USD, quy đổi theo 1 credit = $0.005. Trước khi tạo hàng loạt, hãy xác nhận giá mới nhất trên trang mô hình.

Hạng mục tính phí Credit USD
Thời lượng video được tạo 21 credit/giây $0.105/giây
Thời lượng video tham chiếu đầu vào 21 credit/giây $0.105/giây
5 ảnh tham chiếu đầu tiên trong mỗi lần tạo 0 $0
Mỗi ảnh tham chiếu từ ảnh thứ 6 trở đi 6.4 credit $0.032

Credit ước tính = 21 × (số giây đầu ra + số giây video tham chiếu được tính phí) + 6.4 × số ảnh tham chiếu vượt quá 5 ảnh. Nếu có tối đa 5 ảnh tham chiếu, phí ảnh bổ sung là 0. Nhân credit ước tính với $0.005 để ra chi phí USD. Nếu thời lượng video tham chiếu có phần lẻ của giây, phí được tính theo thời lượng mà máy chủ xác định.

Ví dụ Credit ước tính USD ước tính
Tạo 5 giây không dùng tư liệu tham chiếu 105 $0.525
Tạo 10 giây không dùng tư liệu tham chiếu 210 $1.05
Tạo 15 giây không dùng tư liệu tham chiếu 315 $1.575
Tạo 10 giây + video tham chiếu 5 giây + 7 ảnh tham chiếu 327.8 $1.639

Ví dụ cuối được tính bằng 21 × (10 + 5) + 6.4 × (7 − 5). Đây là chi phí cho một lần tạo; nếu một cảnh cần thử nhiều lần, hãy tính từng lần vào ngân sách.

Chọn chế độ đầu vào và tư liệu tham chiếu

Các trường media được gửi quyết định chế độ đầu vào. Ví dụ bắt đầu nhanh ở trên dùng văn bản để tạo video. Hãy thêm trường tương ứng khi cần chỉ định khung hình đầu, cuối hoặc sử dụng tư liệu tham chiếu.

Chế độ Trường đầu vào Cách dùng
Văn bản thành video prompt, không gửi URL media Mô tả cảnh, hành động và chuyển động máy quay bằng lời
Tạo từ khung hình đầu và cuối image_urls Ảnh đầu là khung hình bắt đầu; ảnh thứ hai, không bắt buộc, là khung hình kết thúc. Không gửi aspect_ratio; tỷ lệ theo khung hình đầu
Tạo với tham chiếu đa phương thức reference_image_urls, reference_video_urls, reference_audio_urls Kết hợp ảnh, video và âm thanh; âm thanh tham chiếu cần có ảnh hoặc video tham chiếu đi kèm

Không kết hợp image_urls với bất kỳ trường reference_*_urls nào. Mọi URL media phải truy cập công khai được và cho phép tải xuống trực tiếp.

Giới hạn tham số và tư liệu

Các giới hạn sau dựa trên tài liệu API MiniMax H3 của PoYo:

  • prompt là bắt buộc và hỗ trợ tối đa 2000 ký tự.
  • duration là số nguyên từ 5–15 giây, mặc định 5; resolution chỉ hỗ trợ 2K.
  • Chế độ văn bản thành video hỗ trợ 21:9, 16:9, 4:3, 1:1, 3:4 và 9:16, mặc định là 16:9. Chế độ tham chiếu còn hỗ trợ adaptive và dùng giá trị này làm mặc định.
  • Có thể gửi tối đa 9 ảnh, 3 video và 3 đoạn âm thanh tham chiếu. Mỗi video hoặc đoạn âm thanh phải dài 2–15 giây; tổng thời lượng video và tổng thời lượng âm thanh mỗi loại không được vượt quá 15 giây.

Ví dụ yêu cầu dùng khung hình đầu và cuối

Dùng JSON dưới đây làm nội dung yêu cầu POST /api/generate/submit. Các URL trên example.com chỉ là giá trị giữ chỗ: thay bằng tư liệu của bạn có thể tải xuống trước khi gửi. Nếu chỉ dùng khung hình đầu, hãy xóa URL thứ hai khỏi mảng.

{
  "model": "hailuo-03",
  "input": {
    "prompt": "The camera slowly moves through the temple doorway, starting at the entrance and ending inside the hall. Dust floats in the sunlight.",
    "duration": 6,
    "resolution": "2K",
    "image_urls": [
      "https://example.com/assets/temple-entrance.jpg",
      "https://example.com/assets/temple-interior.jpg"
    ]
  }
}

Ví dụ kết hợp ảnh và video tham chiếu

Dùng Image 1 để chỉ định ngoại hình nhân vật và Video 1 cho chuyển động máy quay mong muốn. Chúng lần lượt trỏ đến phần tử đầu tiên trong mảng ảnh và mảng video. Thay URL tư liệu và kiểm tra thời lượng video tham chiếu trước khi gửi.

{
  "model": "hailuo-03",
  "input": {
    "prompt": "Use Image 1 for the character appearance and outfit. The character turns and walks toward the window. Use Video 1 as the camera movement reference.",
    "duration": 8,
    "resolution": "2K",
    "aspect_ratio": "adaptive",
    "reference_image_urls": [
      "https://example.com/assets/character.png"
    ],
    "reference_video_urls": [
      "https://example.com/assets/camera-motion.mp4"
    ]
  }
}

Ví dụ tích hợp Python và Node.js

Các ví dụ tách việc gửi và tra cứu thành hai hàm: lấy và lưu ID tác vụ trước, sau đó chờ kết quả. Nếu tra cứu bị gián đoạn, bạn có thể tiếp tục bằng ID cũ mà không cần tạo lại. Chỉ truy vấn trạng thái mới thử lại khi gặp lỗi kết nối, hết thời gian chờ, HTTP 429 hoặc một số lỗi 5xx; thao tác gửi không tự động thử lại.

Cả hai cách triển khai đều chờ 10 giây giữa các truy vấn, thực hiện tối đa 60 truy vấn và đặt thời gian chờ 30 giây cho mỗi yêu cầu. Vì vậy, tổng thời gian chờ còn bao gồm thời gian thực hiện yêu cầu. Đây là cấu hình ứng dụng trong ví dụ, không phải cam kết về thời gian tạo. Hãy điều chỉnh khoảng chờ và chính sách thử lại theo nhu cầu ứng dụng.

Python: gửi tác vụ và tra cứu kết quả định kỳ

Cài thư viện bằng python -m pip install requests và đặt biến môi trường POYO_API_KEY như hướng dẫn ở trên. Script Python đồng bộ này truy vấn định kỳ một tác vụ tạo video bất đồng bộ.

import os
import time
import requests

BASE_URL = "https://api.poyo.ai"
API_KEY = os.environ["POYO_API_KEY"]
if not API_KEY.strip():
    raise ValueError("Set POYO_API_KEY")
HEADERS = {"Authorization": f"Bearer {API_KEY}"}
RETRYABLE_HTTP = {429, 500, 502, 503, 504}


def response_data(response):
    response.raise_for_status()
    body = response.json()
    if body.get("code") != 200 or not isinstance(body.get("data"), dict):
        raise RuntimeError(f"Unexpected API response: {body}")
    return body["data"]


def submit_h3(prompt, duration=5):
    response = requests.post(
        f"{BASE_URL}/api/generate/submit",
        headers=HEADERS,
        json={"model": "hailuo-03", "input": {
            "prompt": prompt, "duration": duration,
            "resolution": "2K", "aspect_ratio": "16:9",
        }},
        timeout=30,
    )
    task_id = response_data(response).get("task_id")
    if not isinstance(task_id, str) or not task_id:
        raise RuntimeError("Submission response is missing a task ID; check records instead of resubmitting automatically")
    return task_id


def wait_for_h3(task_id, max_polls=60):
    for _ in range(max_polls):
        time.sleep(10)
        try:
            response = requests.get(
                f"{BASE_URL}/api/generate/status/{task_id}",
                headers=HEADERS, timeout=30,
            )
        except (requests.Timeout, requests.ConnectionError):
            continue
        if response.status_code in RETRYABLE_HTTP:
            continue
        task = response_data(response)
        status = task.get("status")
        if status == "finished":
            for item in task.get("files") or []:
                if item.get("file_type") == "video" and item.get("file_url"):
                    return item["file_url"]
            raise RuntimeError(f"Task {task_id} finished, but the response has no video URL")
        if status == "failed":
            raise RuntimeError(f"Task {task_id} failed: {task.get('error_message')}")
        if status not in {"not_started", "running"}:
            raise RuntimeError(f"Task {task_id} returned an unknown status: {status}")
    raise TimeoutError(f"Query limit reached; keep the task ID and query again later: {task_id}")


if __name__ == "__main__":
    task_id = submit_h3("A golden retriever walks through a sunlit autumn park.")
    # In your application, save task_id to the database here before polling.
    print(f"Task ID: {task_id}", flush=True)
    print(wait_for_h3(task_id))

Để tiếp tục tra cứu, gọi trực tiếp wait_for_h3(saved_task_id). Lỗi HTTP như 401 và 403, lỗi ở cấp API hoặc phản hồi ngoài dự kiến sẽ dừng truy vấn; cần xử lý nguyên nhân trước khi tiếp tục.

Node.js: dùng fetch tích hợp sẵn

JavaScript dưới đây dùng fetch tích hợp trong Node.js 20 trở lên, không cần cài thêm thư viện HTTP client. Lưu thành tệp .mjs và chạy trên máy chủ.

const BASE_URL = 'https://api.poyo.ai';
const apiKey = process.env.POYO_API_KEY;
if (!apiKey?.trim()) throw new Error('Set POYO_API_KEY');
const headers = {
  Authorization: `Bearer ${apiKey}`,
  'Content-Type': 'application/json',
};
const retryableHttp = new Set([429, 500, 502, 503, 504]);
const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

async function responseData(response) {
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  const body = await response.json();
  if (body.code !== 200 || !body.data || typeof body.data !== 'object') {
    throw new Error(`Unexpected API response: ${JSON.stringify(body)}`);
  }
  return body.data;
}

export async function submitH3(prompt, duration = 5) {
  const response = await fetch(`${BASE_URL}/api/generate/submit`, {
    method: 'POST', headers,
    body: JSON.stringify({
      model: 'hailuo-03',
      input: { prompt, duration, resolution: '2K', aspect_ratio: '16:9' },
    }),
    signal: AbortSignal.timeout(30_000),
  });
  const data = await responseData(response);
  if (typeof data.task_id !== 'string' || !data.task_id) {
    throw new Error('Submission response is missing a task ID; check records instead of resubmitting automatically');
  }
  return data.task_id;
}

export async function waitForH3(taskId, maxPolls = 60) {
  for (let attempt = 0; attempt < maxPolls; attempt++) {
    await sleep(10_000);
    let response;
    try {
      response = await fetch(
        `${BASE_URL}/api/generate/status/${encodeURIComponent(taskId)}`,
        { headers, signal: AbortSignal.timeout(30_000) },
      );
    } catch (error) {
      if (error instanceof Error &&
          (error.name === 'TimeoutError' || error.name === 'TypeError')) {
        continue;
      }
      throw error;
    }
    if (retryableHttp.has(response.status)) {
      await response.body?.cancel();
      continue;
    }
    const task = await responseData(response);
    if (task.status === 'finished') {
      const video = task.files?.find((file) => file.file_type === 'video' && file.file_url);
      if (!video) throw new Error(`Task ${taskId} finished, but the response has no video URL`);
      return video.file_url;
    }
    if (task.status === 'failed') {
      throw new Error(`Task ${taskId} failed: ${task.error_message || 'No error details provided'}`);
    }
    if (!['not_started', 'running'].includes(task.status)) {
      throw new Error(`Task ${taskId} returned an unknown status: ${task.status}`);
    }
  }
  throw new Error(`Query limit reached; keep the task ID and query again later: ${taskId}`);
}

const taskId = await submitH3('A golden retriever walks through a sunlit autumn park.');
// In your application, save taskId to the database here before polling.
console.log(`Task ID: ${taskId}`);
console.log(await waitForH3(taskId));

Để tiếp tục tra cứu, thay các lệnh gửi và truy vấn cuối tệp bằng waitForH3(savedTaskId). Ví dụ này phù hợp cho script hoặc tác vụ nền. Trong ứng dụng web, hãy trả ID về frontend và theo dõi quá trình tạo ở nền, tránh giữ một yêu cầu trang chờ liên tục.

Nhận kết quả qua webhook

Bạn cũng có thể truyền callback_url ở cấp cao nhất của yêu cầu gửi, ngang hàng với model và input, ví dụ https://your-domain.com/webhooks/poyo. PoYo sẽ gửi kết quả đến URL đó khi tác vụ thành công hoặc thất bại.

Bên nhận cần đối chiếu ID với bản ghi cục bộ và xử lý thông báo trùng lặp theo ID tác vụ để tránh thực hiện lại các bước tiếp theo. Những việc mất thời gian như tải hoặc chuyển mã video có thể chạy ở nền. Trong quá trình tích hợp callback, bạn vẫn có thể dùng truy vấn trạng thái để xác minh kết quả.

Prompt và ví dụ theo cảnh

Mô tả chủ thể và hành động trước, sau đó thêm chuyển động máy quay, bối cảnh, ánh sáng và âm thanh. Khi dùng tham chiếu, nêu rõ vai trò của Image 1, Video 1 hoặc Audio 1 để một tư liệu không phải đáp ứng các yêu cầu mâu thuẫn.

Bốn ví dụ tiếng Anh dưới đây minh họa cách viết prompt; chưa kèm kết quả tạo đã kiểm thử. Thuật ngữ tiếng Anh thuận tiện để tái sử dụng, nhưng không có nghĩa tiếng Anh luôn tốt hơn tiếng Trung. Các mốc thời gian và yêu cầu giữ ngoại hình là mục tiêu; hãy kiểm tra kết quả thực tế.

Quảng cáo sản phẩm: 8 giây, chế độ ảnh tham chiếu

Đặt ảnh sản phẩm ở vị trí đầu trong input.reference_image_urls, thiết lập duration: 8 và aspect_ratio: "16:9", rồi dùng nội dung dưới đây làm prompt. Dùng cấu trúc yêu cầu của chế độ tham chiếu ở trên; xóa reference_video_urls nếu không cần video tham chiếu.

Use Image 1 as the product reference. A clear glass perfume bottle rests on
wet black stone after rain. Preserve the bottle shape, cap, and label placement.
One continuous 8-second shot: begin close to the water droplets, then slowly
pull back to reveal the bottle in warm rim light. Realistic glass reflections,
no added text. Soft rain ambience.

Bắt đầu với cảnh quay đơn giản để kiểm tra tính nhất quán của chai và nhãn, sau đó thử chuyển động máy quay vòng quanh phức tạp hơn.

Hội thoại nhân vật: 8 giây, chế độ ảnh tham chiếu

Đặt ảnh nhân vật ở vị trí đầu trong input.reference_image_urls, rồi thiết lập duration: 8 và aspect_ratio: "16:9". Một câu thoại ngắn giúp kiểm tra đồng bộ khẩu hình, tốc độ nói và ngoại hình dễ hơn.

Use Image 1 as the character reference. An 8-second medium close-up of a pastry
chef in a quiet kitchen at sunrise. She looks into the camera and says:
"Every detail matters in baking." Natural breathing, a subtle smile,
soft window light. Preserve her face, hairstyle, and apron. A steady camera,
clear speech, quiet room tone.

Quảng cáo game dạng dọc: 10 giây, văn bản thành video

Thiết lập duration: 10 và aspect_ratio: "9:16". Các khoảng thời gian thể hiện thứ tự hành động mong muốn; nếu cảnh quá nhiều chi tiết, hãy giảm số hành động và nhân vật trước.

A 10-second vertical fantasy game trailer.
0-3s: An armored knight walks through a ruined stone gate.
3-6s: One creature charges; the knight blocks once with a shield.
6-9s: The camera rises to reveal the fortress walls.
9-10s: Hold the final composition.
Readable action, consistent armor, wind and impact sounds, no UI or captions.

Cảnh quay bám theo liên tục: 10 giây, văn bản thành video

Thiết lập duration: 10 và aspect_ratio: "16:9". Tổ chức cảnh quanh một chủ thể và một lộ trình, rồi kiểm tra xem có cắt cảnh, thay đổi chủ thể hoặc chuyển động đứt quãng hay không.

One unbroken 10-second tracking shot follows a cyclist through a night market.
Begin behind the rear wheel, rise to shoulder height, then move alongside
without cutting. Wet pavement reflections, a clear path between stalls,
consistent bicycle geometry, no speed ramps or scene transitions.
Natural street ambience and bicycle tires rolling on wet pavement.

Câu hỏi thường gặp và xử lý lỗi tích hợp

Có thể dùng trực tiếp định dạng yêu cầu API riêng của MiniMax không?

Các ví dụ dùng POST /api/generate/submit và GET /api/generate/status/{task_id} của PoYo. Endpoint, mã định danh mô hình và cấu trúc trường có thể khác nhau giữa các nền tảng; hãy theo tài liệu của nền tảng bạn dùng.

Có nên gửi lại tác vụ vẫn ở trạng thái not_started không?

not_started nghĩa là tác vụ đang chờ xử lý, tự nó không phải lỗi. Giữ ID và tiếp tục tra cứu. Nếu đạt giới hạn chờ của ứng dụng, ghi lại tác vụ để kiểm tra sau. Khi cần, liên hệ bộ phận hỗ trợ kèm ID tác vụ.

Làm gì nếu yêu cầu gửi hết thời gian chờ trước khi nhận ID?

Hết thời gian chờ không chứng minh máy chủ chưa nhận tác vụ. Trước tiên kiểm tra bản ghi tác vụ; khi cần, liên hệ hỗ trợ và cung cấp thông tin như thời điểm gửi. Bạn phải có ID mới dùng được endpoint truy vấn trạng thái. Không dùng việc gửi lại để khắc phục một truy vấn thất bại.

Có thể kết hợp ảnh, video và âm thanh làm tham chiếu không?

Có, trong chế độ tham chiếu và trong các giới hạn số lượng, thời lượng ở trên. Âm thanh tham chiếu cần có ảnh hoặc video tham chiếu đi kèm. Không thể kết hợp các trường này với image_urls của chế độ khung hình đầu và cuối.

Video 10 giây tốn bao nhiêu?

Theo mức giá trong bài, nếu không dùng tư liệu tham chiếu, chi phí là 10 × 21 = 210 credit, tức $1.05. Video tham chiếu và ảnh tham chiếu vượt quá 5 ảnh đầu tiên sẽ làm tăng chi phí.

Trước khi tích hợp vào ứng dụng, xác nhận URL cho phép tải trực tiếp, lưu ID tác vụ và đặt giới hạn số lần tạo cùng số tác vụ đồng thời phù hợp cho mỗi người dùng. Trước khi đăng video, kiểm tra ngoại hình nhân vật, hình dạng sản phẩm, chữ, chuyển động và âm thanh có phù hợp mục đích sử dụng hay không.

Thử tạo video trên trang mô hình MiniMax H3, hoặc đến trang khóa API để bắt đầu tích hợp. Tìm hiểu thêm trong bài đánh giá MiniMax H3 và so sánh MiniMax H3 với Seedance 2.5.

Blog · PoYo.aiTất cả bài viết
KẾT NỐI

Bạn đang có dự án?

Hãy chia sẻ nhu cầu của bạn. Chúng tôi sẽ tư vấn API AI phù hợp.

Chúng tôi chỉ dùng thông tin để phản hồi yêu cầu này.

PoYo AI

Sẵn sàng khám phá mô hình?

Xem các mô hình hình ảnh, video, âm thanh và ngôn ngữ trên PoYo.

Xem mô hình AI