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

# Asynchronous Tasks

All MuleRouter asynchronous tasks follow the same usage pattern:

Create a task via a `POST` request, then use `GET` requests to retrieve its latest status and result.

## Task response structure

All asynchronous task responses follow the structure below:

### Task Information Object

<ResponseField name="task_info" type="object" required>
  Task Information object

  <Expandable title="properties" defaultOpen>
    <ResponseField name="task_info.id" type="string" required>
      Task ID, `UUID` format
    </ResponseField>

    <ResponseField name="task_info.status" type="string" required>
      Task Status. Enum: `queued`, `running`, `succeeded`, `failed`
    </ResponseField>

    <ResponseField name="task_info.created_at" type="string" required>
      Task Created Timestamp, `ISO 8601` format
    </ResponseField>

    <ResponseField name="task_info.updated_at" type="string" required>
      Task Updated Timestamp, `ISO 8601` format
    </ResponseField>
  </Expandable>
</ResponseField>

### Task Result

The corresponding JSON structure is as follows:

```json theme={null}
{
  "task_info": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "queued",
    "created_at": "2025-09-16T10:00:00Z",
    "updated_at": "2025-09-16T10:00:00Z"
  }
}
```

When querying, use the task ID to fetch the execution status and result.

## Create a task

MuleRouter integrates multiple model vendors. Some requests are synchronous or streaming, while others involve longer inference cycles. To improve the developer experience, we expose these as asynchronous tasks.

Create an asynchronous task via `POST` `/vendors/dummy/v1/videos/generation`.

You will receive a response similar to the following:

```json theme={null}
{
  "task_info": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "queued",
    "created_at": "2025-09-16T10:00:00Z",
    "updated_at": "2025-09-16T10:00:00Z"
  },
  ...
}
```

## Retrieve task status and result

In the above example, the task ID is `123e4567-e89b-12d3-a456-426614174000`.

To retrieve the latest status and result for the task ID.

Use `GET` `/vendors/dummy/v1/videos/generation/123e4567-e89b-12d3-a456-426614174000`.

For example, when the task status is `succeeded`, you may receive a response like the following:

```json theme={null}
{
  "task_info": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "succeeded",
    "created_at": "2025-09-16T10:00:00Z",
    "updated_at": "2025-09-16T10:00:00Z"
  },
  "videos": [
    "https://example.com/video-749337402830284.mp4"
  ]
}
```

The exact result payload varies by endpoint, refer to the model documentation. The task info response envelope remains consistent.

## Failed tasks

If a task finishes with `status: "failed"`, the response includes an `error` object describing what went wrong. The HTTP status of the `GET` itself is still `200` — the lookup succeeded, the task it describes did not.

```json theme={null}
{
  "task_info": {
    "id": "123e4567-e89b-12d3-a456-426614174000",
    "status": "failed",
    "created_at": "2025-09-16T10:00:00Z",
    "updated_at": "2025-09-16T10:02:13Z"
  },
  "error": {
    "title": "External service execution failed",
    "error_code": 3005,
    "detail": "Kling task failed: video generation failed due to prompt violation"
  }
}
```

The `error_code` is the authoritative signal for what went wrong. The most common codes for failed async tasks are:

* `3001` – `3005`: the upstream model provider could not complete the task.
* `4002`, `4008`: a MuleRouter-side error occurred while running the task.

See [Error Codes](/docs/get-started/error-codes) for the full list and the meaning of each code.

## Task lifecycle

| Status      | Meaning                                                                        |
| :---------- | :----------------------------------------------------------------------------- |
| `queued`    | Task accepted and waiting to be picked up by a worker.                         |
| `running`   | A worker has claimed the task and is executing it.                             |
| `succeeded` | Task finished successfully. The result payload (endpoint-specific) is present. |
| `failed`    | Task ended with an error. An `error` object is present.                        |

A task only ever leaves `queued` / `running` once — once it is `succeeded` or `failed`, it stays in that state.

## Common errors

| Situation                                     | Where it surfaces                          | Code           |
| :-------------------------------------------- | :----------------------------------------- | :------------- |
| `POST` body fails validation                  | `POST` returns `400` synchronously         | `2001`–`2004`  |
| Required file too large or wrong format       | `POST` returns `400` synchronously         | `2101`–`2103`  |
| `task_id` in `GET` does not exist             | `GET` returns `404` synchronously          | `2005`         |
| Caller has no balance / over quota            | `POST` returns `402` / `429` synchronously | `1003`–`1005`  |
| Upstream provider could not complete the task | `GET` returns `200` with `status: failed`  | `3001`–`3005`  |
| Server-side error while running the task      | `GET` returns `200` with `status: failed`  | `4002`, `4008` |
