> ## 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.

# Async tasks

> Submit long-running jobs without blocking, then poll on your own schedule

Most MuleRouter generation endpoints are asynchronous under the hood. By
default `mulerouter run` hides this from you — it submits the task and polls
until done. For longer jobs, queues, and CI, you want to decouple submission
from waiting.

## When to use `--no-wait`

* The task may take longer than your default `--max-wait` (15 minutes).
* You are inside a short-lived CI step and want to hand off polling to another
  job.
* You want to **fan out** dozens of tasks in parallel and wait on them
  afterwards.
* You are inside an LLM agent loop and prefer cheap snapshot calls between
  reasoning steps.

## The full flow

```bash theme={null}
# Step 1 — submit
SUBMIT=$(mulerouter run alibaba/wan2.6-t2v \
  --prompt "A long cinematic shot over a glacier" \
  --duration 15 \
  --no-wait --json)

TASK_ID=$(echo "$SUBMIT" | jq -r '.task_id')
API_PATH=$(echo "$SUBMIT" | jq -r '.api_path')

echo "queued $TASK_ID at $API_PATH"

# Step 2 — block until done, possibly minutes or hours later
mulerouter status "$API_PATH" "$TASK_ID" --wait --json > result.json

# Step 3 — download the assets
jq -r '.results[]' result.json | while read -r url; do
  curl -sSLO "$url"
done
```

`--no-wait` always prints the `api_path` so you never have to look it up. The
text output also includes copy-pasteable `status` commands:

```
Task ID:  9d2b8c1a-...
API Path: /vendors/alibaba/v1/wan2.6-t2v/generation
Status:   created (not waiting for completion)

Check status: mulerouter status /vendors/alibaba/v1/wan2.6-t2v/generation 9d2b8c1a-...
Wait:         mulerouter status /vendors/alibaba/v1/wan2.6-t2v/generation 9d2b8c1a-... --wait
```

## Polling cadence

Both `run` (without `--no-wait`) and `status --wait` use the same poller:

| Flag              | Default   | What it controls              |
| ----------------- | --------- | ----------------------------- |
| `--poll-interval` | `20` (s)  | Time between `GET` requests   |
| `--max-wait`      | `900` (s) | Total budget before giving up |

For fast endpoints (text-to-image), drop the interval to `--poll-interval 5`
for snappier feedback. For long video generations, raise `--max-wait 1800`
(30 min) or `3600` (1 hour).

If `--max-wait` elapses, the CLI errors out — but the task itself keeps
running on the server. You can resume polling later with `status --wait` or
just check the snapshot.

## Fan-out / fan-in

A simple batch script that submits many prompts in parallel and waits on them:

```bash theme={null}
#!/usr/bin/env bash
set -euo pipefail

prompts=(
  "A neon-lit Tokyo street at midnight"
  "A misty pine forest at dawn"
  "A sandstorm rolling across desert dunes"
)

# Fan out
> tasks.jsonl
for p in "${prompts[@]}"; do
  mulerouter run alibaba/wan2.6-t2v \
    --prompt "$p" --duration 5 --no-wait --json --quiet \
    | jq -c '{task_id, api_path, prompt: "'"$p"'"}' >> tasks.jsonl
done

# Fan in
while read -r line; do
  tid=$(jq -r .task_id <<<"$line")
  path=$(jq -r .api_path <<<"$line")
  mulerouter status "$path" "$tid" --wait --quiet --json > "result-$tid.json"
done < tasks.jsonl
```

## Status semantics

| Status                   | Terminal? | Meaning                          |
| ------------------------ | --------- | -------------------------------- |
| `pending`, `queued`      | No        | Accepted, waiting for a worker   |
| `running`, `processing`  | No        | A worker is generating the asset |
| `succeeded`, `completed` | **Yes**   | Result URLs are available        |
| `failed`                 | **Yes**   | The `error` field explains why   |

Snapshot calls (`status` without `--wait`) only return non-zero on the explicit
`failed` state; other statuses simply indicate "not done yet."

`status --wait` returns non-zero on any terminal failure.

## Tips

* Persist the `api_path` along with the task ID — the task ID alone is not
  enough to resume polling.
* Add `--quiet` to suppress the per-poll stderr lines when piping output
  through tools.
* Combine `--no-wait` with a queue (Redis, SQS, GitHub Actions matrix) for
  truly distributed generation pipelines.

## See also

* [`mulerouter run`](/docs/cli/commands/run)
* [`mulerouter status`](/docs/cli/commands/status)
* [Scripting with JSON output](/docs/cli/workflows/json-output)
