Skip to content
On this page

Blog API ​

The Blog API covers the modular content system used for posts, categories, tags, comments, reactions, bookmarks, views, translations, and SEO support.

This page is written to help developers understand the moving parts quickly, not just memorize endpoints.

How to read this page ​

Each route is documented like a normal operation page:

  • what it does
  • who can call it
  • the relevant request shape
  • a concrete response example

Base path ​

All routes live under /api/v1/posts.

What the API is for ​

  • Reading and listing posts
  • Creating and updating posts
  • Managing categories and tags
  • Handling comments and moderation
  • Tracking reactions, bookmarks, views, and stats
  • Supporting translations and SEO routes

Route map ​

MethodPathAuthPurpose
GET/api/v1/postsOptionalList posts with filters and pagination
GET/api/v1/posts/authors/:idPublicGet author profile
GET/api/v1/posts/:slugOptionalRead one post by slug
GET/api/v1/posts/id/:idOptionalRead one post by id
POST/api/v1/postsSession + writer roleCreate a post
PUT/api/v1/posts/:idSession + owner/adminUpdate a post
DELETE/api/v1/posts/:idSession + owner/adminDelete a post
POST/api/v1/posts/:id/publishSession + owner/adminPublish a draft
POST/api/v1/posts/:id/unpublishSession + owner/adminReturn a post to draft
POST/api/v1/posts/:id/scheduleSession + owner/adminSchedule a post
POST/api/v1/posts/:id/restoreSession + adminRestore a soft-deleted post
POST/api/v1/posts/:id/featured-imageSession + owner/adminUpload featured image
DELETE/api/v1/posts/:id/featured-imageSession + owner/adminDelete featured image
GET/api/v1/posts/categoriesPublicList categories
POST/api/v1/posts/categoriesSession + adminCreate a category
PUT/api/v1/posts/categories/:idSession + adminUpdate a category
DELETE/api/v1/posts/categories/:idSession + adminDelete a category
GET/api/v1/posts/tagsPublicList tags
POST/api/v1/posts/tagsSession + adminCreate a tag
PUT/api/v1/posts/tags/:idSession + adminUpdate a tag
DELETE/api/v1/posts/tags/:idSession + adminDelete a tag
GET/api/v1/posts/:id/commentsOptionalList comments
POST/api/v1/posts/:id/commentsConditionalCreate a comment
GET/api/v1/posts/:id/reactionsOptionalRead reaction counts
POST/api/v1/posts/:id/reactionsSessionAdd or toggle a reaction
POST/api/v1/posts/:id/bookmarkSessionBookmark a post
GET/api/v1/posts/me/bookmarksSessionList bookmarks
POST/api/v1/posts/:id/viewPublicTrack a view
GET/api/v1/posts/:id/statsOptionalRead aggregated stats
GET/api/v1/posts/seo/sitemap.xmlPublicGenerate the sitemap

Route details ​

Posts ​

GET /api/v1/posts/authors/:id ​

Get one public author profile by id.

Auth: public.

GET /api/v1/posts ​

List posts with pagination and filters.

Auth: optional.

Returns: a paginated list of posts.

Query params:

  • page
  • limit
  • sort
  • order
  • status
  • visibility
  • category
  • tag
  • author
  • q
  • lang

Example response:

json
{
  "data": [],
  "user_context": {
    "authenticated": false
  },
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 0,
    "hasMore": false
  }
}

GET /api/v1/posts/:slug ​

Read one post by slug.

GET /api/v1/posts/id/:id ​

Read one post by id.

POST /api/v1/posts ​

Create a new post.

Auth: session + writer role.

Required body fields:

  • title
  • slug
  • body
  • body_format
  • visibility

Optional body fields:

  • excerpt
  • comments_enabled
  • reactions_enabled
  • scheduled_at

PUT /api/v1/posts/:id ​

Update an existing post.

Auth: session + owner/admin.

DELETE /api/v1/posts/:id ​

Delete a post.

Auth: session + owner/admin.

POST /api/v1/posts/:id/publish ​

Publish a draft post.

Auth: session + owner/admin.

POST /api/v1/posts/:id/unpublish ​

Return a published post to draft.

Auth: session + owner/admin.

POST /api/v1/posts/:id/schedule ​

Schedule a post for later publishing.

Auth: session + owner/admin.

POST /api/v1/posts/:id/restore ​

Restore a previously soft-deleted post.

Auth: session + admin.

