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

# AI API

> Universal AI calls — chat, images, speech, transcription, video — billed against your space.

The Kazzle AI API gives you one authenticated endpoint to call any model we support. You pay once, in credits, against your space — no separate accounts for OpenAI, Anthropic, Cloudflare Workers AI, or anyone else we route to.

All endpoints live under `/ai/*` on `https://api.kazzle.app` and accept a `kzl_` API key in the `Authorization` header. See [API keys](/platform/api-keys) for how to create one.

Generated Kazzle apps should use this API too — see [AI in apps](/apps/ai-api) for wiring the key into a component. Do not ask users for provider keys unless they explicitly want to use their own provider account.

## Capabilities

| Endpoint                        | Modality               | Standardized input                          | Standardized output                            |
| ------------------------------- | ---------------------- | ------------------------------------------- | ---------------------------------------------- |
| `POST /ai/chat/completions`     | Chat (text, streaming) | OpenAI-compatible `messages[]`              | OpenAI-compatible `choices[]` or SSE stream    |
| `POST /ai/responses`            | Responses API          | OpenAI Responses-compatible                 | OpenAI Responses-compatible                    |
| `POST /ai/images/generations`   | Image                  | `{ model, prompt, size?, output_format? }`  | `{ images: [{ url? \| b64?, mimeType }] }`     |
| `POST /ai/audio/speech`         | Text-to-speech         | `{ model, text, voice?, format? }`          | `audio/*` byte stream                          |
| `POST /ai/audio/transcriptions` | Speech-to-text         | `multipart/form-data` with `file` + `model` | `{ text }`                                     |
| `POST /ai/video/generations`    | Video (async)          | `{ model, prompt, ... }`                    | `{ id, status, pollUrl }`                      |
| `GET  /ai/responses/{id}`       | Async poll             | response id                                 | provider-shaped result                         |
| `POST /ai/gateway`              | Raw passthrough        | Any Workers AI / provider-native payload    | Raw upstream response                          |
| `GET  /ai/models`               | Catalog                | —                                           | `{ models: [{ id, modality, pricing, ... }] }` |

`GET /ai/models` is the source of truth for which model ids work on which endpoint. Read it first if you're building against the API.

## How a call works

Every billable call goes through five phases. You don't see most of these — they're tracked server-side so we can refund failed calls and report exact usage.

| Phase      | What happened                                                                                                |
| ---------- | ------------------------------------------------------------------------------------------------------------ |
| `open`     | We've created a billing event tied to your request, but haven't called upstream yet.                         |
| `recorded` | The upstream provider returned. We have a log id from Cloudflare AI Gateway. The cost is not yet known.      |
| `priced`   | Cloudflare reported the final cost. We applied our markup and wrote the credit charge. Terminal.             |
| `failed`   | The upstream call failed, or we couldn't get a cost after 20 retries. Customer is **not** charged. Terminal. |
| `synced`   | The priced event has been delivered to our metering system.                                                  |

Every successful response includes `x-kazzle-ai-billing-event-id: airesp_...` — keep it if you want to correlate the request with usage exports later.

## Billing & markup

We charge `cloudflare_cost_usd × (1 + markup)`. The markup is published in [Settings → Billing → Pricing](/platform/billing#pricing). Calls that Cloudflare priced at \$0 (free Workers AI tier, promos) reach the `priced` phase with zero cost and are never billed.

Reserve: you need at least **\$0.50** equivalent in credits to make a call. We hold this against your balance until the call finishes, then settle the actual cost.

## Errors

| Status              | Meaning                                                                      |
| ------------------- | ---------------------------------------------------------------------------- |
| `401`               | Missing or invalid `kzl_` API key.                                           |
| `402`               | Insufficient credits for the reserve. Top up in **Settings → Billing**.      |
| `4xx` from upstream | Forwarded as-is. Body contains the provider's error. Customer is not billed. |
| `5xx` from upstream | Forwarded as-is. Customer is not billed.                                     |

## Example — image generation

```bash theme={"theme":"material-theme-darker"}
curl https://api.kazzle.app/ai/images/generations \
  -H "Authorization: Bearer kzl_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "openai/gpt-image-1",
    "prompt": "a single red dot on white",
    "size": "1024x1024"
  }'
```

```json theme={"theme":"material-theme-darker"}
{
  "images": [
    { "url": "https://...", "mimeType": "image/png" }
  ]
}
```

## Example — text to speech

```bash theme={"theme":"material-theme-darker"}
curl https://api.kazzle.app/ai/audio/speech \
  -H "Authorization: Bearer kzl_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{"model":"openai/tts-1","text":"hello world","voice":"alloy","format":"mp3"}' \
  --output speech.mp3
```

## See also

* [API Reference](/api-reference) — full request/response schemas for every endpoint
* [API keys](/platform/api-keys) — creating and using `kzl_` keys
* [Billing](/platform/billing) — credits, plans, and the markup we apply
