Blog Builder API
Blog Builder API and AI connector.
Read and change posts, pages, pictures, menus and settings from your own code, or write with Claude or ChatGPT. Every blog has both built in, running on your own Cloudflare account.
1Get started
Blog Builder is built on EmDash, the MIT-licensed blogging software, and the API is EmDash's. It lives on your own blog:
https://blog.yourdomain.co.uk/_emdash/api
- Open API TokensSign in to your blog's admin and open Settings › API Tokens.
- Make a tokenGive it a name, tick what it may do and copy it. It's shown once, and starts with
ec_pat_. - Send it with each requestIn an Authorization header, like this:
curl "https://blog.yourdomain.co.uk/_emdash/api/content/posts?limit=5" \ -H "Authorization: Bearer ec_pat_••••••••••••••••••••••••••••"
2Tokens and permissions
Make a separate token for each script or app. Each one only does what you ticked, so a script that reads posts can't publish or delete them. The main ones are:
| Permission | What it allows |
|---|---|
content:read | Read posts and pages. |
content:write | Make and change posts and pages. |
content:publish | Publish and unpublish them. |
media:read, media:write | See and upload pictures and files. |
menus:manage, taxonomies:manage | Change menus, categories and tags. |
settings:read, settings:manage | Read and change the blog's settings. |
Deleting a token in Settings › API Tokens stops it straight away.
3Every request
The full list, with every field, is in the blog's own OpenAPI description, so developers can generate code from it or open it in tools such as Postman:
https://blog.yourdomain.co.uk/_emdash/api/openapi.json
| Request | What it does |
|---|---|
GET /content/{collection} | A page of posts or pages. The collection is posts or pages. |
GET /content/{collection}/{id} | One post or page in full. |
POST /content/{collection} | Makes a new draft. |
PUT /content/{collection}/{id} | Changes a post or page. |
POST /content/{collection}/{id}/publish | Publishes it. |
GET /search?q=… | Searches the blog. |
GET /media | Pictures and files. Upload with POST /media. |
GET /menus | The blog's menus. |
GET /settings | The blog's settings. |
4Examples
Read the five newest posts
curl "https://blog.yourdomain.co.uk/_emdash/api/content/posts?limit=5" \ -H "Authorization: Bearer $BLOG_TOKEN"
Answers come back as {"success": true, "data": …}.
In JavaScript
const res = await fetch(`${BLOG_API_URL}/content/posts?limit=5`, {
headers: { Authorization: `Bearer ${process.env.BLOG_TOKEN}` },
});
const body = await res.json();
if (!body.success) throw new Error(body.error.message);
console.log(body.data);5Webhooks
Blog Builder doesn't send webhooks yet. To act when you publish, ask the API for recent posts on a schedule, or use the blog's RSS feed.
6AI connector
Add your blog to Claude, ChatGPT or any MCP client at:
https://blog.yourdomain.co.uk/_emdash/api/mcp
It signs in through your blog, and you choose what it may do. Then say things like “draft a post about…” or “fix the typos in my last post”. Step by step: Connect Claude.
7Errors and limits
Anything that goes wrong comes back with a status and a code and message:
{"success": false, "error": {"code": "INSUFFICIENT_SCOPE", "message": "Token lacks required scope: content:write"}}| Status | What it means |
|---|---|
400 | Something in the request needs fixing. |
401 | No token, or one that has been deleted. |
403 | The token doesn't have the permission this needs. The message says which. |
404 | Not found. |
429 | Too many requests. Wait a little and try again. |
Keep tokens on your server or in your scripts, never in a web page.
Questions or ideas? Ask in GitHub Discussions, or open an issue for a bug.
Stay in the loop
Subscribe for updates.
Leave your email and I'll tell you when there's a new version of one of my apps, or a new project to try. Nothing else.