> ## Documentation Index
> Fetch the complete documentation index at: https://docs.aihubmix.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tarefas assíncronas

> API de tarefas assíncronas da AIHubMix: imagens com async, vídeo, recuperação de interrupção de LLM e webhook, com status e resultados em /ai/v1/tasks.

Requisições como geração de vídeo e geração de imagens em lote costumam levar mais tempo do que é razoável esperar em uma única conexão HTTP. Além disso, se o cliente se desconectar durante a geração de textos longos, a resposta já produzida também não pode mais ser recuperada.

As **tarefas assíncronas** (Async Tasks) unificam esses três cenários em um mesmo objeto de tarefa: imagens e vídeos criam a tarefa pela interface de geração e retornam imediatamente o `task_id`, enquanto requisições de LLM interrompidas pelo cliente são concluídas pela plataforma, que salva a resposta final. Os três compartilham os mesmos status de tarefa, a mesma interface de consulta e o mesmo fluxo de download de resultados.

<Note>
  Use a mesma API Key com que a tarefa foi criada para consultar a tarefa e baixar os resultados. As tarefas são isoladas por API Key: mesmo que duas Keys pertençam à mesma conta, uma não pode ler as tarefas da outra.
</Note>

<Card title="Acessar o console para ativar as tarefas assíncronas" icon="list-check" href="https://console.aihubmix.com/support" horizontal>
  Antes de criar imagens ou vídeos assíncronos, ative o recurso de tarefas assíncronas para a conta atual. Se o console ainda não exibir esse acesso, entre em contato com o suporte técnico da AIHubMix.
</Card>

<Warning>
  Quando o recurso de tarefas assíncronas não está ativado, as requisições de criação de tarefas de mídia retornam `403 async_not_enabled`. As requisições de LLM não geram erro por causa disso, mas a resposta final não pode ser recuperada depois que o cliente se desconecta.
</Warning>

***

<h2 id="quickstart">
  Início rápido
</h2>

O fluxo completo das tarefas assíncronas de imagem e vídeo tem três etapas:

```text theme={null}
1. Enviar a tarefa -> obter o task_id
2. Consultar o status -> aguardar a conclusão da tarefa
3. Obter o resultado -> baixar o arquivo ou ler o conteúdo da resposta
```

<CodeGroup>
  ```shell curl theme={null}
  # Etapa 1: enviar a tarefa assíncrona de vídeo
  curl -X POST https://aihubmix.com/ai/v1/videos \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "wan2.6-t2v",
      "prompt": "A cat playing jazz on a piano, warm lighting, cinematic shot",
      "seconds": "5",
      "size": "1280x720"
    }'

  # Etapa 2: consultar a cada 15 segundos, até a tarefa ser concluída, falhar ou ser cancelada
  curl https://aihubmix.com/ai/v1/tasks/{task_id} \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY"

  # Etapa 3: baixar um único arquivo gerado
  curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.mp4
  ```

  ```json Resposta de criação theme={null}
  {
    "id": "task_01K0...",
    "object": "video",
    "model": "wan2.6-t2v",
    "status": "in_progress",
    "output": [],
    "error": null,
    "created_at": 1784707200,
    "completed_at": null,
    "expires_at": null
  }
  ```
</CodeGroup>

***

<h2 id="sync-vs-async">
  Comparação: chamadas síncronas vs tarefas assíncronas
</h2>

| Tipo de requisição       | Forma de retorno padrão               | Forma assíncrona                                                                                        |
| ------------------------ | ------------------------------------- | ------------------------------------------------------------------------------------------------------- |
| Geração de imagens       | Retorna o resultado de forma síncrona | Com `async: true` no corpo da requisição, retorna imediatamente o `task_id`                             |
| Geração de vídeo         | Sempre assíncrona                     | Retorna o `task_id` após a criação; o resultado é obtido pela interface de tarefas                      |
| Geração de texto por LLM | Retorno síncrono ou em streaming      | Quando o cliente se desconecta e as condições são atendidas, a resposta final é salva como tarefa `llm` |

