# POST /api/render/generate

Render a template synchronously and return a public CDN URL to the
finished image. This is the workhorse endpoint of the Audome API.

```http
POST https://audome.io/api/render/generate
Authorization: Bearer YOUR_API_TOKEN
Content-Type: application/json
```

## Request body

| Field            | Type    | Required | Description                                                                 |
| ---------------- | ------- | -------- | --------------------------------------------------------------------------- |
| `projectId`    | string  | yes\*    | Audome template ID. Either `projectId` or `html` must be provided.       |
| `data`         | object  | no       | Dynamic values keyed as `<elementKey>.text` or `<elementKey>.img`.       |
| `html`         | string  | yes\*    | Inline HTML to render. Mutually exclusive with `projectId`.                |
| `width`        | integer | no       | Canvas width in pixels. Defaults to the template width.                     |
| `height`       | integer | no       | Canvas height in pixels. Defaults to the template height.                   |
| `format`       | enum    | no       | One of `png`, `jpeg`, `webp`. Defaults to `png`.                       |
| `quality`      | integer | no       | 1-100. Ignored for `png`. Defaults to 90.                                  |
| `backgroundColor` | string | no    | CSS colour. Use `transparent` to force PNG with alpha.                     |

\* Either `projectId` or `html` is required.

### Dynamic data shape

Each editable element in your template has a `dynamicKey`. Provide
values namespaced by suffix:

- `<key>.text` for text elements.
- `<key>.img` for image elements (must be a public HTTPS URL).

```json
{
  "projectId": "8fce2c7e-7e6f-4d46-b5b1-2aaa5a44f1c9",
  "data": {
    "title.text": "Summer sale",
    "subtitle.text": "Up to 50% off",
    "hero.img": "https://images.example.com/hero.jpg"
  }
}
```

## Successful response

```json
{
  "success": true,
  "imageUrl": "https://cdn.audome.io/renders/2026/05/abc123.png",
  "width": 1080,
  "height": 1080,
  "format": "png",
  "creditsUsed": 1,
  "creditsRemaining": 499,
  "generationId": "gen_01HX9Y..."
}
```

## Errors

```json
{
  "success": false,
  "error": "Insufficient credits",
  "code": "INSUFFICIENT_CREDITS"
}
```

| Status | Code                   | Meaning                                              |
| ------ | ---------------------- | ---------------------------------------------------- |
| 400    | `VALIDATION_FAILED`  | Body did not validate against the schema.            |
| 401    | `UNAUTHORIZED`       | Missing or invalid Bearer token.                     |
| 402    | `INSUFFICIENT_CREDITS` | Account has zero render credits.                   |
| 404    | `PROJECT_NOT_FOUND`  | `projectId` does not exist for this account.        |
| 429    | `RATE_LIMITED`       | Per-minute request limit exceeded.                   |
| 500    | `RENDER_FAILED`      | Internal renderer error. Safe to retry once.         |

## Examples

### cURL

```bash
curl -X POST https://audome.io/api/render/generate \
  -H "Authorization: Bearer YOUR_API_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "projectId": "PROJECT_ID",
    "data": { "title.text": "Hello" }
  }'
```

### Node.js

```js
const res = await fetch('https://audome.io/api/render/generate', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.AUDOME_TOKEN}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    projectId: 'PROJECT_ID',
    data: { 'title.text': 'Hello world' },
    format: 'jpeg',
    quality: 85,
  }),
});
const json = await res.json();
console.log(json.imageUrl);
```

### Python

```python
import os, requests
r = requests.post(
    "https://audome.io/api/render/generate",
    headers={"Authorization": f"Bearer {os.environ['AUDOME_TOKEN']}"},
    json={
        "projectId": "PROJECT_ID",
        "data": {"title.text": "Hello world"},
        "format": "png",
    },
    timeout=60,
)
r.raise_for_status()
print(r.json()["imageUrl"])
```

## Discovering a project's dynamic schema

To programmatically learn which keys a template accepts:

```bash
curl https://audome.io/api/render/projects/PROJECT_ID \
  -H "Authorization: Bearer YOUR_API_TOKEN"
```

The response includes a `dynamicElements` array, each with `type`,
`dynamicKey`, `defaultValue`, and `placeholder`.
