API Reference

Posts API

The Posts API lets you create, retrieve, update, publish, and schedule blog posts programmatically. All endpoints require JWT authentication via the Authorization: Bearer token header.

Base URL
https://api.blogree.com/api

Post Object

All post endpoints return a Post object with the following fields:

{ "id": "post_xyz789", // Unique post ID "version": 3, // Content version (increments on update) "slug": "my-blog-post-title", // URL-friendly identifier "title": "My Blog Post Title", // Post title "excerpt": "Short summary...", // Optional excerpt for listings "body": { "html": "<h1>Title</h1><p>...</p>", "markdown": "# Title ...", "json": { "type": "doc", "content": [...] } // Tiptap JSON }, "meta": { "title": "SEO title for <head>", "description": "Meta description (160 chars)", "og_image": "https://cdn.example.com/og.jpg" }, "tags": ["AI blogging", "content automation"], "status": "published" | "draft" | "scheduled", "scheduled_at": "2026-04-10T09:00:00Z", // null if not scheduled "published_at": "2026-04-02T14:30:00Z", // null if not published "created_at": "2026-04-01T10:00:00Z", "updated_at": "2026-04-02T14:29:00Z", "deliveries": [ // Only in single-post responses { "site_id": "site_abc", "status": "delivered", "delivered_at": "..." } ] }

List Posts

GET/api/posts

Returns a paginated list of all posts in your account.

Query Parameters

ParameterTypeDefaultDescription
statusstringallFilter by: draft, scheduled, published
pageinteger1Page number for pagination
limitinteger20Results per page (max 100)
site_idstringFilter posts delivered to a specific site
searchstringFull-text search in title and body
tagstringFilter by tag name
GET /api/posts?status=published&limit=10&page=1 Authorization: Bearer eyJhbGci... // Response { "data": [ { ...Post }, { ...Post } ], "pagination": { "page": 1, "limit": 10, "total": 127, "pages": 13 } }

Get Single Post

GET/api/posts/:id
GET /api/posts/post_xyz789 Authorization: Bearer eyJhbGci... // Returns full Post object including deliveries array

Create Post

POST/api/posts

Creates a new post in draft state. To publish immediately, include "status": "published". To schedule, include "status": "scheduled" with scheduled_at.

POST /api/posts Authorization: Bearer eyJhbGci... Content-Type: application/json { "title": "10 Best AI Blogging Tools in 2026", "body": { "html": "<h1>Introduction</h1><p>AI blogging tools have...</p>", "markdown": "# Introduction AI blogging tools have..." }, "excerpt": "A comprehensive roundup of the top AI tools for bloggers in 2026.", "meta": { "title": "10 Best AI Blogging Tools in 2026 (Tested & Ranked)", "description": "We tested 30+ AI blogging tools. Here are the 10 best for SEO, automation, and multi-platform publishing in 2026.", "og_image": "https://cdn.myblog.com/ai-tools-2026.jpg" }, "tags": ["AI tools", "blogging", "content automation"], "status": "draft" // or "published" or "scheduled" }

Update Post

PATCH/api/posts/:id

Partially update any post field. Only include fields you want to change. Each update increments the post's version field.

PATCH /api/posts/post_xyz789 Authorization: Bearer eyJhbGci... { "title": "Updated Title Here", "meta": { "description": "Updated meta description" } } // Returns updated Post object

Delete Post

DELETE/api/posts/:id

Permanently deletes a post. This cannot be undone. Published deliveries are not removed from connected sites (you must remove those manually).

DELETE /api/posts/post_xyz789 Authorization: Bearer eyJhbGci... // Response: 204 No Content

Publish Post

POST/api/posts/:id/publish

Triggers immediate delivery of the post to all specified sites. If site_ids is omitted, delivers to all connected sites.

POST /api/posts/post_xyz789/publish Authorization: Bearer eyJhbGci... { "site_ids": ["site_abc123", "site_def456"] // optional, omit for all sites } // Response { "post_id": "post_xyz789", "dispatched_to": [ { "site_id": "site_abc123", "status": "pending" }, { "site_id": "site_def456", "status": "pending" } ], "estimated_delivery": "2026-04-02T14:31:00Z" }

Generate Post with AI

POST/api/posts/generate

Triggers AI generation of a full SEO blog post based on a topic or keyword. The post is created in draft state for review before publishing.

POST /api/posts/generate Authorization: Bearer eyJhbGci... { "topic": "How to use AI for content marketing in 2026", "site_id": "site_abc123", // used to tailor to site's niche "length": "long", // short (~800w), medium (~1500w), long (~2500w) "tone": "professional", // professional, casual, educational, persuasive "include_faq": true, "target_keywords": ["AI content marketing", "content automation 2026"] } // Response (async — poll for completion) { "job_id": "gen_job_12345", "status": "processing", "poll_url": "/api/posts/generate/gen_job_12345", "estimated_seconds": 15 }
// Poll for completion: GET /api/posts/generate/gen_job_12345 // When complete: { "job_id": "gen_job_12345", "status": "complete", "post": { ...full Post object in draft status } }

Error Responses

// 400 Bad Request { "error": "validation_error", "message": "title is required", "field": "title" } // 401 Unauthorized { "error": "unauthorized", "message": "Invalid or expired JWT token" } // 404 Not Found { "error": "not_found", "message": "Post post_xyz789 not found" } // 429 Rate Limited { "error": "rate_limited", "message": "Too many requests", "retry_after": 60 } // 500 Internal Server Error { "error": "internal_error", "message": "An unexpected error occurred", "request_id": "req_abc123" }