Uma chamada síncrona retorna o resultado dentro de uma única resposta HTTP e o resultado não pode ser recuperado se a conexão cair. As tarefas assíncronas mantêm o resultado no lado da plataforma, e o `task_id` permite consultar e baixar novamente com a mesma API Key antes de o resultado expirar. Isso serve para requisições de geração demoradas e para saídas de texto longo cuja resposta final precisa ser recuperada após uma interrupção.

***

<h2 id="api-overview">
  Visão geral das interfaces
</h2>

| Operação                      | Método | Caminho                                      | Descrição                                                |
| ----------------------------- | ------ | -------------------------------------------- | -------------------------------------------------------- |
| Criar imagem assíncrona       | POST   | `/ai/v1/images/generations`                  | Adicione `async: true` ao corpo da requisição            |
| Criar vídeo assíncrono        | POST   | `/ai/v1/videos`                              | Tarefas de vídeo são assíncronas por padrão              |
| Consultar a lista de tarefas  | GET    | `/ai/v1/tasks`                               | Localiza as tarefas criadas pela API Key atual           |
| Consultar detalhes da tarefa  | GET    | `/ai/v1/tasks/{task_id}`                     | Consulta o status unificado e a saída da tarefa          |
| Obter um único resultado      | GET    | `/ai/v1/tasks/{task_id}/content`             | Serve para tarefas de um único arquivo ou tarefas de LLM |
| Obter um resultado específico | GET    | `/ai/v1/tasks/{task_id}/content/{result_id}` | Serve para tarefas com múltiplos arquivos                |

Base URL: `https://aihubmix.com`, com autenticação por Bearer Token:

```bash theme={null}
Authorization: Bearer $AIHUBMIX_API_KEY
```

<Note>
  `/ai/v1/tasks` é um ponto de consulta unificado somente leitura e não oferece `POST /ai/v1/tasks`. Imagens e vídeos são criados pelas respectivas interfaces de geração; as requisições que atendem às condições de [recuperação de interrupção de LLM](#llm-interruption-recovery) são registradas automaticamente como tarefas `llm` após a desconexão do cliente.
</Note>

***

<h2 id="supported-models">
  Modelos suportados
</h2>

As tarefas assíncronas dividem a cobertura por tipo de tarefa e não exigem parâmetros adicionais na chamada.

<h3 id="supported-models-image">
  Imagem assíncrona
</h3>

| Modelo           |
| ---------------- |
| `qwen-image-2.0` |

<h3 id="supported-models-video">
  Vídeo assíncrono
</h3>

| Modelo       |
| ------------ |
| `wan2.6-t2v` |

<h3 id="supported-models-llm">
  Recuperação de interrupção de LLM
</h3>

| Modelo           |
| ---------------- |
| `gpt-5.5-pro`    |
| `claude-fable-5` |

A cobertura será ampliada continuamente e esta tabela será atualizada junto.

***

<h2 id="create-async-task">
  Como criar uma tarefa assíncrona
</h2>

<h3 id="create-async-image">
  Imagem assíncrona
</h3>

A interface de imagens retorna de forma síncrona por padrão. Com `async` definido como `true`, a interface retorna imediatamente o objeto de tarefa e o processo de geração continua em segundo plano.

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/images/generations \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "qwen-image-2.0",
    "prompt": "A flower shop with delicate windows, warm sunlight streaming in",
    "n": 2,
    "size": "1024x1024",
    "async": true
  }'
```

`async` deve ser um valor booleano. Se não for enviado ou for definido como `false`, a interface de imagens mantém o comportamento síncrono.

<h3 id="create-async-video">
  Vídeo assíncrono
</h3>

A interface de vídeo é sempre assíncrona. Após a criação bem-sucedida, ela retorna o status `pending` ou `in_progress` e não permite mudar para espera síncrona com `Prefer: wait`.

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "Ocean waves crashing on rocky cliffs at sunset",
    "seconds": "5",
    "size": "1280x720"
  }'
```

<h3 id="common-parameters">
  Parâmetros comuns
</h3>

