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

# Generate asynchronously

> Queue a Cloud generation task, monitor its status, and handle completion or failure reliably.

Asynchronous generation returns a task immediately and completes the presentation outside the request. Use it for production integrations, longer presentations, or any workflow that should not keep one HTTP connection open during generation.

## Task lifecycle

An asynchronous task has one of three schema-defined statuses:

| Status      | Meaning                             | Application action                             |
| ----------- | ----------------------------------- | ---------------------------------------------- |
| `pending`   | The task is queued or still running | Continue waiting with bounded backoff          |
| `completed` | Generation finished successfully    | Read the presentation details from `data`      |
| `error`     | Generation failed                   | Stop polling and inspect `error` and `message` |

## 1. Submit the generation request

Send the same body accepted by synchronous generation to `POST /presentation/generate/async`:

```bash theme={null}
curl --request POST \
  --url https://api.presenton.ai/api/v3/presentation/generate/async \
  --header "Authorization: Bearer YOUR_API_KEY" \
  --header "Content-Type: application/json" \
  --data '{
    "content": "Create an eight-slide executive briefing about the rollout of a new customer analytics platform",
    "n_slides": 8,
    "language": "English",
    "tone": "professional",
    "standard_template": "neo-modern",
    "export_as": "pptx",
    "trigger_webhook": false
  }'
```

The initial response contains a task identifier:

```json theme={null}
{
  "id": "task-9a827c13f4",
  "status": "pending",
  "message": "Presentation generation task created",
  "data": null,
  "error": null,
  "created_at": "2026-07-17T08:00:00Z",
  "updated_at": "2026-07-17T08:00:00Z"
}
```

Persist `id` before returning control to your caller. Your application needs it to resume monitoring after a restart or failed handoff.

## 2. Check the task status

Request `GET /async-task/status/{id}` with the same API key:

```bash theme={null}
curl --request GET \
  --url https://api.presenton.ai/api/v3/async-task/status/task-9a827c13f4 \
  --header "Authorization: Bearer YOUR_API_KEY"
```

When the task completes, `data` contains the generated presentation information:

```json theme={null}
{
  "id": "task-9a827c13f4",
  "status": "completed",
  "message": "Presentation generated successfully",
  "data": {
    "presentation_id": "8f29a2e7-4f26-48d2-9d1d-9b0716909a6d",
    "path": "https://example.com/generated-presentation.pptx",
    "edit_path": "https://presenton.ai/presentation?id=8f29a2e7-4f26-48d2-9d1d-9b0716909a6d",
    "credits_consumed": 8
  },
  "error": null,
  "created_at": "2026-07-17T08:00:00Z",
  "updated_at": "2026-07-17T08:01:30Z"
}
```

## 3. Poll with a deadline

This Python example uses a capped delay and a total timeout. The API key is read from the environment instead of being placed in source code.

```python theme={null}
import os
import random
import time

import requests

BASE_URL = "https://api.presenton.ai/api/v3"
API_KEY = os.environ["PRESENTON_API_KEY"]
HEADERS = {"Authorization": f"Bearer {API_KEY}"}


def wait_for_task(task_id: str, timeout_seconds: int = 600) -> dict:
    deadline = time.monotonic() + timeout_seconds
    delay = 2.0

    while time.monotonic() < deadline:
        response = requests.get(
            f"{BASE_URL}/async-task/status/{task_id}",
            headers=HEADERS,
            timeout=30,
        )
        response.raise_for_status()
        task = response.json()

        if task["status"] == "completed":
            return task["data"]

        if task["status"] == "error":
            raise RuntimeError(task.get("error") or task.get("message"))

        time.sleep(delay + random.uniform(0, 0.5))
        delay = min(delay * 1.5, 15.0)

    raise TimeoutError(f"Task {task_id} did not finish before the deadline")
```

## Make polling reliable

* Use one poller per task. Multiple workers polling the same task waste capacity and complicate handoffs.
* Persist the task identifier, latest status, and timestamps in your application database.
* Apply a total deadline even when individual HTTP requests have their own timeouts.
* Add small random jitter so many tasks do not poll at exactly the same moment.
* Stop immediately on `completed` or `error`; these are terminal states.
* Preserve sanitized failure data for diagnostics, but never log the API key.
* Decide what your product should do when its own timeout expires: continue in a background worker, notify the user, or allow a manual status refresh.

## Polling or webhooks?

Polling is simple and works without a public callback endpoint. Webhooks reduce repeated status requests and work well when your application already exposes a secure HTTPS receiver.

To receive generation events, subscribe to a webhook and set `trigger_webhook` to `true` in the generation request. See [Receive generation webhooks](/cloud/guides/webhooks).

<Note>
  A successfully accepted task can still finish with `error`. Do not treat the initial `200` response as proof that the presentation will complete.
</Note>

<Card title="Synchronous generation" icon="presentation-screen" href="/cloud/guides/generate-a-presentation">
  Review the request controls and the completed presentation response.
</Card>
