# Kratk API — справочник для агентов

Base URL: `https://kratk.ru/api` · Формат: JSON · Язык ошибок: русский (`{"error": "..."}`).
Человеческая версия: https://kratk.ru/docs/api · Ключи: https://kratk.ru/admin/api-docs

## Авторизация

Каждый запрос: `Authorization: Bearer YOUR_API_KEY`. Ключ создаётся в кабинете и показывается один раз. API доступен на тарифах с `api_access`.

| Код | Значение |
|-----|----------|
| 400 | неверные данные или шаг выполнен не по порядку |
| 401 | ключ отсутствует, неверен, отключён, исчерпан лимит или нет доступа на тарифе |
| 403 | функция недоступна на тарифе (например, `custom_domains`) |
| 404 | объект не найден или чужой |
| 429 | лимит отправки писем |
| 500/502 | ошибка сервиса / сервер получателя не принял письмо |

## Ссылки

- `POST /links` — `{"url","customCode?","title?","description?","domain?"}` → ссылка. UTM — часть `url`.
- `POST /links/bulk` — `{"links":[{"url","title?","customCode?"}]}` до 1000 → `{created, errors}`.
- `GET /links` — список ссылок. `GET /links/export` — CSV.
- `GET /analytics` — `{totalLinks,totalClicks,clickRate}`.

## Домены: подключение по шагам

Подключение = 5 шагов. DNS-записи добавляет пользователь у своего DNS-провайдера, проверяет Kratk. После добавления записей опрашивайте `GET /domains/{id}/status` каждые ~5 с (DNS может обновляться до 30 минут), пока нужные поля не станут `true`.

### 1. Добавить домен
`POST /domains` `{"domain":"go.example.com"}` → объект домена (`id`, `domain`, `verified`, `sslEnabled`, `mailEnabled`, `mailMxVerifiedAt`, `mailSendingVerifiedAt`, …).
`GET /domains` — список. `GET /domains/{id}` — один. `DELETE /domains/{id}` — удалить.

### 2. Получить DNS-записи
`GET /domains/{id}/dns` →
```json
{
  "verifyHost": "_kratk-verify.go", "verifyToken": "d49b…",
  "recordHost": "go", "serverIp": "203.0.113.10", "cnameTarget": "kratk.ru",
  "dnsZone": "example.com",
  "inboundEmail": { "mxHost": "kratk.ru", "priority": 10, "recordHost": "go" }
}
```
Имена записей (`verifyHost`, `recordHost`) — относительно `dnsZone`; `@` = корень зоны.

| Шаг | Запись |
|-----|--------|
| Владение | `TXT  verifyHost = verifyToken` |
| Подключение | `A  recordHost → serverIp` (CNAME → `cnameTarget` тоже принимается, но на одном имени с CNAME нельзя держать MX/SPF) |
| Приём почты | `MX  inboundEmail.recordHost → mxHost, priority` |

### 3. Проверить DNS
`GET /domains/{id}/status` → `{"ownership":bool,"routing":bool,"mx":bool,"spf":bool,"dkim":bool,"dmarc":bool}`.
`ownership` — TXT владения найден (домен становится `verified`); `routing` — домен указывает на Kratk; `mx` — MX найден; `spf`+`dkim`+`dmarc` — записи отправки (все три нужны). Найденное подтверждение сохраняется.

### 4. SSL
`POST /domains/{id}/ssl` — выпустить сертификат. Требует `ownership` и `routing`. Ошибка 500 — повторить позже.

## Почта на домене

Требует подтверждённого домена (`verified: true`).

### Приём писем
`POST /domains/{id}/mail` — включить; `DELETE` — отключить. Затем добавить MX (шаг 2) и дождаться `mx: true`.
Принимаются письма на **любой** адрес домена (catch-all).

### Отправка писем
1. `POST /domains/{id}/mail/sending` — создаёт DKIM-ключ (селектор `kratk`), возвращает записи:
```json
{ "verified": false, "records": {
  "dnsZone": "example.com", "serverIp": "203.0.113.10",
  "spf":  { "type": "TXT", "host": "go", "value": "v=spf1 ip4:203.0.113.10 ~all" },
  "dkim": { "type": "TXT", "host": "kratk._domainkey.go", "value": "v=DKIM1; k=rsa; p=…" },
  "dmarc": { "type": "TXT", "host": "_dmarc.go", "value": "v=DMARC1; p=none;" } } }
```
   Повторно получить — `GET` того же пути (404, если не включено). Отключить и удалить ключ — `DELETE`.
   Если у домена уже есть SPF — добавьте в него `ip4:<serverIp>`, а не создавайте вторую запись.
   Все три записи (SPF, DKIM, DMARC) обязательны.
2. Дождаться `spf`, `dkim` и `dmarc` = `true` в `/status` (или `POST /domains/{id}/mail/sending/verify` → `{verified,spf,dkim,dmarc}`).

### Отправить письмо
`POST /inbox/send`
```json
{ "domainId": "DOMAIN_ID", "localPart": "info", "to": "customer@example.com",
  "subject": "Тема", "html": "<p>Текст</p>", "inReplyTo": "<message-id@…>" }
```
- Отправитель: `localPart@домен`; домен должен иметь подтверждённую отправку.
- Один получатель. Тело: `html` (очищается: `p br strong em u s ul ol li blockquote a h2 h3 hr`, ссылки http/https/mailto) или `text`. Текстовая версия строится автоматически.
- `inReplyTo` — `messageId` исходного письма (для ответа).
- Лимиты: 30/час и 200/сутки на аккаунт → `429`.
- Ответ `{"success":true,"messageId":"…"}`; `502` — сервер получателя не принял письмо.

`GET /inbox/sent?limit=50&cursor=…&search=…` (limit 1–100) → `{"items":[{"id","sender","recipient","subject","preview","messageId","status":"sent|failed","error","createdAt"}],"pagination":{limit,hasMore,nextCursor}}`. `id` — строка, `cursor` брать из `nextCursor`.
`GET /inbox/sent/{id}` — письмо целиком (`textBody`, `htmlBody`).

## Входящие

- `GET /inbox?limit=50&cursor=…&search=…` → `{"items":[{id,domain,recipient,sender,subject,preview,receivedAt,readAt}],"pagination":{limit,hasMore,nextCursor}}`. `id` — десятичная **строка**; `cursor` непрозрачный, передавать как получен; новые первыми, `limit` 1–100.
- `GET /inbox/{id}` — полное письмо (`textBody`, `htmlBody`, `headers`, `messageId`).
- `PATCH /inbox/{id}` `{"read":true|false}` — состояние прочтения.
- `DELETE /inbox/{id}` — необратимо, `204`.

## Рецепт: подключить домен с почтой «под ключ»

1. `POST /domains` → `id`.
2. `GET /domains/{id}/dns` → показать пользователю TXT (владение) и A (подключение).
3. Опрашивать `/status`, пока `ownership && routing`.
4. `POST /domains/{id}/ssl`.
5. `POST /domains/{id}/mail` → показать MX; `POST /domains/{id}/mail/sending` → показать SPF, DKIM и DMARC.
6. Опрашивать `/status`, пока `mx && spf && dkim && dmarc`.
7. Отправка: `POST /inbox/send`. Чтение: `GET /inbox`.
