Метод `POST /templates/validate` показывает, что получит получатель письма по шаблону, и находит фрагменты `{{…}}`, для которых в модели нет значения. Метод ничего не сохраняет и не отправляет, поэтому его можно вызывать сколько угодно раз.

## Когда это пригодится

* Перед первой отправкой нового шаблона.
* После правки шаблона, чтобы убедиться, что ничего не сломалось.
* Когда получатели видят в письме текст вида `{{name}}` вместо имени.
* В автоматических тестах вашего приложения: проверяйте шаблоны до выкладки.

## Как проверить шаблон

1. Передайте в запросе тему (Subject), HTML (HtmlBody) и текстовую версию (TextBody) шаблона. Нужна хотя бы одна из трёх частей.

2. Добавьте тестовые подстановки в поле TestRenderModel — те же, что вы передаёте в TemplateModel при отправке.

3. Изучите ответ: готовое письмо и список найденных ошибок.

Подстановка буквальная: ключ модели — это фрагмент текста шаблона вместе со скобками, значение — строка или число. Например, `{"{{name}}": "Иван"}` заменит `{{name}}` на «Иван». Фрагменты `{{SENDDATE}}` и `%SENDDATE%` заменяются сегодняшней датой, их передавать не нужно.

Пример запроса cURL:

```bash
curl "https://api.haskimail.ru/templates/validate" \
  -X POST \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -H "X-Haskimail-Server-Token: ваш_токен_сервера" \
  -d '{
    "Subject": "Заказ {{order}} оформлен",
    "HtmlBody": "<p>Здравствуйте, {{name}}!</p>\n<p>Трек-номер: {{track}}</p>",
    "TextBody": "Здравствуйте, {{name}}! Заказ {{order}} оформлен.",
    "TestRenderModel": {
      "{{name}}": "Иван",
      "{{order}}": "1042"
    }
  }'
```

В этом примере в модели нет значения для `{{track}}`.

## Что вернёт API

API отвечает HTTP 200, даже если в шаблоне есть ошибки. Общий результат — в поле **AllContentIsValid**: true, если ошибок нет ни в одной из переданных частей.

Для каждой переданной части — Subject, HtmlBody, TextBody — ответ содержит:

* **RenderedContent** — часть письма после подстановки, как её получит получатель;
* **ContentIsValid** — true, если в этой части нет ошибок;
* **ValidationErrors** — список ошибок. У каждой есть описание (Message), номер строки (Line) и позиция в строке (CharacterPosition) в исходном тексте этой части, считая с 1.

Ещё в ответе есть **SuggestedTemplateModel** — готовая модель со всеми фрагментами `{{…}}` из шаблона. Если значения для фрагмента нет, вместо него стоит заглушка, например `track_Value`. Её удобно скопировать и дополнить.

Ответ на пример выше:

```json
{
  "AllContentIsValid": false,
  "Subject": {
    "ContentIsValid": true,
    "ValidationErrors": [],
    "RenderedContent": "Заказ 1042 оформлен"
  },
  "HtmlBody": {
    "ContentIsValid": false,
    "ValidationErrors": [
      {
        "Message": "Нет значения для {{track}}: в TestRenderModel нет такого ключа",
        "Line": 2,
        "CharacterPosition": 16
      }
    ],
    "RenderedContent": "<p>Здравствуйте, Иван!</p>\n<p>Трек-номер: {{track}}</p>"
  },
  "TextBody": {
    "ContentIsValid": true,
    "ValidationErrors": [],
    "RenderedContent": "Здравствуйте, Иван! Заказ 1042 оформлен."
  },
  "SuggestedTemplateModel": {
    "{{order}}": "1042",
    "{{name}}": "Иван",
    "{{track}}": "track_Value"
  }
}
```

## Что считается ошибкой

* Фрагмент `{{…}}`, оставшийся после подстановки: в модели нет такого ключа или он записан иначе, например с пробелами внутри скобок.
* Открывающие скобки `{{` без закрывающих `}}`.

Больше ничего не проверяется: разметка HTML не валидируется, ссылки и открытия при проверке не отслеживаются.

**Важно:** если в ошибке Line и CharacterPosition равны 0, фрагмент `{{…}}` появился из значения модели, а в самом шаблоне его нет. Проверьте значения в TestRenderModel.

Если проверять нечего или TestRenderModel передан не как объект «фрагмент → значение», API вернёт HTTP 422 с кодом 1120.

## Частые вопросы

**Сохраняется ли шаблон при проверке?** Нет. Метод только показывает результат. Чтобы сохранить шаблон, создайте или обновите его в разделе «Шаблоны» или через API шаблонов.

**Уходит ли письмо получателю?** Нет, проверка не отправляет писем.

**Какой ключ нужен?** Серверный ключ в заголовке `X-Haskimail-Server-Token` или ключ аккаунта в заголовке `X-Haskimail-Account-Token`.

**Можно ли проверить уже сохранённый шаблон?** Да. Получите его тему, HTML и текстовую версию методом `GET /templates/{templateIdOrAlias}` и передайте их в запросе проверки вместе с тестовой моделью.

**Можно ли проверить шаблон с тестовым ключом?** Нет. `HASKIMAIL_API_TEST` работает только с методами отправки, а на проверку шаблона с ним API ответит HTTP 401 с кодом 10.

Подробнее — в [API шаблонов](https://haskimail.ru/developer/api/templates-api#validate-template) и в статье «[Использование шаблонов в Haskimail](https://help.haskimail.ru/hc/haskimail/articles/1768996255-ispolzovanie-shablonov-v-haskimail)».