Beta . Ortha CMS is in public beta. Every plan is free until it ends.
Features Ortha CMS on GitHub

Glossary

The terms that mean something specific here, including two that mislead.

Documents 0.13.1 Updated Edit this page Report a problem

Admin API — everything under /api/ without the v1 prefix. The admin application’s own API, authenticated with a session cookie and enforcing per-user RBAC. Not versioned, and not what you build an integration against.

Alarm — a workspace rule that flags content problems without ever blocking a write: a content type, a saved records-list filter, and a severity. Its verdict about one entry is a finding.

API token — a long-lived bearer credential for the public API, minted in the admin. Scoped read or full, and bucketed to a set of workspaces.

Archived workspace — a workspace taken out of sight: hidden from the sidebar’s quick list, the command palette and Home, and shown under the Archived filter of Workspaces. It deletes nothing and gates nothing — its content is still read and written over the API as before — and Restore brings it back. Since 0.13.0 the admin asks first, saying what stays and how many workspaces linking its shared records will see them as unavailable.

Bucket — the set of workspaces an API token may act in. A request picks one with X-Workspace-Id.

Collection — a content type with many entries. Declared with collection().

Content manifest — apps/server/src/content/index.ts, the generated file that lists every content type for ContentPlugin and re-exports every table for drizzle-kit. Written by orthacms content sync or the schema builder, never by hand.

Copilot — the code name for Ortha CMS AI, the assistant in the admin: the copilot-* packages, the copilot:* permissions and the /api/copilot routes. It acts with exactly its user’s permissions, asks in the chat before a write is applied, and cannot publish or approve.

Dead letter — an outbox event that failed delivery fifteen times and is no longer claimed, most often an activity row that was never written. Listed at GET /api/activity/dead-letters and put back in the queue one at a time with the retry route, which needs activity:manage. The admin’s Retry all retries the rows its dialog shows through that same route, one at a time.

Delivery — one attempt series to POST one event to one webhook endpoint. Has its own id (X-Orthacms-Delivery, new on every redelivery) and a status: pending, delivering, succeeded, failed (another attempt is scheduled) or dead.

Domain event — an immutable record that something happened, appended to the outbox in the same transaction as the change that raised it.

Envelope — the platform-owned columns every entry carries: id, workspace_id, created_at, updated_at, plus the flag-gated status, published_at, deleted_at, locale and locale_group_id. Also the JSON body of a webhook delivery, which carries references to the record rather than its values.

Event id — the outbox event’s id, carried on every webhook delivery as X-Orthacms-Event-Id and as eventId in the body. Stable across retries and redeliveries, which is what makes it the key a receiver deduplicates on.

Finding — one alarm rule’s verdict about one entry. Keyed (rule, entry), so a repeat evaluation is a no-op; firstSeenAt survives it resolving and re-opening.

Host — the application shell that turns a plugin list into a running app. There are two, one per runtime, and they own no domain logic.

Insights signal — one line of the Needs attention card that opens the Insights page: a count, a tone and a hint, contributed through INSIGHTS_SIGNAL_SLOT, and a drill-down panel listing the records behind it. New in 0.13.0, where Waiting to go live, Gone quiet, Waiting on review and Images missing alt text moved from cards to lines.

Locale group — the set of rows that are translations of each other, sharing a locale_group_id. A record in one language is one row of a group.

Localized field — a field marked localized: true, whose value differs per language. A field without the flag is shared across the whole group.

Mirrored relation — a relation on a localized type whose target is also localized, so a synced link resolves to the target’s row in each sibling’s own language.

Modified — an entry that was published and has been saved since. Not a stored value: it is status = 'draft' with a non-null published_at. The delivery API (REST, GraphQL, MCP) keeps serving its last published version until it is published again — since 0.7.0; before, it disappeared from reads.

Outbox — the table domain events are appended to, outbox_events, inside the transaction of the change that raised them, then dispatched to subscribers after commit. Internal to the process, and the only table the shared database plugin owns. Delivered rows are pruned after OUTBOX_RETENTION_DAYS, 30 by default.

Ownership marker — // @orthacms-generated as the first line of a type file. The schema builder edits only files that carry it; adding the line hands a hand-written type over, deleting it takes the type back.

Paranoid — a content type with soft delete. Deleting stamps deleted_at rather than removing the row.

