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

# Async Tasks

> Create, poll, list, and receive callbacks for EggAPI generation tasks

The current public nano-banana model returns async tasks. The API creates the task immediately, workers process it in the background, and you read the result later.

## Lifecycle

```mermaid theme={null}
sequenceDiagram
  participant App
  participant API as EggAPI API
  participant Worker
  participant Provider
  App->>API: POST /v1/generate
  API-->>App: 202 Accepted with task id
  Worker->>Provider: Start generation
  loop Poll upstream
    Worker->>Provider: Check status
  end
  Worker->>API: Persist output, usage, cost
  App->>API: GET /v1/tasks/{id}
  API-->>App: completed or failed task
```

Task statuses:

| Status       | Meaning                                       |
| ------------ | --------------------------------------------- |
| `pending`    | Task was created and queued.                  |
| `processing` | Worker started provider execution or polling. |
| `completed`  | Output, cost, and usage have been recorded.   |
| `failed`     | The task ended with an error message.         |

## Create a Task

```bash theme={null}
curl -X POST https://api.eggapi.ai/v1/generate \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "nanobanana",
    "prompt": "A dashboard hero image with glass UI panels",
    "aspect_ratio": "16:9",
    "num_outputs": 1
  }'
```

Response:

```json theme={null}
{
  "data": {
    "id": "gen_abc123def456",
    "status": "pending",
    "model": "nanobanana",
    "type": "image_generate",
    "cost": "$0.00",
    "created_at": "2026-05-08T10:30:00Z"
  },
  "error": null
}
```

## Poll a Task

```bash theme={null}
curl https://api.eggapi.ai/v1/tasks/gen_abc123def456 \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Completed image task:

```json theme={null}
{
  "data": {
    "id": "gen_abc123def456",
    "status": "completed",
    "model": "nanobanana",
    "type": "image_generate",
    "output": {
      "url": "https://file.eggapi.ai/images/gen_abc123def456/0.png",
      "urls": ["https://file.eggapi.ai/images/gen_abc123def456/0.png"]
    },
    "cost": "$0.0100",
    "created_at": "2026-05-08T10:30:00Z",
    "started_at": "2026-05-08T10:30:01Z",
    "completed_at": "2026-05-08T10:30:10Z"
  },
  "error": null
}
```

## List Tasks

```bash theme={null}
curl "https://api.eggapi.ai/v1/tasks?page=1&per_page=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
```

Pagination fields are returned under `data.pagination`.

## Webhooks

Pass `webhook_url` when creating a task:

```json theme={null}
{
  "model": "nanobanana",
  "prompt": "A studio portrait with soft lighting",
  "webhook_url": "https://example.com/eggapi/webhook"
}
```

EggAPI posts JSON to your URL after completion or failure. It sends these headers:

| Header               | Description                                                                       |
| -------------------- | --------------------------------------------------------------------------------- |
| `X-EggAPI-Timestamp` | Unix timestamp used in the signature payload.                                     |
| `X-EggAPI-Signature` | `sha256=` plus HMAC-SHA256 of `{timestamp}.{raw_body}` using your webhook secret. |

Completed payload:

```json theme={null}
{
  "event": "task.completed",
  "task_id": "gen_abc123def456",
  "status": "completed",
  "model": "nanobanana",
  "output": {
    "urls": ["https://file.eggapi.ai/images/gen_abc123def456/0.png"]
  },
  "cost": "0.010000",
  "timestamp": 1778217000
}
```

Failed payload:

```json theme={null}
{
  "event": "task.failed",
  "task_id": "gen_abc123def456",
  "status": "failed",
  "model": "nanobanana",
  "error": "generation failed: upstream provider unavailable",
  "cost": "0.000000",
  "timestamp": 1778217000
}
```

Webhook delivery uses a 30 second HTTP timeout and retries up to 5 attempts with exponential backoff.

## Polling Helper

```javascript theme={null}
async function waitForTask(taskId, apiKey, timeoutMs = 300000) {
  const start = Date.now();

  while (Date.now() - start < timeoutMs) {
    const response = await fetch(`https://api.eggapi.ai/v1/tasks/${taskId}`, {
      headers: { "Authorization": `Bearer ${apiKey}` }
    });
    const { data, error } = await response.json();

    if (error) throw new Error(error.message);
    if (data.status === "completed") return data;
    if (data.status === "failed") throw new Error(data.error || "Task failed");

    await new Promise((resolve) => setTimeout(resolve, 3000));
  }

  throw new Error("Task timed out");
}
```
