Com a API do MiniMax H3 do PoYo, podes gerar vídeos 2K de 5 a 15 segundos a partir de texto, de primeiro e último frames ou de media de referência. Sem media de referência, um vídeo de 5 segundos tem um custo estimado de 105 créditos ($0.525).
Este guia começa com o teu primeiro pedido e depois aborda os preços, os modos de entrada, exemplos em Python e Node.js e prompts para diferentes cenas. Todos os endpoints e preços deste guia aplicam-se ao PoYo.
Início rápido: submete uma tarefa e obtém o vídeo
1. Submete uma tarefa de vídeo de 5 segundos
Obtém uma chave de API na consola do PoYo, substitui YOUR_POYO_API_KEY abaixo e executa o comando num terminal ou no teu servidor. Mantém a chave no servidor; não a incluas em código de browser nem em repositórios públicos.
Nos pedidos ao PoYo, o valor de model para o MiniMax H3 é hailuo-03. O exemplo seguinte submete uma tarefa de geração paga.
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"
}
}'
Depois de uma submissão bem-sucedida, lê o ID da tarefa em data.task_id. Este exemplo mostra a estrutura da resposta com um ID de tarefa de substituição:
{
"code": 200,
"message": "success",
"data": {
"task_id": "YOUR_TASK_ID"
}
}
2. Consulta o resultado da tarefa
Define TASK_ID com o ID de tarefa devolvido e usa a mesma chave de 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}"
Uma submissão bem-sucedida significa que a tarefa foi aceite; ainda tens de esperar que a geração do vídeo termine. A resposta da consulta tem quatro valores possíveis em data.status:
| Estado | Significado | Passo seguinte |
|---|---|---|
not_started | À espera de ser processada | Consulta novamente mais tarde |
running | Geração em curso | Consulta novamente mais tarde |
finished | Geração concluída | Lê data.files[].file_url |
failed | A geração falhou | Verifica data.error_message e pára de consultar |
Eis um exemplo de uma resposta concluída. O URL e a data e hora são ilustrativos:
{
"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
}
}
Consulta a documentação de consulta de tarefas do PoYo para ver as definições dos campos e exemplos de resposta para outros estados. Se uma consulta falhar temporariamente ou o teu período de espera expirar, guarda o ID da tarefa e consulta novamente mais tarde; não submetas automaticamente outra geração paga.
Como funcionam os preços do MiniMax H3 no PoYo
Os preços seguintes foram verificados a 21 de setembro de 2026. Todos os valores estão em USD, com 1 crédito = $0.005. Antes de gerares em massa, confirma os preços mais recentes na página do modelo.
| Item faturável | Créditos | USD |
|---|---|---|
| Duração do vídeo gerado | 21 créditos/segundo | $0.105/segundo |
| Duração do vídeo de referência de entrada | 21 créditos/segundo | $0.105/segundo |
| Primeiras 5 imagens de referência por geração | 0 | $0 |
| Cada imagem de referência a partir da 6.ª | 6,4 créditos | $0.032 |
Créditos estimados = 21 × (segundos de saída + segundos faturáveis de vídeo de referência) + 6,4 × o número de imagens de referência acima de 5. Com 5 ou menos imagens de referência, o custo adicional de imagens é 0. Multiplica os créditos estimados por $0.005 para obteres o custo em USD. Nos vídeos de referência com segundos fracionários, a faturação usa a duração determinada pelo servidor.
| Exemplo | Créditos estimados | USD estimados |
|---|---|---|
| Gerar 5 segundos sem media de referência | 105 | $0.525 |
| Gerar 10 segundos sem media de referência | 210 | $1.05 |
| Gerar 15 segundos sem media de referência | 315 | $1.575 |
| Gerar 10 segundos + 5 segundos de vídeo de referência + 7 imagens de referência | 327,8 | $1.639 |
O último exemplo usa 21 × (10 + 5) + 6.4 × (7 − 5). Estes são custos por geração; se um plano precisar de várias tentativas, inclui cada geração no teu orçamento.
Escolhe um modo de entrada e a media de referência
Os campos de media que submetes determinam o modo de entrada. O exemplo de início rápido acima usa texto para vídeo. Acrescenta os campos adequados quando precisares de especificar frames inicial e final ou de usar media de referência.
| Modo | Campos de entrada | Utilização |
|---|---|---|
| Texto para vídeo | prompt, sem URLs de media | Descreve por palavras a cena, a ação e o movimento de câmara |
| Geração com primeiro/último frame | image_urls | A primeira imagem é o frame inicial; a segunda, opcional, é o frame final. Omite aspect_ratio; o primeiro frame determina a proporção |
| Geração com referências multimodais | reference_image_urls, reference_video_urls, reference_audio_urls | Combina imagens, vídeo e áudio; o áudio de referência exige uma imagem ou um vídeo de referência |
Não combines image_urls com nenhum campo reference_*_urls. Todos os URLs de media têm de ser acessíveis publicamente e transferíveis diretamente.
Limites de parâmetros e de media
Os limites seguintes vêm da documentação da API do MiniMax H3 do PoYo:
prompté obrigatório e aceita até 2000 carateres.durationé um número inteiro de 5 a 15 segundos, com 5 por predefinição;resolutionsó suporta2K.- Texto para vídeo suporta
21:9,16:9,4:3,1:1,3:4e9:16, com16:9por predefinição. O modo de referência também suportaadaptivee usa-o por predefinição. - Podes fornecer até 9 imagens de referência, 3 vídeos de referência e 3 clipes de áudio de referência. Cada clipe de vídeo ou de áudio tem de durar entre 2 e 15 segundos; a duração total de vídeo e a duração total de áudio têm de ficar, cada uma, dentro de 15 segundos.
Exemplo de pedido com primeiro/último frame
Usa o JSON abaixo como corpo de POST /api/generate/submit. Os URLs de media em example.com são marcadores de posição: substitui-os pela tua própria media transferível antes de submeteres. Para usares apenas um frame inicial, remove o segundo URL do array.
{
"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"
]
}
}
Exemplo de referência combinada de imagem e vídeo
Usa Image 1 para especificar o aspeto da personagem e Video 1 para o movimento de câmara pretendido. Referem-se ao primeiro item do array de imagens e do array de vídeos, respetivamente. Substitui os URLs de media e verifica a duração do vídeo de referência antes de submeteres.
{
"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"
]
}
}
Exemplos de integração em Python e Node.js
Os exemplos abaixo separam a submissão e a consulta em duas funções: obtém e guarda primeiro o ID da tarefa e só depois espera pelo resultado. Se a consulta for interrompida, retoma-a com o ID da tarefa original, sem gerar de novo. Só as consultas de estado repetem em caso de erros de ligação, tempos limite, HTTP 429 e alguns erros 5xx; as submissões não são repetidas automaticamente.
Ambas as implementações esperam 10 segundos entre consultas, fazem até 60 consultas e definem um tempo limite de 30 segundos por pedido. O tempo total de espera inclui, por isso, também a duração dos pedidos. Estas são definições da aplicação dos exemplos, não uma garantia de tempo de geração. Ajusta os intervalos e a política de repetição às necessidades da tua aplicação.
Python: submeter uma tarefa e consultar o resultado
Instala a dependência com python -m pip install requests e define a variável de ambiente POYO_API_KEY como descrito acima. Este script Python síncrono consulta repetidamente uma tarefa de geração assíncrona.
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))
Para retomares a consulta, chama diretamente wait_for_h3(saved_task_id). Erros HTTP como 401 e 403, erros ao nível da API ou respostas inesperadas interrompem a consulta; resolve a causa antes de continuares.
Node.js: usar o fetch integrado
O JavaScript seguinte usa o fetch integrado no Node.js 20 ou superior, pelo que não é necessária nenhuma dependência de cliente HTTP. Guarda-o como um ficheiro .mjs e executa-o no servidor.
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));
Para retomares a consulta, substitui as chamadas de submissão e de consulta no final do ficheiro por waitForH3(savedTaskId). Este exemplo de consulta repetida é adequado para scripts ou tarefas em segundo plano. Numa aplicação web, devolve o ID da tarefa ao frontend e acompanha a geração em segundo plano, em vez de manteres um pedido de página à espera.
Receber resultados através de um webhook
Também podes passar callback_url ao nível superior do pedido de submissão, junto a model e input, por exemplo https://your-domain.com/webhooks/poyo. O PoYo envia o resultado para esse URL quando a tarefa termina com sucesso ou falha.
O recetor deve fazer corresponder o ID da tarefa aos registos locais e tratar as notificações duplicadas por ID de tarefa, para evitar repetir operações a jusante. O trabalho demorado, como transferir ou transcodificar o vídeo, pode correr em tarefas em segundo plano. Podes continuar a usar consultas de estado para verificar os resultados enquanto integras os callbacks.
Prompts e exemplos de cenas
Descreve primeiro o sujeito e a ação e depois acrescenta o movimento de câmara, o cenário, a iluminação e o som. Quando usares media de referência, indica o papel de Image 1, Video 1 ou Audio 1, para que uma única referência não carregue requisitos contraditórios.
Os quatro exemplos em inglês abaixo ilustram a escrita de prompts; não incluem resultados de geração testados. Os termos em inglês tornam os exemplos fáceis de reutilizar, mas não significam que o inglês funcione necessariamente melhor do que o chinês. As instruções de tempo e de preservação do aspeto descrevem resultados pretendidos; inspeciona o resultado real.
Anúncio de produto: 8 segundos, modo de imagem de referência
Coloca primeiro a imagem do produto em input.reference_image_urls, define duration: 8 e aspect_ratio: "16:9" e usa o texto abaixo como prompt. Segue a estrutura de pedido do modo de referência acima; remove reference_video_urls se não precisares de um vídeo de referência.
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.
Começa com um plano simples para verificares se o frasco e o rótulo se mantêm consistentes e só depois experimenta movimentos de câmara orbitais mais complexos.
Diálogo de uma personagem: 8 segundos, modo de imagem de referência
Coloca primeiro a imagem da personagem em input.reference_image_urls e define duration: 8 e aspect_ratio: "16:9". Uma frase curta de diálogo facilita a verificação da sincronização labial, do ritmo da fala e do aspeto da personagem.
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.
Anúncio vertical de um jogo: 10 segundos, texto para vídeo
Define duration: 10 e aspect_ratio: "9:16". Os segmentos de tempo exprimem a sequência de ações pretendida; se a cena parecer sobrecarregada, começa por reduzir o número de ações e de personagens.
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.
Travelling contínuo: 10 segundos, texto para vídeo
Define duration: 10 e aspect_ratio: "16:9". Constrói o plano em torno de um sujeito e de um percurso e depois verifica se há cortes, alterações do sujeito ou movimento descontínuo.
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.
Perguntas frequentes e resolução de problemas de integração
Posso usar diretamente o formato de pedido da própria API da MiniMax?
Estes exemplos usam POST /api/generate/submit e GET /api/generate/status/{task_id} do PoYo. Os endpoints, os identificadores de modelos e as estruturas de campos podem diferir entre plataformas; segue a documentação da plataforma que utilizares.
Devo voltar a submeter uma tarefa que fica em not_started?
not_started significa que a tarefa está à espera de ser processada; não é, por si só, uma falha. Guarda o ID da tarefa e continua a consultar. Se o limite de espera da tua aplicação expirar, regista a tarefa e verifica-a mais tarde. Se necessário, contacta o suporte com o ID da tarefa.
E se a submissão expirar antes de eu receber um ID de tarefa?
Um tempo limite do pedido não prova que o servidor não aceitou a tarefa. Verifica primeiro os registos de tarefas; se necessário, contacta o suporte com pormenores como a hora da submissão. Precisas de um ID de tarefa para usar o endpoint de consulta de estado. Não trates a nova submissão como remédio para uma consulta falhada.
Posso combinar imagens, vídeo e áudio como referências?
Sim, combina-os no modo de referência, dentro dos limites de quantidade e de duração acima. O áudio de referência exige uma imagem ou um vídeo de referência. Estes campos não podem ser combinados com image_urls no modo de primeiro/último frame.
Quanto custa um vídeo de 10 segundos?
Aos preços aqui indicados, sem media de referência, o custo é 10 × 21 = 210 créditos, ou $1.05. Os vídeos de referência e as imagens de referência além das primeiras 5 acrescem ao custo.
Antes de integrares na tua aplicação, confirma que os URLs de media permitem transferências diretas, guarda os IDs das tarefas e define limites adequados de geração e de concorrência por utilizador. Antes de publicares um vídeo gerado, verifica se o aspeto das personagens, a forma do produto, o texto, o movimento e o som se adequam à utilização prevista.
Experimenta gerar na página do modelo MiniMax H3 ou visita a página de chaves de API para começares a integrar. Para saberes mais sobre os modelos, consulta a análise do MiniMax H3 e a comparação entre o MiniMax H3 e o Seedance 2.5.