Skip to content
  1. Компоненты
  2. mxHeadless
  3. API

Обзор API ​

Базовый URL: {prefix}/v1, по умолчанию /api/v1.

Живой каталог на установленном сайте: GET /meta/endpoints и Swagger UI /docs. Ниже маршруты core из RoutesRegistrar и CoreEndpointBootstrap (версия пакета 1.0.43). Extras добавляют свои через registerEndpoint.

Запрос проходит стек middleware до обработчика:

В стеке также работают BodyLimit (413), ContentNegotiation (406), CORS, RequestId, AuditLog и Error — на схеме они не показаны.

Envelope успеха ​

json
{
  "data": {},
  "meta": {
    "total": 100,
    "count": 20,
    "limit": 20,
    "offset": 0,
    "has_more": true
  },
  "links": {
    "self": "/api/v1/resources?limit=20&offset=0",
    "next": "/api/v1/resources?limit=20&offset=20"
  }
}

При ошибке ответ в формате RFC 9457, без обёртки data/meta.

Meta и auth ​

MethodPathPublicScopeНазначение
GET/да-Discovery: версия, возможности
GET/healthда-Health БД: data.status (ok / degraded), data.database, data.timestamp. Доступен при kill switch
GET/schemaда-Схема зарегистрированных объектов
GET/docsда-Swagger UI (mxheadless_swagger_enabled)
GET/meta/endpointsда-Живой каталог эндпоинтов
GET/meta/openapiда-OpenAPI в envelope
GET/meta/openapi.jsonда-Сырой OpenAPI 3.0 JSON
POST/auth/tokenда*-OAuth token. Работает только при mxheadless_oauth_enabled

*Маршрут публичный, но endpoint выключен настройкой, пока OAuth выключен.

Resources и pages ​

MethodPathPublicScope
GET/resourcesдаresources.read
GET/resources/{id}даresources.read
POST/resourcesнетresources.create
PUT, PATCH/resources/{id}нетresources.update
DELETE/resources/{id}нетresources.delete
GET/pages/{uri}даresources.read

Публичный GET для anonymous. API key / OAuth на публичном GET всё равно должны иметь указанный scope.

Contexts ​

MethodPathPublicScope
GET/contextsнетcontexts.read
GET/contexts/{key}нетcontexts.read
GET/contexts/{key}/settingsнетcontexts.read

{key}: ключ контекста (web, mgr, …). Settings по списку.

Elements (read-only) ​

MethodPathPublicScope
GET/chunksнетchunks.read
GET/chunks/{id}нетchunks.read
GET/templatesнетtemplates.read
GET/templates/{id}нетtemplates.read
GET/snippetsнетsnippets.read
GET/snippets/{id}нетsnippets.read
GET/tvsнетtvs.read
GET/tvs/{id}нетtvs.read
GET/categoriesнетcategories.read
GET/categories/{id}нетcategories.read
GET/content_typesнетcontent_types.read
GET/content_types/{id}нетcontent_types.read

Универсальные объекты ​

Только для имён из ObjectRegistry (core + extras). Незарегистрированное {name} даёт 404.

MethodPathPublicScope
GET/objects/{name}нет{name}.read
GET/objects/{name}/{id}нет{name}.read
POST/objects/{name}нет{name}.create
PUT, PATCH/objects/{name}/{id}нет{name}.update
DELETE/objects/{name}/{id}нет{name}.delete

Пример: object products → scopes products.read, products.create, …

Полный список scopes: Авторизация.

Kill switch ​

При mxheadless_enabled=false работают только GET / и GET /health. Остальное → 503 service_disabled.

Заголовки ​

Заголовок запроса:

ЗаголовокРоль
Authorization / X-API-KeyУчётные данные
X-ContextКонтекст MODX
X-CSRF-TokenМутации по сессии
Idempotency-KeyИдемпотентный POST
X-Request-IDКорреляция

X-Request-ID принимается только в формате 8–64 символа из A-Za-z0-9, -, _, .. Значение вне формата игнорируется, сервер подставляет случайный hex-идентификатор.

Ответы rate limit: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset. На 429 добавляется Retry-After с числом секунд до окна.

Заголовок ответа при CORS: Vary: Origin. Состав Access-Control-Expose-Headers задаёт mxheadless_cors_expose_headers.

Заголовок Accept проверяется на всех маршрутах: без application/json и без */* ответ 406. Исключение одно, text/html проходит только на /api/v1/docs, чтобы Swagger UI открывался из браузера.

Дальше по группам ​