Tested: GET /dictionaries/spacecraft с Accept-Language: en-US возвращает schemaJson с descriptions на ru (defaultLocale). Header игнорируется на этом endpoint. Локализация (Accept-Language header) работает только на records-side (read-api DictionaryReadController). DictionaryDefinitionController (writer/ordinis-app) возвращает schema без locale negotiation. Cheatsheet обновлён, добавлен warning в query-params секцию.
11 KiB
Ordinis API · Cheat Sheet
Одностраничный референс. Полный гайд — api-quickstart.md.
Base prod: https://ordinis.nstart.cloud/api/v1 (public LE-cert)
Base staging: https://ordinis.k8s.265.nstart.cloud/api/v1 (Swagger UI здесь)
Version: v2.37.x · OpenAPI: /v3/api-docs (только staging — на prod Swagger выключен)
Auth
TOKEN=$(curl -s -X POST https://auth.nstart.space/realms/nstart/protocol/openid-connect/token \
-d client_id=ordinis -d grant_type=password -d scope=openid \
-d username=$USER -d password=$PASS | jq -r .access_token)
curl -H "Authorization: Bearer $TOKEN" $ORDINIS/api/v1/me/notifications/settings
Scopes: PUBLIC (anon ok) · INTERNAL (auth) · RESTRICTED (admin).
Read (no auth для PUBLIC)
| Verb | Path | Что |
|---|---|---|
GET |
/version |
Версия + commit + builtAt |
GET |
/dictionaries |
Список всех справочников |
GET |
/dictionaries/{name} |
Детали + JSON Schema |
GET |
/dictionaries/templates |
6 шаблонов схем |
GET |
/dictionaries/templates/{id} |
Один шаблон со schemaJson |
GET |
/dictionaries/graph/outgoing |
FK-граф между справочниками |
GET |
/dictionaries/{name}/dependents |
Кто ссылается на этот dict |
GET |
/dictionaries/{name}/changelog |
Список изменений схемы |
GET |
/dictionaries/{name}/changelog/{id}/diff |
Diff между версиями |
GET |
/dictionaries/{name}/snapshots?from=&to=&granularity= |
Bucket'ы изменений для TimeTravel slider (granularity: hour/day/week) |
GET |
/{name}/records?as_scope=PUBLIC |
Список записей (⚠️ БЕЗ /dictionaries/ префикса) |
GET |
/{name}/records/{businessKey}?as_scope=PUBLIC |
Одна запись |
GET |
/dictionaries/{name}/records/{businessKey}/history?as_scope=PUBLIC |
История версий записи (Envers) — с /dictionaries/ |
GET |
/dictionaries/{name}/records/{businessKey}/cascade-preview?as_scope=PUBLIC |
Preview каскада — с /dictionaries/ |
GET |
/{name}/records/scheduled-summary?as_scope=PUBLIC |
Будущие версии (count + nearestValidFrom) |
GET |
/search?q= |
Поиск по справочникам (records не индексируются) |
GET |
/ai/info |
{enabled: bool} AI feature flag |
⚠️ Корень частой путаницы: consumer endpoints (
/records/...) идут БЕЗ/dictionaries/префикса. Admin-style audit endpoints (history, cascade-preview, changelog, drafts, snapshots) — С/dictionaries/. См. api-quickstart.md § Topology.
Query params (records)
?as_scope=PUBLIC,INTERNAL (required) CSV scope filter
?at=2026-03-15T00:00:00Z bitemporal: запись на конкретный момент (validFrom <= at < validTo)
Accept-Language: en-US (header) локаль — единственный рабочий путь
⚠️ ?locale= query param backend сейчас игнорирует
⚠️ Работает ТОЛЬКО на records endpoints.
Schema endpoint (`/dictionaries/{name}`) всегда
возвращает schemaJson на defaultLocale.
?bbox=lon1,lat1,lon2,lat2 geo: bounding box (для geo-dicts)
?polygon=<GeoJSON> geo: polygon-фильтр
Что НЕ работает (на read-api endpoint):
?limit=,?offset=— pagination отсутствует, возвращается весь массив?status=ACTIVE&country=RU— нет ad-hoc filtering по schema полям; фильтруй на клиенте
Write (требует auth)
⚠️ Все write-endpoints — на writer сервисе, с /dictionaries/ префиксом.
| Verb | Path | Что |
|---|---|---|
POST |
/dictionaries/{name}/records |
Создать запись (если approval не нужен) |
PUT |
/dictionaries/{name}/records/{businessKey} |
Обновить |
DELETE |
/dictionaries/{name}/records/{businessKey} |
Soft-delete (tombstone) |
POST |
/dictionaries/{name}/records/bulk-close |
Массовое закрытие |
POST |
/dictionaries/{name}/records/{businessKey}/cascade-close |
Закрыть с зависимыми |
POST |
/dictionaries/{name}/records/export-selected.csv |
Bulk export (выборка по ids в body) |
PATCH |
/dictionaries/{name}/schema |
Изменить схему inline (non-breaking) |
PUT |
/dictionaries/{name} |
Полностью пересоздать (breaking) |
Workflow (drafts + approvals)
| Verb | Path | Что |
|---|---|---|
POST |
/dictionaries/{name}/records/drafts |
Создать record draft |
POST |
/dictionaries/{name}/drafts |
Создать schema draft |
GET |
/dictionaries/{name}/drafts |
Список schema drafts по dict |
GET |
/dictionaries/{name}/drafts/active |
Активный draft (200+null если нет) |
GET |
/dictionaries/{name}/drafts/{id} |
Один draft |
DELETE |
/dictionaries/{name}/drafts/{id} |
Withdraw |
POST |
/dictionaries/{name}/drafts/{id}/review |
Назначить ревью |
POST |
/dictionaries/{name}/drafts/{id}/decision |
Approve/reject schema draft |
POST |
/dictionaries/{name}/drafts/{id}/publish |
Опубликовать после approve |
GET |
/drafts/me |
Мои record-drafts (status filter) |
GET |
/drafts/{id} |
Один record draft |
DELETE |
/drafts/{id} |
Withdraw record draft |
POST |
/drafts/{id}/approve |
Одобрить (body: {comment}) |
POST |
/drafts/{id}/reject |
Отклонить (body: {comment}) |
GET |
/admin/reviews/pending |
Очередь ревьюера (records) |
GET |
/admin/schema-reviews/pending |
Очередь ревьюера (schemas) |
GET |
/admin/schema-drafts/me |
Мои schema drafts |
AI
curl -X POST -H "Authorization: Bearer $TOKEN" -H "Content-Type: application/json" \
$ORDINIS/api/v1/ai/suggest-field \
-d '{"prompt":"контактный email оператора"}'
Limits: 30 req/min на IP, circuit breaker 10 fails / 60s → open 5min (503 circuit_open).
Notifications (per-user, auth)
| Verb | Path | Что |
|---|---|---|
GET |
/me/notifications |
Bell-bar feed |
POST |
/me/notifications/{id}/read |
Mark as read |
POST |
/me/notifications/read-all |
Mark all as read |
GET |
/me/notifications/preferences |
Per-event matrix |
PUT |
/me/notifications/preferences |
Сохранить матрицу |
GET |
/me/notifications/settings |
Quiet hours config |
PUT |
/me/notifications/settings |
Сохранить quiet hours |
Webhooks (admin)
| Verb | Path | Что |
|---|---|---|
GET |
/admin/webhooks/subscriptions |
Список подписок |
POST |
/admin/webhooks/subscriptions |
Создать (secret в ответе, один раз) |
GET |
/admin/webhooks/subscriptions/{id} |
Детали |
PUT |
/admin/webhooks/subscriptions/{id} |
Обновить |
DELETE |
/admin/webhooks/subscriptions/{id} |
Удалить |
POST |
/admin/webhooks/subscriptions/{id}/rotate-secret |
Перевыпуск ключа |
POST |
/admin/webhooks/subscriptions/{id}/test |
Test delivery |
GET |
/admin/webhooks/subscriptions/{id}/stats |
Histogram (24h/7d) |
GET |
/admin/webhooks/subscriptions/{id}/deliveries |
Recent deliveries |
GET |
/admin/webhooks/deliveries/dlq |
DLQ list |
POST |
/admin/webhooks/deliveries/{id}/retry |
Manual retry |
Headers delivered
X-Ordinis-Event: RecordCreated
X-Ordinis-Signature: sha256=<hex> HMAC-SHA256(body, secret)
X-Ordinis-Delivery: del_01HXY...
User-Agent: ordinis-alerts
Event types
RecordCreated · RecordUpdated · RecordClosed · RecordRestored · BulkClosed · SchemaDraftSubmitted · SchemaDraftApproved · SchemaDraftRejected · SchemaDraftPublished · RecordDraftSubmitted · RecordDraftApproved
Audit (admin)
| Verb | Path | Что |
|---|---|---|
GET |
/admin/audit?dictionary=&action=&user=&dateFrom=&dateTo= |
Фильтрованный аудит |
GET |
/admin/audit/export.csv |
Полный экспорт |
GET |
/admin/audit/export-selected.csv |
Selected ids экспорт |
Action types (13): DICTIONARY_CREATED · SCHEMA_UPDATED · SCHEMA_PUBLISHED · RECORD_CREATED · RECORD_UPDATED · RECORD_CLOSED · RECORD_RESTORED · DRAFT_CREATED · DRAFT_SUBMITTED · DRAFT_APPROVED · DRAFT_REJECTED · DRAFT_WITHDRAWN · REVIEWER_ASSIGNED
Outbox (admin)
| Verb | Path | Что |
|---|---|---|
GET |
/admin/outbox/stats |
Pending/DLQ counters |
GET |
/admin/outbox/dlq |
DLQ events list |
Errors — единая форма
{ "status": 422, "code": "validation_failed", "message": "...",
"details": {}, "traceId": "...", "timestamp": "..." }
| HTTP | code | |
|---|---|---|
| 400 | bad_request |
Невалидный body |
| 401 | unauthorized |
Нет/просрочен токен |
| 403 | forbidden |
Scope/role не пускает |
| 404 | not_found |
Нет такого ресурса |
| 409 | conflict |
Concurrent update / unique violation |
| 422 | validation_failed |
Schema validation fail |
| 429 | rate_limited |
Лимит запросов |
| 500 | internal_error |
См. traceId |
| 502 | llm_error |
AI: LLM upstream |
| 503 | circuit_open |
AI: circuit breaker |
60-second smoke
ORDINIS=https://ordinis.nstart.cloud # prod (public LE)
# или: ORDINIS=https://ordinis.k8s.265.nstart.cloud # staging
curl -s $ORDINIS/api/v1/version | jq # alive
curl -s $ORDINIS/api/v1/dictionaries | jq 'length' # 37 на prod / 39 на staging
curl -s $ORDINIS/api/v1/dictionaries/spacecraft | jq '.scope' # "PUBLIC"
curl -s "$ORDINIS/api/v1/spacecraft/records?as_scope=PUBLIC" | jq '.[0].businessKey'
curl -s "$ORDINIS/api/v1/search?q=spacecraft" | jq '.total' # >0
curl -s $ORDINIS/api/v1/ai/info | jq '.enabled' # true / false
Postman collection
Готовая collection с реальными запросами (28 запросов, demo-flow): см. docs/integration/postman/ или ~/Desktop/Ordinis-Postman/ (если генерировал локально).
Связанные доки
api-quickstart.md · bundle-format-spec.md · docs/changelog.md · Swagger UI /swagger-ui/index.html