Documentation
89 pages. How content is modelled, delivered, extended and run — written against the source, and honest about where a feature stops.
Getting started
What Apograph is, how it is put together, and how to find your way around the codebase.
- What Apograph CMS is A plugin host, a code-defined content model, and a Postgres database you own — what that means in practice.
- Quick start From an empty directory to your first published entry, in one sitting.
- Installation Prerequisites, the two ways in, first boot, and upgrading afterwards.
- How Apograph is put together A host, two plugin contracts, one database connection, and the two ways plugins extend each other.
- Project structure Where everything lives in the monorepo, and which parts are yours to edit.
Modelling content
Content types in TypeScript, the fields and relations they carry, and the Postgres tables they become.
- Content types Two kinds of content type, the flags that shape their storage, and the table each one generates.
- Fields Twelve builders, what each one stores, and the options every one of them shares.
- Relations Four cardinalities out of two storage forms, and the inverse side that stores nothing at all.
- Rich text A node tree in a jsonb column, and the structural rules the server refuses to store a body without.
- Media fields How an entry points at library assets, and what restricts which ones it may point at.
- Localization One row per language, translation groups, and the difference between a shared field and a localized one.
- Publishing and deletion The states an entry moves through, and what publishing actually validates before it lets a row go live.
- Version history Every save is snapshotted, history is append-only, and restoring differs from publishing an old version.
- Validation One set of rules, applied by the server and mirrored by the admin form.
- Migrations Per-plugin migrations, generated from your schema and applied by the host in one command.
Working in the admin
The content library, the entry editor, media, translations and version history, from a developer’s side of the screen.
- The admin application The shape of the interface, and how the pieces you will use every day fit together.
- The content library Where content lives in the admin, and how to find one record among thousands.
- The entry editor A form generated from your content type, and the difference between saving and publishing.
- The rich-text editor What the editor can do, and the structural checks it runs while you write rather than after you save.
- The media library Where assets live, how they get there, and how they attach to a record.
- Translating content How a translation is created and edited, and which fields you are editing for every language at once.
- Version history Reading the timeline, comparing two versions, and the difference between restoring and publishing one.
- Insights and the activity log What the dashboard reports, and what the audit log does and does not record.
- Accessibility and theme What the admin commits to for accessibility, how it is verified, and where the gaps are.
- Export and import Moving content out of one Apograph and into another, without duplicating half of it.
Delivering content
The public REST and GraphQL APIs, the tokens that reach them, and how to query, filter and expand.
- The delivery API One public API in two protocols, reached with a bearer token scoped to a set of workspaces.
- API tokens Bearer tokens, the workspace bucket they cover, and the two scopes they come in.
- Reading entries Listing, fetching, searching, sorting, paging and sparse fieldsets on the public read endpoints.
- Filtering A JSON tree of and/or groups and rules, validated against the type's own schema.
- Expanding relations and media Opt-in expansion of relation and media fields, and how to page past the cap.
- Writing entries Create, update, publish and delete — including relation deltas and bulk saves that report per item.
- GraphQL The same API in a second protocol, with a schema built per workspace grant set.
- The media API Upload an asset, get its bytes back, and the reason those URLs are not public.
- Errors and status codes What each status means, and where two different causes answer identically on purpose.
- Front-end frameworks Where the token lives in each framework, and how to generate a typed client since there is no official one.
- Reacting to changes A receiver that verifies, deduplicates and answers fast — then invalidates a cache or rebuilds a site.
- Preview and drafts The rule behind ?status=draft, a preview route that never ships the token, and what the API actually caches.
AI and agents
Apograph AI in the product, the MCP endpoint external agents connect to, and the authority both are held to.
- AI in Apograph Two AI surfaces, one authority model, and an honest account of what it does and does not protect you from.
- Setting up the copilot The kill switch, the run ceilings, and what you get with no key and no network.
- Model providers Two adapters behind one port, and why a local model is a setting rather than a fork.
- Tools and permissions One registry, two surfaces, and the three points at which a tool call is checked.
- Skills Named instruction packets, declared in code or authored in the admin.
- The MCP endpoint The CMS as a tool provider, reached over the Model Context Protocol with an API token.
Plugins
Every plugin a deployment can register: what it does, what to install, and what it reads from the environment.
- Plugins Every plugin a deployment can register, and the two arrays that decide what your CMS is.
- Database plugin The connection, the transaction boundary, and the event outbox underneath everything else.
- Identity plugin Authentication, authorization, and the identity providers a deployment can reach.
- Workspaces plugin The tenancy boundary, and the guard the rest of the system borrows from it.
- Activity plugin The audit log, and why it is a subscriber rather than a second write.
- Users plugin Managing the people in a CMS — and the one thing this plugin deliberately does not do.
- Content plugin Content types, entries, revisions and publishing — plus the API that serves them.
- Saved views plugin Naming the slice of a collection an editor returns to, and sharing it.
- GraphQL plugin GraphQL over the content API — no schema, no credential, no permission of its own.
- Media plugin Where uploaded bytes go, which backend puts them there, and how they come back out.
- Localization plugin Translating content — and the one setting that decides what happens to a removed language.
- Transfer plugin Moving content out of one Apograph and into another — new in 0.4.0.
- Alarms plugin Declaring what a workspace considers wrong, without refusing anybody's save.
- Segments plugin Deciding who may read a published entry, enforced on every protocol.
- Protection plugin Requiring approvals before publication, without adding a workflow or a status.
- Webhooks plugin Telling other systems that an entry changed, without ever letting one of them stall the CMS.
- Copilot plugin The assistant in the admin — off until an operator says otherwise.
- MCP plugin One endpoint, one credential, and the same authority an API token already has.
- Shell plugin The frame every other admin plugin renders inside.
- Rich text plugin One slot contribution, and the document format behind every body field.
- Insights plugin The dashboard, and the slot that stops it becoming the module that knows everything.
- API tokens plugin The lifecycle of the credentials your delivery clients and agents present.
Extending Apograph
Writing a plugin: the two contracts, the extension points, the data layer and the test harnesses.
- Plugins The unit of capability in Apograph, and the two contracts a plugin implements.
- Server plugins The factory, the dynamic module, and how a plugin owns its own tables.
- Admin plugins Routes, layout and slot contributions, plus the data-layer conventions the admin expects.
- Slots Named extension points, the ones that ship, and the rule that makes them safe.
- Database access Getting at the database, and running work inside one transaction.
- Domain events and the outbox How a change raises an event that cannot outlive it, and what happens to that event afterwards.
- DI ports The server-side inversion that lets one plugin extend another with no dependency between them.
- Contributing agent tools Adding a capability an agent can call, and deciding which surfaces it is offered to.
- Testing a plugin The three test layers, what each is good at, and the harness each one gives you.
Running Apograph
Configuration, the database, media storage, and the security posture you are taking on by self-hosting.
- Deployment Getting Apograph onto your own infrastructure and keeping it there.
- Configuration The complete environment reference, and the two settings most often got wrong.
- Database and migrations What Apograph needs from Postgres, how migrations are applied, and which tables grow.
- Media storage Where uploaded bytes actually go, and the things to get right before production.
- Security The posture you are taking on by self-hosting, including the parts that are your job.
- Single sign-on Configuring an identity provider, and the defaults that decide what a sign-in can do.
- Upgrading Bump every @apograph/* package to one version, migrate forward, and know what each release changed.
- Troubleshooting Symptom, cause, fix — for the failures that look like bugs and are configuration.
Reference
The tables to look things up in — field types, permission keys, environment variables, endpoints and terms.
- Field type reference Every builder, its options, its column, and whether it can be filtered or sorted.
- Permissions and roles The complete permission catalogue, the role matrix, and how token scopes map onto it.
- HTTP endpoints Every route, grouped by surface, with what authenticates each one.
- Package map Every app and package, one line each, so you can find the right one quickly.
- Glossary The terms that mean something specific here, including two that mislead.
- Architecture decisions Seventeen records covering why the system is shaped the way it is.
- Command line The two binaries an installed app is built, run and migrated with.