# Quickstart: single slide

This quickstart starts a single-slide generation job, polls until it finishes, and reads the download URL from the completed status response.

## Set environment variables

Set `PERCEPTIS_API_BASE_URL` to the API origin only. Do not include `/api`; the examples append `/api/v1/...`.

```bash
export PERCEPTIS_API_BASE_URL="https://app.perceptis.ai"
export PERCEPTIS_API_KEY="sk-live-per-..."
```

Install the Python HTTP client used by this quickstart:

```bash
python3 -m pip install requests
```

## Start generation

Use this as `quickstart_single_slide.py`:

```python
import os
import time
import uuid

import requests


base_url = os.environ["PERCEPTIS_API_BASE_URL"].rstrip("/")
api_key = os.environ["PERCEPTIS_API_KEY"]

response = requests.post(
    f"{base_url}/api/v1/generate",
    headers={
        "Authorization": f"Bearer {api_key}",
        "Content-Type": "application/json",
        "Idempotency-Key": str(uuid.uuid4()),
    },
    json={
        "prompt": "One slide summarizing Q3 revenue drivers",
        "output_type": "single_slide",
    },
    timeout=60,
)
response.raise_for_status()

job_id = response.json()["job_id"]
print(f"Job ID: {job_id}")


def poll_status(job_id, timeout_sec=300):
    deadline = time.monotonic() + timeout_sec

    while time.monotonic() < deadline:
        status_response = requests.get(
            f"{base_url}/api/v1/status/{job_id}",
            headers={"Authorization": f"Bearer {api_key}"},
            timeout=60,
        )
        status_response.raise_for_status()

        body = status_response.json()
        if body["status"] in {"completed", "failed"}:
            return body

        time.sleep(3)

    raise TimeoutError(f"Job did not finish within {timeout_sec} seconds")


final = poll_status(job_id)

if final["status"] == "failed":
    raise RuntimeError(final.get("error") or "Generation failed")

for download in final.get("downloads") or []:
    print(download["url"])
```

The response includes a `job_id`:

```json
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "pending",
  "output_type": "single_slide",
  "downloads": null,
  "error": null
}
```

## Poll status

Poll `GET /api/v1/status/{job_id}` with the same API key that created the job. The example above checks every 3 seconds and stops after 5 minutes. For retries, backoff, and `Retry-After` handling, see the [full client script example](/perceptis-api-v1/examples.md).

## Downloads

When `status` is `completed`, each item in `downloads` includes a short-lived `url` for a `.pptx` file. If a URL expires, poll status again for fresh links while the generated files remain available. Use the same API key that created the job.

Example completed response:

```json
{
  "job_id": "550e8400-e29b-41d4-a716-446655440000",
  "status": "completed",
  "output_type": "single_slide",
  "downloads": [
    {
      "url": "https://app.perceptis.ai/downloads/550e8400-e29b-41d4-a716-446655440000.pptx?expires=3600&signature=...",
      "format": "pptx",
      "variant": 1
    }
  ],
  "error": null
}
```

## Optional: reference images

For single-slide generation, include `reference_images` when you want the prompt to use a visual reference:

```json
"reference_images": [
  {
    "data": "<base64>",
    "mime_type": "image/png"
  }
]
```

You can also include `variant_count`, `template_name`, `use_web_search`, or `use_knowledge_base` when needed. See the [`POST /api/v1/generate` reference](/api-reference/post-generate.md) for the full request body.


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://docs.perceptis.ai/perceptis-api-v1/quickstart-single-slide.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
