API Documentation
Complete reference for the Writer API. All endpoints are self-discoverable at /api.
Authentication
Protected endpoints require the X-Auth-Token header:
X-Auth-Token: your-auth-token-here
Get your token from the onboarding page (first time only). The token is not returned by GET /api/settings for security.
Public Endpoints
GET /api
Returns this API documentation in JSON format.
GET /api/posts
List all published blog posts with pagination. Drafts are never included.
Query Parameters:
page- Page number (default: 1)limit- Posts per page (default: 10, max: 100)
curl http://localhost:8080/api/posts?page=1&limit=5
GET /api/posts/:slug
Get a single published post by its URL slug. Drafts return 404 unless you provide a valid X-Auth-Token.
curl http://localhost:8080/api/posts/my-post-slug
GET /api/settings
Get blog settings (title, author, description, show_docs). The auth_token field is intentionally omitted.
curl http://localhost:8080/api/settings
GET /feed.xml
RSS 2.0 feed with up to 20 published posts.
Protected Endpoints
These require a valid X-Auth-Token header.
POST /api/posts
Create a new blog post.
Required: title, body
Optional: tags (array), cover_image (URL), status (draft or published)
curl -X POST http://localhost:8080/api/posts \
-H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_TOKEN" \
-d '{"title": "My Post", "body": "Content here", "tags": ["tech"], "status": "published"}'
Auto-generated: slug, keywords, meta_description, reading_time, excerpt
PUT /api/posts/:slug
Update an existing post. Only include fields you want to change.
curl -X PUT http://localhost:8080/api/posts/my-post-slug \
-H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_TOKEN" \
-d '{"title": "New Title"}'
DELETE /api/posts/:slug
Delete a post by its slug. This action requires confirmation.
curl -X DELETE http://localhost:8080/api/posts/my-post-slug \
-H "X-Auth-Token: YOUR_TOKEN"
Response:
{
"confirmation_required": true,
"confirmation_url": "/api/confirm/abc123..."
}
PUT /api/settings
Update blog settings.
Optional: title, author, description, custom_scripts, show_docs
curl -X PUT http://localhost:8080/api/settings \
-H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_TOKEN" \
-d '{"title": "New Title", "author": "New Author", "show_docs": true}'
PUT /api/settings/credentials
Update the admin username and password. Send an empty password to keep the current one.
curl -X PUT http://localhost:8080/api/settings/credentials \
-H "Content-Type: application/json" \
-H "X-Auth-Token: YOUR_TOKEN" \
-d '{"username": "admin", "password": "newpass"}'
POST /api/settings/rotate-token
Rotate the auth token. This action requires confirmation. Any application using the old token will lose access.
curl -X POST http://localhost:8080/api/settings/rotate-token \
-H "X-Auth-Token: YOUR_TOKEN"
Response:
{
"confirmation_required": true,
"confirmation_url": "/api/confirm/abc123..."
}
POST /api/confirm/:token
Confirm a pending destructive action. Use the confirmation_url returned by the original request. Confirmation tokens expire after 10 minutes.
curl -X POST http://localhost:8080/api/confirm/abc123... \
-H "X-Auth-Token: YOUR_TOKEN"
Expired/invalid token response: 410 Gone
Confirmation Flow Example
Deleting a post is a two-step process:
# Step 1: Request deletion → get confirmation URL
curl -X DELETE http://localhost:8080/api/posts/my-post \
-H "X-Auth-Token: YOUR_TOKEN"
# Response:
# {
# "confirmation_required": true,
# "confirmation_url": "/api/confirm/abc123..."
# }
# Step 2: POST the confirmation URL
curl -X POST http://localhost:8080/api/confirm/abc123... \
-H "X-Auth-Token: YOUR_TOKEN"
# Response:
# { "message": "Post deleted successfully", "slug": "my-post" }
Response Examples
Post Object
{
"id": "uuid",
"title": "My Post",
"slug": "my-post",
"body": "Content...",
"bodyHtml": "<p>Content...</p>",
"excerpt": "First 200 chars...",
"cover_image": "",
"keywords": ["keyword1", "keyword2"],
"meta_description": "Meta description...",
"reading_time": 2,
"status": "published",
"tags": ["tech"],
"created_at": "2026-04-08T12:00:00Z",
"updated_at": "2026-04-08T12:00:00Z"
}
Settings Object
{
"title": "Writer",
"author": "John Doe",
"description": "A blog about tech",
"onboarding_complete": true,
"show_docs": true,
"hasPassword": true
}
Security Notes
- All web forms (login, settings, logout) include CSRF tokens. Do not use the web UI endpoints programmatically.
- Draft posts are never returned by public API endpoints.