Nos exemplos, `model`, `prompt`, `n`, `seconds` e `size` são parâmetros de modelo comuns. Os campos e valores aceitos por cada modelo seguem a documentação de API do modelo correspondente; para modelos de vídeo, consulte a [documentação de geração de vídeo](/pt/api/Video-Gen). A tabela abaixo descreve apenas os parâmetros compartilhados por todas as tarefas assíncronas.

| Parâmetro               | Tipo      | Obrigatório                                 | Descrição                                                                  |
| ----------------------- | --------- | ------------------------------------------- | -------------------------------------------------------------------------- |
| `async`                 | boolean   | Imagem: sim; vídeo: não é necessário enviar | Com `true`, a interface de imagens executa de forma assíncrona             |
| `webhook_url`           | string    | Não                                         | Endereço HTTPS de callback da tarefa atual, com no máximo 512 caracteres   |
| `webhook_events_filter` | string\[] | Não                                         | Estados finais a serem enviados, entre `completed`, `failed` e `cancelled` |

<Note>
  Tarefas de imagem só podem usar Webhook quando têm `async: true`. Ao omitir `webhook_events_filter`, a plataforma envia os três estados finais `completed`, `failed` e `cancelled`; quando informado, ele deve ser usado junto com `webhook_url` e não pode ser vazio nem conter valores repetidos.
</Note>

***

<h2 id="llm-interruption-recovery">
  Como funciona a recuperação de interrupção de LLM
</h2>

A recuperação de interrupção de LLM serve para recuperar a resposta final depois que o cliente se desconecta. Esse recurso reutiliza a forma atual de fazer requisições de LLM, mantém o comportamento de streaming e o formato de resposta, não exige a chamada de uma interface de criação adicional e não retorna um `task_id` antecipadamente.

<h3 id="recovery-conditions">
  Condições de funcionamento
</h3>

As condições abaixo devem ser atendidas ao mesmo tempo:

