---
title: "Create a blog post"
method: POST
path: "/blog/posts"
tags: ["Blog posts"]
---

# Create a blog post

`POST /blog/posts`

## Request

- Base URL: `https://api.cavuno.com/v1`
- URL: `https://api.cavuno.com/v1/blog/posts`
- Auth: HTTP bearer

Creates a blog post. New posts default to `status: "draft"`; publish explicitly via `POST /v1/blog/posts/{id}/publish`. The `html` body is sanitized server-side.

## Request body

- CreateBlogPostBody
  - `slug` string
  - `html` string
  - `customExcerpt` string
  - `readingTimeMin` integer
  - `featured` boolean
  - `authorIds` string[]
  - `tagIds` string[]
  - `coverMediaId` string, nullable
  - `ogImageMediaId` string, nullable
  - `featureImageAlt` string
  - `featureImageCaption` string
  - `seoTitle` string
  - `seoDescription` string
  - `canonicalUrl` string, uri
  - `publishedAt` string, date-time
  - `title` string, required
  - `status` 'draft' | 'scheduled' | 'published'

## Response `201`

Successful response.

- BlogPost
  - `id` string, required: Unique identifier for the object. Use this value as the `{id}` path parameter for the blog-post endpoints (e.g. `GET /v1/blog/posts/{id}`).
  - `object` 'blog_post', required
  - `title` string, required
  - `slug` string, required
  - `status` string, required
  - `visibility` string, required
  - `type` string, required
  - `featured` boolean, required
  - `authorIds` string[], required
  - `tagIds` string[], required
  - `coverUrl` string, nullable, required
  - `ogImageUrl` string, nullable, required
  - `featureImageAlt` string, nullable, required
  - `featureImageCaption` string, nullable, required
  - `customExcerpt` string, nullable, required
  - `readingTimeMin` number, nullable, required
  - `seoTitle` string, nullable, required
  - `seoDescription` string, nullable, required
  - `canonicalUrl` string, nullable, required
  - `publishedAt` string, nullable, required
  - `createdAt` string, required
  - `updatedAt` string, nullable, required
  - `html` string, nullable, required

## Other responses

- `400`: The request was malformed.

## Changes

- **2026-10-19** `c34152c38176`: 1 info
  - added the optional property `error/upgrade` to the response with the `400` status

[Operation history](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/changes/blog/posts/post.md)

---

[API](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api.md) · [All operations](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/llms.txt) · [OpenAPI document](https://skmtc.dev/cavuno/apis/cavuno-v1-rest-api/revisions/d5974dabff14?raw)