Password recovery — the public “forgot your password” request (/api/auth/password-recovery), new in 0.13.0. It exists only with a mail provider, answers the same whether or not the address belongs to anyone, and mails a single-use reset link; without one, a reset is still started by an admin.

Plugin — a unit of capability. Admin plugins contribute routes and slot items; server plugins contribute a NestJS module and optionally schema and migrations.

Port — a Symbol token plus an interface, declared by the plugin that wants extending and bound by the one providing the behaviour. The server-side counterpart of a slot.

Form group — a collapsible section of the entry form, declared in a type’s groups and joined by a field’s admin.group. Presentation only. See content types.

Properties panel — the entry editor’s panel of record details: the publish gate, Details (status, dates, id), and blocks plugins add. Since 0.12.0 it opens over the form on demand (⌘.) and can be pinned beside it. Nothing needed to decide a save or a publish lives only there.

Propose tool — an agent tool that computes a change and hands it back rather than writing it. The run engine records the change and applies it. One that declares previewable has no side effects, so the copilot can run it once before asking and show the change on the permission prompt.

Publish gate — the check run before an entry goes live: every required field present, every present value valid.

Protection rule — a per-content-type rule requiring a number of approvals before an entry of that type may be published. One row per (workspace, content type); with no row the type publishes as it always did.

Reachable type — a content type a workspace can read: it holds an own grant for it, or a shared grant whose source is still shared and active. A required relation to an unreachable type is not required in that workspace.

Reader tags — the tags naming who is reading, sent by your backend as X-Reader-Tags: premium, eu on public reads (renamed with SEGMENTS_READER_TAGS_HEADER). Matched against segments.

Resolve-from-source — workspace packages are consumed straight from src/index.ts with no build step.

Review approval — one person’s vote on one revision, not on the entry. A later save moves the head, so the approval stops counting without being deleted — the editor shows it struck through, naming the version it was given on.

Revision — an immutable snapshot of a whole entry, written inside the transaction of the save that produced it.

Saved view — a named slice of a collection’s list: filter, sort and columns. Private to its author, or shared with the workspace by someone holding views:share.

Schema builder — the admin’s Content Model page and its plugin. Shows the content model everywhere; in development only, edits it by writing type files and a drizzle-kit migration. Never a runtime schema.

Segment — a named reader audience: a set of tags a reader may arrive carrying. An entry names the segments it admits and the segments it refuses; a deny wins, and an empty allow list means everyone. Decides who may read published content, never who may edit it.

Shared grant — a workspace’s grant of one content type from a named shared workspace (“Tags · Travel Library”), as opposed to an own grant. A row in workspace_content with a source_workspace_id. New in 0.7.0.

Shared workspace — a workspace flagged isShared whose published records other workspaces may read and link to, read-only, once they take a shared grant. See shared workspaces.

Single — a content type with exactly one entry, declared with single(). Requires a path.

Skill — a named instruction packet for the copilot, with a description of when it applies. Reaches the model only through the system prompt.

Slot — a named UI extension point one plugin defines and others contribute into as data, wired once at boot.

Status item — one thing the entry editor’s header reports beyond the save state: a field that blocks publishing, a guard’s refusal, or a plugin’s report through ENTRY_STATUS_ITEM_SLOT. Severity blocking, warning or info; content draws at most two as chips.

Surfaces — which agent consumers a tool is offered to: copilot, mcp, or both. Omitting it means both.

Tool — a named, permission-gated capability an agent can invoke, held in one registry shared by the copilot and the MCP endpoint.

Unit of work — the transaction boundary. A nested run joins the outer transaction rather than opening a new one.

Webhook — an endpoint this installation POSTs to when an entry changes: a URL, a signing secret, and three filters (workspaces × event kinds × content types, where an empty set means everything). Queued from the outbox, sent by a worker, and logged per delivery. A delivery gets six attempts over about two and a half hours — waits of 10 seconds, 1 minute, 5 minutes, 30 minutes and 2 hours — and is marked dead when the sixth fails.

Workspace — a tenant or grouping. Content, media and copilot conversations belong to one. Membership is the M:N link deciding who can reach it.

Two terms that mislead

workspace_content is an access-control mapping — which content types a workspace has been granted, its own or from a shared source — and not content storage. Content lives in the generated content_<name> tables.

MCP points in two directions and they are different features. Ortha is an MCP server: an external agent connects to it. The copilot being an MCP client of your systems is a separate, planned thing that does not exist.