POST /api/v1/posts/:id/featured-image ​

Upload featured image using multipart form-data.

Auth: session + owner/admin.

Delete the current featured image.

Auth: session + owner/admin.

Categories and tags ​

GET /api/v1/posts/categories ​

List categories.

Auth: public.

POST /api/v1/posts/categories ​

Create a category.

Auth: session + admin.

PUT /api/v1/posts/categories/:id ​

Update a category.

Auth: session + admin.

DELETE /api/v1/posts/categories/:id ​

Delete a category.

Auth: session + admin.

GET /api/v1/posts/tags ​

List tags.

Auth: public.

POST /api/v1/posts/tags ​

Create a tag.

Auth: session + admin.

PUT /api/v1/posts/tags/:id ​

Update a tag.

Auth: session + admin.

DELETE /api/v1/posts/tags/:id ​

Delete a tag.

Auth: session + admin.

Comments ​

GET /api/v1/posts/:id/comments ​

List comments for a post.

Auth: optional.

POST /api/v1/posts/:id/comments ​

Create a comment.

Auth: conditional.

PUT /api/v1/posts/:id/comments/:commentId ​

Update a comment.

Auth: session.

DELETE /api/v1/posts/:id/comments/:commentId ​

Delete a comment.

Auth: session.

POST /api/v1/posts/comments/:commentId/moderate ​

Moderate a comment.

Auth: session + moderator/admin.

Engagement ​

GET /api/v1/posts/:id/reactions ​

Read reaction counters for one post.

Auth: optional.

POST /api/v1/posts/:id/reactions ​

Add or toggle a reaction.

Auth: session.

POST /api/v1/posts/:id/bookmark ​

Bookmark a post.

Auth: session.

DELETE /api/v1/posts/:id/bookmark ​

Remove a bookmark.

Auth: session.

GET /api/v1/posts/me/bookmarks ​

List current user bookmarks.

Auth: session.

POST /api/v1/posts/:id/view ​

Track a view.

Auth: public.

GET /api/v1/posts/:id/stats ​

Read aggregated stats.

Auth: optional.

Translations and SEO ​

GET /api/v1/posts/id/:id/translations ​

List translations for a post.

Auth: optional.

POST /api/v1/posts/id/:id/translations ​

Create a translation.

Auth: session + writer role.

PUT /api/v1/posts/id/:id/translations/:lang ​

Update a translation.

Auth: session + owner/admin.

DELETE /api/v1/posts/id/:id/translations/:lang ​

Delete a translation.

Auth: session + owner/admin.

GET /api/v1/posts/seo/sitemap.xml ​

Generate the SEO sitemap.

Auth: public.

Response shape ​

Most blog routes use a consistent envelope:

json
{
  "data": {},
  "user_context": {
    "authenticated": true
  },
  "meta": {}
}

Why that matters ​

  • data holds the useful payload.
  • user_context explains how the response was interpreted for the current viewer.
  • meta carries pagination and query information.

Example: list posts ​

http
GET /api/v1/posts?page=1&limit=10&sort=created_at&order=desc

Example response:

json
{
  "data": [
    {
      "id": "post_1",
      "slug": "hello-world",
      "title": "Hello World",
      "body": "# Hello",
      "status": "published",
      "visibility": "public"
    }
  ],
  "user_context": {
    "authenticated": false
  },
  "meta": {
    "page": 1,
    "limit": 10,
    "total": 1,
    "hasMore": false
  }
}

Example: create a post ​

http
POST /api/v1/posts
Content-Type: application/json

{
  "title": "Why modular docs matter",
  "slug": "why-modular-docs-matter",
  "body": "# Why modular docs matter",
  "body_format": "markdown",
  "visibility": "public",
  "comments_enabled": true
}

Example response:

json
{
  "data": {
    "id": "post_2",
    "slug": "why-modular-docs-matter",
    "status": "draft"
  },
  "user_context": {
    "authenticated": true,
    "user_type": "writer"
  },
  "meta": {
    "cached": false
  }
}

Typical flow ​

  1. List posts publicly.
  2. Create or edit a post as an authenticated writer.
  3. Publish or schedule the post.
  4. Allow comments and reactions if enabled.
  5. Use stats and bookmarks for engagement.

Practical notes ​

  • The API is easiest to understand when you think in layers: content, moderation, engagement, and metadata.
  • Use the response envelope to keep frontend code predictable.
  • Treat publish and schedule as workflow actions, not just CRUD operations.

Next ​