by Rogerio Taques

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.