Admin API
The admin branch (/admin/{tenant}) carries tenant-wide administrative operations — the data model's status, reload and upgrade, full rebuilds, ACL rebuilds, per-class recalculation and sync, and tenant data deletion. Every route under this prefix requires the coarse admin role (see Enforcement); being admin-only follows from the /admin/ prefix itself rather than from a per-route allowlist.
| Method | Path | Purpose |
|---|---|---|
GET | modelStatus | The outcome of the latest load of the tenant's data model. |
POST | reloadModel | Reload the data model from its repository. |
GET | modelUpgrade | Download the model's files converted to the current definition format. |
POST | rebuild | Rebuild the tenant's data. |
POST | rebuildAccessControl | Re-derive ACL rows from the current accessControl definitions. |
POST | {typeName}/recalculate | Recalculate formulas for a class. |
POST | {typeName}/sync | Sync a class. |
DELETE | (root) ?name=&deleteTenant= | Delete tenant data (optionally the tenant). |
Model status
GET /admin/{tenant}/modelStatus
The outcome of the latest load of the tenant's data model — see Loading a model.
{
"state": "REFUSED",
"checkedAt": "2026-09-28T08:12:44.201Z",
"errors": [
{
"severity": "ERROR",
"file": "employmentAgreement.json",
"path": "/layouts/0/items/3/name",
"message": "Class 'my-project.employmentAgreement' has no field 'salry'"
}
],
"warnings": [
{
"severity": "INFO",
"file": "company.json",
"path": "/scripts/0/gateway",
"message": "Gateway 'CompanyRegister' is beta: its contract may still change and is not covered by the compatibility guarantee"
}
],
"upgradableFiles": 12
}
| Property | Description |
|---|---|
state | LOADED: the latest model is active. REFUSED: the latest model was refused and the previous one is still active. FAILED: the latest model was refused and there is no model to fall back on, so the tenant is unavailable. |
checkedAt | When the model was loaded. |
errors | Why the model was refused; empty when LOADED. |
warnings | Findings that do not refuse the model, with severity WARNING or INFO. |
upgradableFiles | The number of files written in an older definition format. When greater than 0, modelUpgrade has files to offer. |
Each issue names the file (relative to the repository root) and the path inside it as a
JSON pointer; path is empty when the finding is
about the file as a whole.
Reload model
POST /admin/{tenant}/reloadModel
Loads the tenant's data model again from its repository, for example after a change the platform was not notified of. The request waits for the load and returns the resulting model status:
200 OK— the new model loaded and is active;422 Unprocessable Entity— the new model was refused; the body lists the errors. The previously active model keeps serving the tenant, unless the state isFAILED.
With a webhook configured, a push to the repository reloads the model automatically; see Automatic reload via webhooks.
Model upgrade
GET /admin/{tenant}/modelUpgrade
Returns a zip (application/zip, as an attachment named for example acme-definition-format-1.zip)
with every file of the tenant's repository that is written in an older
definition format, converted to
the current one, plus UPGRADE-REPORT.md. Files have their paths relative to the repository root:
unzip the archive over the root of the repository, review the changes and commit them. See
Upgrading a repository.
A model that was refused for reference errors can still be upgraded; the report lists its errors.
Returns 422 Unprocessable Entity, with the errors, when the model's files cannot be read at all.
The zip is fetched with the same Authorization header as every other request, so a client that offers
it as a download fetches it first and then saves it; a plain link would not carry the token.
Rebuild
POST /admin/{tenant}/rebuild
Starts a full rebuild of the tenant's data. Returns 202 Accepted, or 409 Conflict if a rebuild is already running.
Interview needed. Explain what "rebuild" reconstructs, when it is needed (e.g. after a model change), and how to observe progress/completion.
Rebuild access control
POST /admin/{tenant}/rebuildAccessControl
Re-derives every ACL row for the tenant from the current accessControl definitions. See Rebuilding after a model change for when this is required and how it differs from the tenant-wide rebuild above.
Recalculate
POST /admin/{tenant}/{typeName}/recalculate
Recalculates formulas for all objects of a type. Returns 202 Accepted.
Interview needed. Document scope (this type only? dependents?), and how it differs from rebuild and sync.
Sync
POST /admin/{tenant}/{typeName}/sync
Starts a sync for a type. Returns 202 Accepted.
Interview needed. Clarify what sync synchronizes (external source? search index?), and how it differs from recalculate and rebuild.
Delete tenant data
DELETE /admin/{tenant}?name={name}&deleteTenant={bool}
Deletes a tenant's data, and optionally the tenant itself when deleteTenant=true.
Interview needed. Document the name parameter (why it is required alongside the path tenant), the deleteTenant flag, safeguards, and irreversibility.