For a decade, Grav has had exactly one front door for managing a site. If you wanted to change something, you either edited the files by hand or you opened the admin plugin. And the admin was welded to the same rendering pipeline that served the public site, which is part of why it worked so well for so long, but it also meant there was no clean way for anything else to manage a Grav site. No way for a script to do it, no way for a different admin to do it, no way for an AI to do it. The files were open, but the management was locked to one tool.
That's the thing Grav 2.0 changes, and it's the change everything else in this release is built on. We pulled site management out of the admin and into a proper first-party REST API. The API ships as part of the 2.0 package, it speaks JSON over HTTP, and it does everything: pages, media, configuration, users, plugins, themes, backups, the lot. The files are still the source of truth, nothing about that changed. What changed is that there's now a clean, documented way to read and write them that isn't tied to one particular screen.
One Door Becomes Many
Here's why that matters, and it's the whole idea behind 2.0. Once management lives behind an API, the admin is just one of the things that can talk to it. So is an AI agent. So is your build script.
- Admin Next, the new admin, is a client. It's a single-page app that does everything through the API. The post after this one is a full tour of it.
- The MCP server is a client. It lets an AI agent manage your site through the same API, with the same permissions a person would have. That post comes later in the series.
- Your own tooling is a client. A deploy script, a CI job, a content importer, a mobile app: anything that can make an HTTP request can manage a Grav site now.
Same API underneath all of them. Same authentication, same permissions, same rules. We didn't build one feature with an API bolted to the side. We built the API, and then built the admin and the AI integration on top of it like anybody else would. If it's good enough to run the whole admin, it's good enough for whatever you want to point at it.
What It Actually Does
The API covers the same ground the admin always has, just reachable over HTTP:
- Pages. Read, create, edit, move, copy, and delete pages, including their frontmatter and content. Reorder them, manage the media attached to each one.
- Media. Upload, browse, and delete both page media and site-level media.
- Configuration. Read and write system, site, plugin, and theme config.
- Users. Full account management, plus roles and permissions.
- Plugins and themes. Install, update, and remove through GPM, and manage their config.
- The system itself. Cache, backups, logs, the scheduler, and diagnostic reports.
A request looks about as plain as you'd hope. Here's the whole thing for listing pages:
curl https://mysite.com/api/v1/pages \
-H "X-API-Key: grav_your_key_here"
And the response is just JSON, with a predictable shape:
{
"data": [ ... ],
"meta": { "total": 42, "page": 1, "per_page": 20 }
}
No surprises, no bespoke envelope to decode. Lists are paginated, errors come back as proper RFC 7807 problem responses, and writes use ETags so two clients editing the same page can't silently clobber each other. It behaves the way you'd want a modern API to behave.
Built Like a Real API, Not a Hatch
It would have been easy to expose a thin, half-secured hatch into Grav and call it an API. We didn't, because the admin and an AI agent were both going to depend on it, so it had to be solid from day one.
Authentication has three modes, and you pick the one that fits. API keys for servers, scripts, and the MCP server (generate one with bin/plugin api keys:generate). JWT tokens for browser and mobile apps. And session passthrough, so a logged-in admin session just works. Whichever you use, the API checks the same permission system the rest of Grav uses. An API key acts as a specific user and can do exactly what that user can do, no more. There's no separate, parallel set of API permissions to keep in sync.
On top of that you get the things that make an API safe to leave running: per-user rate limiting, configurable CORS, webhooks that fire on changes (HMAC-signed, with delivery logs and automatic retries), and full environment support so you can point a request at staging or production. None of it is something you bolt on later. It's there in the box.
It's Not Just for the Admin
This is the part I'm most excited about, because it turns Grav from a CMS into something closer to a platform.
Because content and config are reachable as clean JSON, Grav can be a headless backend. Point a React, Vue, or Next.js frontend at the API and let Grav handle the content while your frontend handles the presentation. Feed a static site generator from it. Wire it into CI/CD so a pipeline can push content changes as part of a deploy. Back a mobile app with it. Drive bulk content jobs from a script instead of clicking through forms.
And it's extensible. Your own plugin can add its own endpoints to the same API, with the same authentication and permission checks it gets for free, so a plugin's data and actions become reachable by every one of those clients too. That's a developer topic in its own right, and it's already written up in API Integration for Plugins if you want the code.
The point is that "manage a Grav site" stopped being something only the admin could do. Now it's something anything can do, safely, through one interface.
What's Next
The API isn't new code we're nervously shipping. It's been the foundation Admin Next was built on through the entire beta and RC cycle, so it's had months of real mileage driving an actual admin before it ever reached you. Full reference documentation lives on the Learn site.
In the next post, we'll get into the thing most of you will actually spend your day in: Admin Next, the new admin, and everything it does on top of this foundation.
Quick Links and Help
- The 2.0 release post: Introducing Grav 2.0.
- The new admin built on this API: Admin Next.
- AI through the same API: The MCP Server.
- For developers, adding your own endpoints: API Integration for Plugins.
- The full API reference: learn.getgrav.org.
- Discord: chat.getgrav.org if you want to talk through a headless or integration idea.
Andy
Important
Next in the series: Admin Next: A Modern Admin Experience