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

# Async Requests

> Get a request ID right away & fetch the result when it's ready

Send `"async": true` with a generation request to get an answer right away instead of waiting for the result. Poll the request's `status_url` until its status is `COMPLETED`, then fetch the result from its `response_url`.

Use async for long generations, or when your client can't hold a connection open for minutes, such as behind a proxy or a serverless function with a short timeout. Without `async`, the request waits & returns the result in the same response.

These endpoints accept `async`:

* [Create from text](https://docs.pikzels.com/thumbnails/create-from-text.md)
* [Create from image](https://docs.pikzels.com/thumbnails/create-from-image.md)
* [Edit thumbnail](https://docs.pikzels.com/thumbnails/edit-thumbnail.md)
* [Upscale thumbnail](https://docs.pikzels.com/thumbnails/upscale-thumbnail.md)
* [Score thumbnail](https://docs.pikzels.com/thumbnails/score-thumbnail.md)
* [Generate titles](https://docs.pikzels.com/titles/generate-titles.md)

## Send the Request

```bash cURL theme={"theme":"css-variables"}
curl -X POST https://api.pikzels.com/v2/thumbnail/text \
  -H "X-Api-Key: pkz_example_a1b2c3d4e5f6" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "I bought my first island",
    "model": "pkz_4_5",
    "format": "16:9",
    "async": true
  }'
```

```json Response (202) theme={"theme":"css-variables"}
{
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "status": "IN_QUEUE",
  "status_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234/status",
  "response_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

The request is checked & charged before this response, the same as without `async`. Errors at this point, such as `VALIDATION_ERROR`, `INSUFFICIENT_CREDITS` or `INVALID_IMAGE`, come back on this request with their usual HTTP status, & any charge for them is refunded. The `request_id` is also sent as the `X-Request-Id` header.

## Poll the Status

Call `GET` on the `status_url` every few seconds until `status` is `COMPLETED`. See [Get request status](https://docs.pikzels.com/requests/get-request-status.md).

| `status` | HTTP | Meaning |
| - | - | - |
| `IN_QUEUE` | `202` | Accepted & waiting to start. Poll again. |
| `IN_PROGRESS` | `202` | Generating. Poll again. |
| `COMPLETED` | `200` | Done. Fetch the result from `response_url`. |

```json IN_QUEUE (202) theme={"theme":"css-variables"}
{
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "status": "IN_QUEUE",
  "status_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234/status",
  "response_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

```json IN_PROGRESS (202) theme={"theme":"css-variables"}
{
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "status": "IN_PROGRESS",
  "status_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234/status",
  "response_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

```json COMPLETED (200) theme={"theme":"css-variables"}
{
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "status": "COMPLETED",
  "status_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234/status",
  "response_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

A failed request is `COMPLETED` too, with an `error`. Its charge is refunded.

```json COMPLETED with error (200) theme={"theme":"css-variables"}
{
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "status": "COMPLETED",
  "status_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234/status",
  "response_url": "https://api.pikzels.com/v2/requests/18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234",
  "error": {
    "code": "GENERATION_FAILED",
    "message": "Something went wrong. Please try again."
  }
}
```

Polling doesn't count against your concurrency limit.

## Fetch the Result

Once the status is `COMPLETED`, call `GET` on the `response_url`. See [Get request result](https://docs.pikzels.com/requests/get-request-result.md). The result is exactly what the request returns without `async`: the same body with the same HTTP status.

```json Success (200) theme={"theme":"css-variables"}
{
  "output": "https://cdn.pikzels.com/example.png",
  "model": "pkz_4_5",
  "prompt_compacted": false,
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

A failed request returns the standard [error body](https://docs.pikzels.com/errors.md) with the HTTP status it failed with, such as `400` for `CONTENT_POLICY`, `500` for `GENERATION_FAILED` or `504` for `GENERATION_TIMEOUT`. `error.code` is the code the request would have returned without `async`, & the charge is refunded.

```json Failure (500) theme={"theme":"css-variables"}
{
  "error": {
    "code": "GENERATION_FAILED",
    "message": "Something went wrong. Please try again."
  },
  "request_id": "18b2ad5e-2a9e-4d3f-b9a8-9f2a1e0b1234"
}
```

Fetching the result before the status is `COMPLETED` returns `400` with `REQUEST_IN_PROGRESS`. The `request_id` in this error belongs to the `GET` call itself, not to the request you're fetching.

```json Too early (400) theme={"theme":"css-variables"}
{
  "error": {
    "code": "REQUEST_IN_PROGRESS",
    "message": "This request is still in progress. Check its status and try again once it is completed."
  },
  "request_id": "7b9e2f6d-2b5f-4d79-8d6c-4a9c6e2b7890"
}
```

A request that hasn't finished an hour after you sent it fails with `GENERATION_TIMEOUT` & is refunded.

## Full Example

```python Python theme={"theme":"css-variables"}
import time
import requests

HEADERS = {"X-Api-Key": "pkz_example_a1b2c3d4e5f6"}

def wait_for_result(submitted):
    while True:
        status = requests.get(submitted["status_url"], headers=HEADERS)
        status.raise_for_status()
        if status.json()["status"] == "COMPLETED":
            break
        time.sleep(3)
    # A failed request returns its error body with its error status, as without async
    return requests.get(submitted["response_url"], headers=HEADERS)

response = requests.post(
    "https://api.pikzels.com/v2/thumbnail/text",
    headers=HEADERS,
    json={"prompt": "I bought my first island", "model": "pkz_4_5", "format": "16:9", "async": True},
)
response.raise_for_status()
result = wait_for_result(response.json())
print(result.status_code, result.json())
```

```javascript JavaScript theme={"theme":"css-variables"}
const headers = { "X-Api-Key": "pkz_example_a1b2c3d4e5f6" };

async function waitForResult(submitted) {
  while (true) {
    const status = await fetch(submitted.status_url, { headers });
    if (!status.ok) throw new Error(`HTTP ${status.status}`);
    if ((await status.json()).status === "COMPLETED") break;
    await new Promise((resolve) => setTimeout(resolve, 3000));
  }
  // A failed request returns its error body with its error status, as without async
  return fetch(submitted.response_url, { headers });
}

const response = await fetch("https://api.pikzels.com/v2/thumbnail/text", {
  method: "POST",
  headers: { ...headers, "Content-Type": "application/json" },
  body: JSON.stringify({ prompt: "I bought my first island", model: "pkz_4_5", format: "16:9", async: true }),
});
if (!response.ok) throw new Error(`HTTP ${response.status}`);
const result = await waitForResult(await response.json());
console.log(result.status, await result.json());
```

## Good to Know

* An async request counts against your [concurrency limit](https://docs.pikzels.com/rate-limits.md) from the moment you send it until it completes or fails.
* There are no webhooks. Poll `status_url` for the status.
* Both `GET` endpoints also work for requests sent without `async`. Their status is always `COMPLETED`.
* An unknown request ID, or one from another account, returns `404` with `NOT_FOUND`. So does the result of a request sent before October 25, 2026, which has no stored result.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.