| Condição                                          | Descrição                                                                                                               |
| ------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
| A conta tem as tarefas assíncronas ativadas       | Ative o recurso para a conta atual no console da AIHubMix                                                               |
| O modelo usado suporta recuperação de interrupção | Consulte [Recuperação de interrupção de LLM](#supported-models-llm); nenhum parâmetro adicional é necessário na chamada |
| A chamada usa uma interface de LLM suportada      | A requisição atinge uma das interfaces de geração de texto listadas abaixo                                              |
| Ocorre uma interrupção no cliente                 | Cancelamento pelo próprio cliente, queda de rede ou cancelamento pelo chamador                                          |

Interfaces suportadas:

| Interface                                          | Descrição                                                        |
| -------------------------------------------------- | ---------------------------------------------------------------- |
| `POST /v1/chat/completions`                        | OpenAI Chat Completions, com suporte a streaming e sem streaming |
| `POST /v1/messages`                                | Anthropic Messages, com suporte a streaming e sem streaming      |
| `POST /v1/responses`                               | OpenAI Responses API                                             |
| Gemini `generateContent` / `streamGenerateContent` | Interfaces nativas de geração de texto do Gemini                 |

<Note>
  Nenhum campo adicional precisa ser enviado na chamada. A cobertura está em [Recuperação de interrupção de LLM](#supported-models-llm); para modelos não listados na tabela, faça a validação da recuperação de interrupção com uma requisição de baixo custo antes da integração oficial, e a requisição de validação continua sendo cobrada normalmente. Se alguma das condições não for atendida, a requisição continua sendo executada normalmente e nenhuma tarefa `llm` é gerada após a desconexão do cliente.
</Note>

<h3 id="recovery-flow">
  Fluxo de execução após a interrupção
</h3>

```text theme={null}
1. O cliente faz uma requisição de LLM normalmente
2. O cliente se desconecta ou cancela antes de a resposta ser concluída
3. A AIHubMix continua processando a requisição, que continua sendo cobrada normalmente
4. A resposta final em JSON ou SSE é salva como uma tarefa do tipo llm
5. Use a API Key original para consultar a lista de tarefas e ler a resposta salva
```

Requisições de LLM concluídas normalmente e entregues com sucesso ao cliente não criam tarefas e não aparecem na lista de tarefas. As requisições interrompidas aparecem na lista depois que a resposta final termina de ser salva, portanto podem ficar temporariamente indisponíveis para consulta durante o processamento.

<h3 id="locate-interrupted-request">
  Localizar a requisição interrompida correspondente
</h3>

O cabeçalho de resposta do LLM retorna `X-Aihubmix-Request-Id`. Assim que receber os cabeçalhos de resposta, o cliente deve salvar esse valor; após uma interrupção, é possível usar esse ID de requisição para localizar a tarefa correspondente na lista de tarefas assíncronas do console da AIHubMix.

A API pública de tarefas ainda não permite filtrar por ID de requisição. Sem o ID de requisição salvo, a busca só pode ser feita por modelo e horário de criação, usando a mesma API Key da requisição original:

```bash theme={null}
# Consultar as tarefas de interrupção de LLM mais recentes
curl "https://aihubmix.com/ai/v1/tasks?object=llm&model={model}&order=desc&limit=20" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

# Depois de encontrar o task_id, consulte os detalhes e obtenha a resposta original
curl https://aihubmix.com/ai/v1/tasks/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"

curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

<Warning>
  Quando a mesma API Key envia várias requisições simultâneas para o mesmo modelo, apenas o modelo e o horário de criação não garantem a correspondência exata. Para uma recuperação confiável, salve o `X-Aihubmix-Request-Id` e faça a busca pelo console; se os cabeçalhos de resposta não tiverem sido obtidos, evite tratar a tarefa mais recente da lista diretamente como a requisição em questão.
</Warning>

<Warning>
  As tarefas de recuperação de interrupção de LLM ainda não enviam Webhook; consulte o resultado pela lista de tarefas. A interrupção do cliente não impede que a plataforma continue processando a requisição, e essa chamada continua sendo cobrada segundo as regras da interface de LLM original.
</Warning>

***

<h2 id="task-object">
  Objeto de tarefa e status
</h2>

Todas as tarefas usam uma estrutura de resposta unificada:

```json theme={null}
{
  "id": "task_01K0ABCDEF",
  "object": "video",
  "model": "wan2.6-t2v",
  "status": "completed",
  "output": [
    {
      "index": 0,
      "result_id": "result_01K0XYZ",
      "type": "file",
      "content_type": "video/mp4",
      "content_url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
    }
  ],
  "error": null,
  "created_at": 1784707200,
  "completed_at": 1784707320,
  "expires_at": 1784709120
}
```

| Campo          | Tipo         | Descrição                                                                        |
| -------------- | ------------ | -------------------------------------------------------------------------------- |
| `id`           | string       | ID da tarefa na plataforma, ou seja, o `task_id` usado nas requisições seguintes |
| `object`       | string       | Tipo da tarefa: `llm`, `image` ou `video`                                        |
| `model`        | string       | Modelo usado na criação da tarefa                                                |
| `status`       | string       | Status unificado da tarefa                                                       |
| `output`       | array        | Resultados disponíveis; array vazio quando a tarefa não produziu resultados      |
| `error`        | object/null  | Informações de falha, geralmente com `code` e `message`                          |
| `created_at`   | integer      | Horário de criação, em segundos Unix                                             |
| `completed_at` | integer/null | Horário em que a tarefa foi concluída, falhou ou foi cancelada, em segundos Unix |
| `expires_at`   | integer/null | Horário de expiração do primeiro resultado a expirar, em segundos Unix           |

Campos dos resultados em `output`:

| Campo          | Descrição                                                                                    |
| -------------- | -------------------------------------------------------------------------------------------- |
| `index`        | Posição do resultado na tarefa atual, a partir de 0                                          |
| `result_id`    | ID do resultado; usado para baixar um resultado específico em tarefas com múltiplos arquivos |
| `type`         | Tipo do resultado: `file` para arquivos e `response` para respostas de LLM                   |
| `content_type` | Tipo de arquivo do resultado (MIME), por exemplo `video/mp4` ou `application/json`           |
| `content_url`  | Endereço de download do resultado; o acesso exige a API Key usada na criação da tarefa       |
| `b64_json`     | Resultado codificado em Base64 que alguns modelos de imagem podem retornar diretamente       |
| `truncated`    | Indica se a resposta de LLM foi truncada por limite de tamanho                               |

<h3 id="task-status">
  Descrição dos status
</h3>

| Status        | Já finalizado | Descrição                                                    |
| ------------- | ------------- | ------------------------------------------------------------ |
| `pending`     | Não           | A plataforma recebeu a tarefa e aguarda o início da execução |
| `in_progress` | Não           | A tarefa está em execução                                    |
| `completed`   | Sim           | Tarefa concluída, o resultado pode ser obtido em `output`    |
| `failed`      | Sim           | A tarefa falhou; o motivo está em `error`                    |
| `cancelled`   | Sim           | A tarefa foi cancelada                                       |

Recomenda-se consultar a cada **15 segundos**, até o status mudar para `completed`, `failed` ou `cancelled`.

<Note>
  Tarefas com status `failed` ou `cancelled` também podem conter resultados parciais já gerados. Ao verificar se há resultados, além do status, confira também se `output` está vazio.
</Note>

***

<h2 id="query-tasks">
  Como consultar tarefas
</h2>

<h3 id="query-task-detail">
  Consultar os detalhes da tarefa
</h3>

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

Essa interface retorna as informações mais recentes da tarefa no momento da consulta. A operação de consulta não altera a tarefa; o status é atualizado automaticamente pela plataforma.

<h3 id="query-task-list">
  Consultar a lista de tarefas
</h3>

Quando a resposta de criação for perdida, ou quando for preciso revisar várias tarefas anteriores, o `task_id` pode ser recuperado pela interface de lista:

```bash theme={null}
curl "https://aihubmix.com/ai/v1/tasks?object=video&status=in_progress&limit=20&order=desc" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

| Parâmetro | Tipo    | Padrão | Descrição                                                  |
| --------- | ------- | ------ | ---------------------------------------------------------- |
| `object`  | string  | -      | Filtra por tipo: `llm`, `image`, `video`                   |
| `status`  | string  | -      | Filtra pelo status unificado da tarefa                     |
| `model`   | string  | -      | Filtra por nome exato do modelo                            |
| `after`   | string  | -      | Cursor de paginação; use o `next_after` da página anterior |
| `limit`   | integer | `20`   | Quantidade por página, no intervalo de 1 a 100             |
| `order`   | string  | `desc` | `asc` ou `desc`                                            |

Exemplo de resposta:

```json theme={null}
{
  "object": "list",
  "data": [
    {
      "id": "task_01K0ABCDEF",
      "object": "video",
      "model": "wan2.6-t2v",
      "status": "in_progress",
      "output": [],
      "error": null,
      "created_at": 1784707200,
      "completed_at": null,
      "expires_at": null
    }
  ],
  "has_more": true,
  "next_after": "task_01K0ABCDEF"
}
```

| Campo        | Descrição                                                                   |
| ------------ | --------------------------------------------------------------------------- |
| `object`     | Sempre `list`, indicando que esta é uma resposta de lista                   |
| `data`       | Array de tarefas da página atual                                            |
| `has_more`   | Indica se existe uma próxima página                                         |
| `next_after` | Cursor da próxima página; retornado apenas quando existe uma próxima página |

Para solicitar a próxima página:

```bash theme={null}
curl "https://aihubmix.com/ai/v1/tasks?limit=20&order=desc&after=task_01K0ABCDEF" \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

***

<h2 id="get-task-results">
  Como obter o resultado da tarefa
</h2>

<h3 id="single-artifact">
  Tarefas com um único arquivo
</h3>

Quando `output` tem apenas um arquivo, o acesso pode ser direto:

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.bin
```

Também é possível usar diretamente `output[0].content_url`. O `Content-Type` da resposta de download é igual a `output[0].content_type`.

<h3 id="multiple-artifacts">
  Tarefas com múltiplos arquivos
</h3>

Quando `output` contém vários arquivos, é obrigatório indicar o `result_id` correspondente:

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content/{result_id} \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  --output result.png
```

Se o `result_id` não for informado em uma tarefa com múltiplos arquivos, a interface retorna `400 result_id_required`.

<h3 id="llm-response-task">
  Tarefas de resposta de LLM
</h3>

Depois que as condições de [recuperação de interrupção de LLM](#llm-interruption-recovery) são atendidas e a resposta é salva, o `object` da tarefa é `llm` e o `type` do item de `output` é `response`. O tipo de conteúdo pode ser:

* `application/json`: resposta JSON comum
* `text/event-stream`: resposta em streaming SSE salva

```bash theme={null}
curl https://aihubmix.com/ai/v1/tasks/{task_id}/content \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY"
```

A marcação de truncamento fica em `output[0].truncated`, nos detalhes da tarefa. O valor `true` indica que a resposta salva foi truncada por limite de tamanho. `GET /ai/v1/tasks/{task_id}/content` retorna o conteúdo JSON ou SSE original, sem envolver o conteúdo em um campo `truncated`, portanto consulte primeiro os detalhes da tarefa e depois leia o conteúdo.

<Warning>
  Os resultados podem expirar e também pode haver limite no número de downloads. Salve os arquivos antes de `expires_at`. Após a expiração, é retornado `410 artifact_expired`; ao ultrapassar o limite de downloads, é retornado `429 too_many_downloads`.
</Warning>

***

<h2 id="webhooks">
  Como usar Webhook
</h2>

Atualmente é possível informar um Webhook por tarefa no momento da criação da tarefa assíncrona. Para que a AIHubMix notifique ativamente após a conclusão da tarefa, envie `webhook_url` e o opcional `webhook_events_filter` no corpo da requisição de imagem ou vídeo assíncrona:

```bash theme={null}
curl -X POST https://aihubmix.com/ai/v1/videos \
  -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "wan2.6-t2v",
    "prompt": "A tranquil Japanese garden at sunrise",
    "seconds": "5",
    "webhook_url": "https://example.com/webhooks/aihubmix",
    "webhook_events_filter": ["completed", "failed"]
  }'
```

O endereço de callback deve usar HTTPS e não pode apontar para o próprio host, para redes privadas ou para outros endereços restritos.

<h3 id="webhook-payload">
  Requisição de callback
</h3>

A AIHubMix envia uma requisição `POST` ao endereço de callback:

```json theme={null}
{
  "event_id": "evt_01K0ABCDEF",
  "event_type": "completed",
  "created_at": "2026-07-22T12:00:00Z",
  "data": {
    "task_id": "task_01K0ABCDEF",
    "status": "completed",
    "model": "wan2.6-t2v",
    "results": [
      {
        "url": "https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content"
      }
    ]
  }
}
```

| Campo                | Descrição                                                                        |
| -------------------- | -------------------------------------------------------------------------------- |
| `event_id`           | ID único deste evento de callback, usado para identificar notificações repetidas |
| `event_type`         | Status final da tarefa: `completed`, `failed` ou `cancelled`                     |
| `created_at`         | Horário de criação do evento de callback                                         |
| `data.task_id`       | ID da tarefa, que pode ser usado para consultar os detalhes                      |
| `data.status`        | Status atual da tarefa                                                           |
| `data.model`         | Modelo usado na criação da tarefa                                                |
| `data.results[].url` | Endereço de download dos resultados já gerados                                   |
| `data.error.code`    | Código de erro da falha; pode aparecer apenas em eventos de falha                |
| `data.error.message` | Motivo da falha; pode aparecer apenas em eventos de falha                        |

As URLs em `results` ainda exigem a API Key usada na criação da tarefa para serem acessadas.

<h3 id="webhook-retry">
  Novas tentativas e deduplicação
</h3>

A plataforma tenta entregar o callback pelo menos uma vez, portanto o mesmo evento pode ser enviado mais de uma vez:

* HTTP `2xx` indica recebimento bem-sucedido.
* HTTP `5xx`, erros de rede ou timeouts acionam novas tentativas.
* HTTP `3xx` e `4xx` não geram novas tentativas.
* No máximo 6 entregas, com intervalos de 1, 4, 16, 64 e 256 segundos.

O receptor deve armazenar o `event_id`. Ao receber novamente o mesmo `event_id`, pule a lógica de negócio e retorne `2xx` diretamente.

<Warning>
  O Webhook por tarefa atual não oferece credenciais de assinatura independentes configuráveis. Ao receber a notificação, use a API Key da criação da tarefa para chamar `GET /ai/v1/tasks/{task_id}` e considere o resultado da consulta como definitivo.
</Warning>

***

<h2 id="error-codes">
  Respostas de erro e códigos de erro
</h2>

As respostas de erro usam uma estrutura unificada:

```json theme={null}
{
  "error": {
    "message": "Task not found.",
    "type": "invalid_request_error",
    "code": "task_not_found",
    "tid": "req_01K0..."
  }
}
```

| Campo           | Descrição                                                               |
| --------------- | ----------------------------------------------------------------------- |
| `error.message` | Motivo do erro                                                          |
| `error.type`    | Tipo do erro                                                            |
| `error.code`    | Código de erro identificável por programas                              |
| `error.tid`     | ID de rastreamento da requisição; informe ao contatar o suporte técnico |

| Código de status HTTP | Código de erro                  | Descrição                                                                                      |
| --------------------- | ------------------------------- | ---------------------------------------------------------------------------------------------- |
| 400                   | `invalid_request`               | Tipo ou valor de parâmetro incorreto                                                           |
| 400                   | `result_id_required`            | Tarefa com múltiplos arquivos sem `result_id` informado                                        |
| 400                   | `webhook_invalid`               | URL de Webhook inválida                                                                        |
| 400                   | `webhook_events_filter_invalid` | Lista de eventos de Webhook inválida                                                           |
| 401                   | `authentication_failed`         | API Key ausente ou inválida                                                                    |
| 403                   | `async_not_enabled`             | A conta não tem o recurso de tarefas assíncronas ativado                                       |
| 404                   | `task_not_found`                | A tarefa não existe ou não pertence à API Key atual                                            |
| 404                   | `result_not_found`              | O resultado não existe ou não está disponível no momento                                       |
| 410                   | `artifact_expired`              | O resultado expirou                                                                            |
| 429                   | `too_many_downloads`            | Limite de downloads do resultado ultrapassado                                                  |
| 503                   | `async_unavailable`             | O serviço de imagens assíncronas está temporariamente indisponível, tente novamente mais tarde |

***

<h2 id="full-example">
  Exemplo completo
</h2>

Fluxo completo para criar uma tarefa de vídeo, fazer polling do status e baixar todos os resultados:

<CodeGroup>
  ```python Python theme={null}
  import base64
  import os
  import time

  import requests

  BASE_URL = "https://aihubmix.com"
  API_KEY = os.environ["AIHUBMIX_API_KEY"]
  HEADERS = {
      "Authorization": f"Bearer {API_KEY}",
      "Content-Type": "application/json",
  }

  # 1. Criar a tarefa
  response = requests.post(
      f"{BASE_URL}/ai/v1/videos",
      headers=HEADERS,
      json={
          "model": "wan2.6-t2v",
          "prompt": "A cat playing jazz on a piano",
          "seconds": "5",
          "size": "1280x720",
      },
      timeout=60,
  )
  response.raise_for_status()
  task = response.json()
  task_id = task["id"]

  # 2. Fazer polling, até a tarefa ser concluída, falhar ou ser cancelada
  while task["status"] not in {"completed", "failed", "cancelled"}:
      time.sleep(15)
      response = requests.get(
          f"{BASE_URL}/ai/v1/tasks/{task_id}",
          headers=HEADERS,
          timeout=30,
      )
      response.raise_for_status()
      task = response.json()
      print("status:", task["status"])

  # 3. Obter o resultado
  if task["output"]:
      for index, item in enumerate(task["output"]):
          if encoded := item.get("b64_json"):
              with open(f"result-{index}.bin", "wb") as file:
                  file.write(base64.b64decode(encoded))
              continue
          result = requests.get(
              item["content_url"],
              headers=HEADERS,
              timeout=120,
          )
          result.raise_for_status()
          with open(f"result-{index}.bin", "wb") as file:
              file.write(result.content)
  elif task["status"] == "failed":
      raise RuntimeError(task.get("error"))
  ```

  ```typescript TypeScript theme={null}
  import { writeFile } from "node:fs/promises";

  const BASE_URL = "https://aihubmix.com";
  const HEADERS = {
    Authorization: `Bearer ${process.env.AIHUBMIX_API_KEY}`,
    "Content-Type": "application/json",
  };

  // 1. Criar a tarefa
  const created = await fetch(`${BASE_URL}/ai/v1/videos`, {
    method: "POST",
    headers: HEADERS,
    body: JSON.stringify({
      model: "wan2.6-t2v",
      prompt: "A cat playing jazz on a piano",
      seconds: "5",
      size: "1280x720",
    }),
  });
  let task = await created.json();

  // 2. Fazer polling, até a tarefa ser concluída, falhar ou ser cancelada
  const finished = new Set(["completed", "failed", "cancelled"]);
  while (!finished.has(task.status)) {
    await new Promise((resolve) => setTimeout(resolve, 15_000));
    const polled = await fetch(`${BASE_URL}/ai/v1/tasks/${task.id}`, {
      headers: HEADERS,
    });
    task = await polled.json();
    console.log("status:", task.status);
  }

  // 3. Obter o resultado
  if (task.output?.length) {
    for (const [index, item] of task.output.entries()) {
      if (item.b64_json) {
        await writeFile(`result-${index}.bin`, Buffer.from(item.b64_json, "base64"));
        continue;
      }
      const result = await fetch(item.content_url, { headers: HEADERS });
      await writeFile(`result-${index}.bin`, Buffer.from(await result.arrayBuffer()));
    }
  } else if (task.status === "failed") {
    throw new Error(JSON.stringify(task.error));
  }
  ```

  ```shell curl theme={null}
  # 1. Criar a tarefa e anotar o id retornado
  curl -X POST https://aihubmix.com/ai/v1/videos \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "model": "wan2.6-t2v",
      "prompt": "A cat playing jazz on a piano",
      "seconds": "5",
      "size": "1280x720"
    }'

  # 2. Consultar o status a cada 15 segundos
  curl https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY"

  # 3. Baixar o resultado depois que o status mudar para completed
  curl https://aihubmix.com/ai/v1/tasks/task_01K0ABCDEF/content \
    -H "Authorization: Bearer $AIHUBMIX_API_KEY" \
    --output result.mp4
  ```
</CodeGroup>

***

<h2 id="faq">
  Perguntas frequentes (FAQ)
</h2>

**Com que frequência devo consultar o status da tarefa?**

Recomenda-se consultar a cada 15 segundos, evitando polling de alta frequência. Ao usar Webhook, mantenha também uma consulta de baixa frequência como alternativa.

**Como recuperar a tarefa depois de perder a resposta de criação?**

Use a mesma API Key da criação da tarefa para chamar `GET /ai/v1/tasks`, restringindo a busca por `object`, `model` e `status`.

**Por que outra API Key da mesma conta não encontra a tarefa?**

As tarefas são isoladas por API Key. As requisições de consulta, download e listagem devem usar a mesma Key com que a tarefa foi criada.

**Por que a tarefa falhou, mas `output` não é um array vazio?**

Alguns modelos podem já ter gerado resultados entregáveis antes da falha ou do cancelamento geral. Sempre que houver `content_url` ou `b64_json` em `output`, o resultado pode ser obtido pelo método correspondente.

**O que fazer se o Webhook não chegar?**

Verifique se o endereço de callback é publicamente acessível, se usa HTTPS e se retorna `2xx` em até 10 segundos. Com ou sem Webhook, o status final sempre pode ser consultado por `GET /ai/v1/tasks/{task_id}`.

**A recuperação de interrupção de LLM exige mudanças no código atual?**

Não. A forma de fazer a requisição, o comportamento de streaming e o formato da resposta permanecem iguais. Recomenda-se salvar o cabeçalho de resposta `X-Aihubmix-Request-Id` para localizar a tarefa correspondente com precisão no console após uma interrupção.

***

Data de atualização: 2026-07-28
