# Mailer API — инструкция для клиента

Через выданный вам **токен** можно запускать отправку писем. Вы передаёте только
адресата, ссылку и несколько переменных — всё остальное (шаблон, тема, отправитель,
доставка) настроено на нашей стороне.

- **База API:** `https://grzl.cc`
- **Авторизация:** заголовок `Authorization: Bearer <ваш_токен>` в каждом запросе.
- Токен — секрет. Не публикуйте его. При компрометации сообщите нам — отзовём.
- **Один токен на несколько человек.** Токеном может пользоваться вся ваша команда —
  это нормально. В каждом запросе передавайте Telegram `id` и `username` того, кто
  запускает именно эту отправку (идут только в учёт, в письмо не попадают). Квота и
  лимит запросов — общие на токен (их делят все, кто им пользуется).

---

## 1. Справочник: страны и сервисы

Перед отправкой возьмите список доступных стран и сервисов — из них выбираете, куда слать.

```
GET /api/v1/catalog
Authorization: Bearer <токен>
```

Ответ:
```json
{
  "countries": {
    "PL": { "flag": "🇵🇱", "services": ["myemail.pl", "testshop.pl"] },
    "DE": { "flag": "🇩🇪", "services": ["myemail.de", "testshop.de"] }
  }
}
```

---

## 2. Запуск отправки

```
POST /api/v1/send
Authorization: Bearer <токен>
Content-Type: application/json
```

Тело запроса:

| Поле          | Обяз. | Описание |
|---------------|:---:|----------|
| `country`     | да  | Код страны из каталога (напр. `PL`) |
| `service`     | да  | Сервис из каталога этой страны (напр. `myemail.pl`) |
| `email`       | да  | E-mail получателя |
| `link`        | да  | Ссылка (`http(s)://…`) — подставляется в кнопку письма |
| `id`          | да  | Telegram **userid** (число) того, кто запускает отправку — для учёта, в письмо не идёт |
| `username`    | да  | Telegram **@username** того же человека — для учёта, в письмо не идёт |
| `price`       | нет | Цена товара **без валюты** (напр. `199`) → `*PRICE*` |
| `predmetname` | нет | Название товара → `*PNAME*` |

Пример:
```bash
curl -X POST https://grzl.cc/api/v1/send \
  -H "Authorization: Bearer <токен>" \
  -H "Content-Type: application/json" \
  -d '{
    "country": "PL",
    "service": "myemail.pl",
    "email": "user@example.com",
    "link": "https://target.example/offer",
    "id": "123456789",
    "username": "@kesha",
    "price": "199",
    "predmetname": "iPhone 15"
  }'
```

Ответ (письмо принято в очередь и будет отправлено):
```json
{ "id": "snd_ab12cd34", "status": "queued" }
```

Поле `id` сохраните — по нему можно узнать статус отправки (см. §3).

> Дату в письмо (`*DATE*`) подставляем сами — в часовом поясе страны получателя.
> Тему, оформление, отправителя и способ доставки вы не задаёте.
> Очевидные опечатки домена исправляются автоматически (`gamil.com` → `gmail.com`).

---

## 3. Статус отправки

По `id` из ответа `/send` можно узнать, что стало с письмом (любые отправки этого
токена — в т.ч. сделанные другими людьми с тем же токеном; чужие токены недоступны).

```
GET /api/v1/send/{id}
Authorization: Bearer <токен>
```

Ответ:
```json
{ "id": "snd_ab12cd34", "status": "sent", "label": "Отправлено",
  "email": "b***@gmail.com", "country": "PL", "service": "myemail.pl",
  "created_at": "2026-10-28T10:00:00" }
```

| `status`  | `label`          | Что значит |
|-----------|------------------|------------|
| `pending` | В обработке      | В очереди/отправляется — спросите позже |
| `sent`    | Отправлено       | Письмо ушло |
| `error`   | Ошибка отправки  | Не ушло; причина — в поле `error` |

- Неизвестный `id` или отправка под другим токеном → `404`.
- Адрес получателя в ответе **замаскирован** (`b***@gmail.com`).

Опционально — лента последних отправок/ошибок (нужен scope `logs:read`):
`GET /api/logs/sends` и `GET /api/logs/errors` (параметр `?limit=`, свежие сверху,
email замаскирован).

---

## 4. Повторы на тот же адрес

Защита от дублей управляется на нашей стороне — никаких заголовков от вас не
требуется. Если политика включена, повторная отправка на тот же адрес не
выполняется: ответ `200` с `{"status":"duplicate"}` (письмо не отправлено).

---

## 5. Коды ответов

| Код   | Значение |
|-------|----------|
| `200` | Принято в очередь (`{"id":…, "status":"queued"}`) |
| `401` | Нет/неверный заголовок `Authorization` |
| `403` | Токен недействителен/отозван, либо сервис/домен ссылки не разрешён токену, либо запрос не с разрешённого IP |
| `404` | Статус: неизвестный `id` или отправка под другим токеном |
| `409` | Адрес в стоп-листе (отписка/жалоба) — отправка не выполняется |
| `422` | Ошибка данных: неизвестная страна/сервис, кривой e-mail, ссылка не `http(s)` |
| `429` | Превышен лимит запросов в минуту или суточная квота |
| `503` | Сервис недоступен (техработы или очередь переполнена) — повторите позже |

---

## 6. Лимиты

- На токен действуют **лимит запросов в минуту** и **суточная квота** (значения
  сообщим при выдаче) — они **общие на весь токен**, их делят все, кто им пользуется.
  При превышении — `429`, повторите позже.
- Отправка на адреса из нашего стоп-листа (отписки/жалобы) не выполняется (`409`).
- Повтор на тот же адрес может быть отклонён (`200` с `status: duplicate`) — см. §4.

---

## 7. Чего API не делает

- Не принимает произвольный HTML/тему/отправителя — контент письма задаём мы.
- Не раскрывает внутренние данные (какой сервер/ящик использован, чужие логи).
- Не управляет токенами и настройками — только запуск отправки.
