API записи
Все эндпоинты записи находятся под /api/v1 и требуют Bearer-токена со скоупом write.
Authorization: Bearer <api-key>
Тенант определяется по ключу. ID тенанта не фигурирует в URL.
Режим надёжности
Каждый эндпоинт записи принимает необязательный заголовок X-Letopis-Mode:
| Значение | Ответ | Гарантия |
|---|---|---|
strict |
201 после записи в MongoDB |
Синхронно; подтверждено до ответа |
durable |
202 + тикет |
Очередь Redis Streams; воркер пишет асинхронно |
fast |
202 + тикет |
In-memory очередь; максимальная пропускная способность |
При отсутствии заголовка применяется настроенный reliability_mode коллекции (по умолчанию durable).
Идемпотентность
Для предотвращения дублей при повторе — передайте клиентский ключ:
- Заголовок
Idempotency-Key, или - Поле
event_idв теле запроса (приоритет выше).
Если тот же ключ поступает повторно в течение окна дедупликации (по умолчанию 24 ч), сервер воспроизводит оригинальный ответ. Второе событие не записывается.
Ingest полного состояния
POST /api/v1/collections/{collection}/entities/{entityId}/state
Отправьте полное текущее состояние сущности. Сервер вычислит дифф относительно последнего известного состояния.
Тело запроса
{
"state": {
"title": "ООО Ромашка",
"amount": 50000,
"stage": "prospect"
},
"event_id": "evt-001",
"author_id": "user-42",
"source": "crm-backend",
"ts_source": "2026-06-01T10:00:00Z",
"expected_version": 3
}
| Поле | Тип | Обязательное | Описание |
|---|---|---|---|
state |
object | Да | Полное текущее состояние сущности |
op |
string | Нет | create или update; определяется автоматически |
event_id |
string | Нет | Клиентский ID для идемпотентности |
author_id |
string | Нет | Кто сделал изменение |
source |
string | Нет | Система-источник |
ts_source |
RFC3339 | Нет | Время изменения в системе-источнике |
expected_version |
integer | Нет | Оптимистичная блокировка; 409 при несовпадении |
meta |
object | Нет | Произвольные метаданные |
Ingest готового диффа
POST /api/v1/collections/{collection}/entities/{entityId}/diff
{
"diff": [
{"path": "amount", "op": "change", "old": 50000, "new": 75000},
{"path": "stage", "op": "change", "old": "prospect", "new": "qualified"}
],
"author_id": "user-42"
}
Удаление сущности
POST /api/v1/collections/{collection}/entities/{entityId}/delete
Записывает событие delete. Состояние сущности очищается; история (события и слепки) сохраняется. Для физического удаления (GDPR) используйте Admin API (purge).
Пакетная запись
POST /api/v1/collections/{collection}/batch
{
"writes": [
{
"entity_id": "deal-1",
"type": "state",
"state": {"title": "ООО Ромашка", "amount": 75000}
},
{
"entity_id": "deal-2",
"type": "diff",
"diff": [{"path": "stage", "op": "change", "old": "prospect", "new": "won"}]
}
]
}
Элементы обрабатываются независимо; ошибка одного не откатывает другие.
Опрос тикета
GET /api/v1/tickets/{ticketId}
{
"ticket_id": "tkt_01hx...",
"status": "stored",
"entity_id": "deal-1",
"collection": "crm.deals",
"version": 4,
"ts_stored": "2026-06-02T09:00:01Z"
}
Статус: accepted → processing → stored (успех) или failed (с полем error).