## Start a site generation

`POST /v1/sites/ai/generate`

Starts site generation from a text brief.

## Request body

| Field | Type | Required | Description |
|---|---|---|---|
| `description` | string | yes | Site brief, at most 4000 characters; validated by Bitrix24 |

## Parameters

| Parameter | Type | Required | Default | Description |
|---|---|---|---|---|
| `Idempotency-Key` (header) | string | no | absent | Non-empty client key forwarded unchanged; empty or whitespace-only values are treated as absent |

## Examples

### curl — personal key

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/sites/ai/generate" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: example-site-generation-1" \
  -d '{"description": "A small demonstration website for a flower shop. This is an API integration test."}'
```

### curl — OAuth application

```bash
curl -X POST "https://vibecode.bitrix24.com/v1/sites/ai/generate" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: example-site-generation-1" \
  -d '{"description": "A small demonstration website for a flower shop. This is an API integration test."}'
```

### JavaScript — personal key

```javascript
const res = await fetch("https://vibecode.bitrix24.com/v1/sites/ai/generate", {
  "method": "POST",
  "headers": {
    "X-Api-Key": "YOUR_API_KEY",
    "Content-Type": "application/json",
    "Idempotency-Key": "example-site-generation-1"
  },
  "body": JSON.stringify({"description": "A small demonstration website for a flower shop. This is an API integration test."})
});
const result = await res.json();
console.log(result);
```

### JavaScript — OAuth application

```javascript
const res = await fetch("https://vibecode.bitrix24.com/v1/sites/ai/generate", {
  "method": "POST",
  "headers": {
    "X-Api-Key": "YOUR_APP_KEY",
    "Authorization": "Bearer USER_SESSION_TOKEN",
    "Content-Type": "application/json",
    "Idempotency-Key": "example-site-generation-1"
  },
  "body": JSON.stringify({"description": "A small demonstration website for a flower shop. This is an API integration test."})
});
const result = await res.json();
console.log(result);
```

## Response fields

| Field | Type | Description |
|---|---|---|
| `success` | boolean | `true` on success |
| `data` | object | Generation state |
| `data.id` | number | Generation identifier |
| `data.status` | string | `running`, `completed` or `failed` |
| `data.siteId` | number | Generated site identifier, 0 until created; [sites](../get.md) |
| `data.pageId` | number | Generated page identifier, 0 until created; [pages](/docs/entities/pages/get) |
| `data.draftSiteId` | number | Draft site identifier on failure, 0 otherwise |
| `data.draftPageId` | number | Draft page identifier on failure, 0 otherwise |
| `data.message` | string | Human-readable state; use status for branching |
| `data.error` | string \| null | Failure reason or null |
| `data.errorDetails` | string \| null | Request-limit detail or null |

## Response example

```json
{
  "success": true,
  "data": {
    "id": 11,
    "status": "running",
    "siteId": 0,
    "pageId": 0,
    "draftSiteId": 0,
    "draftPageId": 0,
    "message": "Generating a site",
    "error": null,
    "errorDetails": null
  }
}
```

## Error response example

```json
{
  "success": false,
  "error": {
    "code": "INVALID_PARAMS",
    "message": "Request validation failed"
  }
}
```

## Errors

| HTTP | Code | Description |
|---|---|---|
| 400 | `INVALID_PARAMS` | Bitrix24 refused the request |
| 401 | `MISSING_API_KEY`, `INVALID_API_KEY`, `TOKEN_MISSING` | Missing or unusable credentials |
| 403 | `SCOPE_DENIED` | The key lacks the landing scope |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | The key forbids writes |

[Common errors](/docs/errors).

## Known specifics

Bitrix24 automatically attempts to publish the generated site. Include only information intended for public viewing in the description.

The generation takes the user's available AI site draft. An open AI site chat loses it and must be reloaded. Send a client `Idempotency-Key` to reuse the completed response for 24 hours. Concurrent repeats before that response is stored are not protected. Without the header, or with an empty or whitespace-only header, every call starts another generation. The platform does not retry the start automatically.

Calls run as the webhook owner or the user whose OAuth token the key uses. Read the result through [generation status](./status.md): `running`, `completed` or `failed`.

## See also

- [AI site generation](../ai.md)
