# Validate template code

`POST https://postcraft.io/api/v1/templates/validate`

Checks code-mode content and returns the diagnostics a write would, without storing anything and without touching any template. Use it to find out whether generated Handlebars compiles before replacing a template that is being rendered. Any valid credential may call it.

## Authentication

Send one of these headers:

- `x-api-key: <key>`: Long-lived account credential. Create one from the dashboard.
- `Authorization: Bearer <token>`: Short-lived presigned token scoped to a single template (minted via /presigned-url).

## Request body

`content-type: application/json`

| Field | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| `code` | string | yes |  |
| `styles` | string | no |  |
| `exampleContext` | object | no | Structural JSON value: object or array. Scalars and null are rejected. |
| `subject` | string or null | no | Email subject line, as Handlebars rendered against the render context. `null` removes it; omit it to keep the stored one. |

Example:

```json
{
  "code": "Hello {{name}}, welcome to {{product}}!",
  "exampleContext": {
    "name": "Ada",
    "product": "Postcraft"
  }
}
```

## Responses

### 200

The content was checked.

| Field | Type | Required | Description |
| ----- | ---- | -------- | ----------- |
| `diagnostics` | object[] | yes | Problems found in the template. Advisory rather than fatal: a template that renders can still carry warnings, while an `error` severity is one that will not. |

### Errors

Every error answers with `{ "error": { "code": string, "message": string } }`.

| Status | Meaning |
| ------ | ------- |
| 400 | Invalid input. |
| 401 | Missing or invalid credential. |
| 403 | Authenticated but not allowed. |
| 404 | Not found. |
| 413 | Payload exceeds size limit. |
| 422 | Template render failed. |
| 429 | Rate limited. |

The whole API as an OpenAPI document: https://postcraft.io/api/v1/openapi.json
