Skip to main content
POST
/
posts
curl --request POST \
  --url https://api.buttercms.com/v2/posts/ \
  --header 'Authorization: <api-key>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "title": "This is a blog post",
  "slug": "this-is-a-blog-post",
  "status": "published",
  "author": {
    "email": "your@author.com"
  },
  "categories": [
    "Recipes",
    "Meals"
  ],
  "tags": [
    "Butter",
    "Sushi",
    "Really Good Recipes"
  ],
  "featured_image": "https://farm1.staticflickr.com/836/42903355654_8faa21171a_m_d.jpg",
  "featured_image_alt": "Featured image alt text example.",
  "body": "<h1>Butter</h1><p>I am so hungry!</p>",
  "summary": "This is a blog post summary.",
  "seo_title": "This is a blog post",
  "meta_description": "This is a blog post to test the API.",
  "upload_images_to_media_library": false
}
'
{
  "status": "pending"
}
Create a new blog post using the Write API with support for rich media, categorization, and automatic author assignment. This endpoint enables programmatic content creation for blogs, news sites, and content management workflows. Required Fields: Every blog post must include a title (post title) and slug (URL-friendly identifier). The slug must be unique across all posts in your organization and will become part of the post’s permanent URL. Author Management: The author must already exist in your ButterCMS account before creating posts. You can specify the author by email address or slug. If no author is specified, the post will be automatically assigned to your organization owner, ensuring every post has proper attribution. Dynamic Categorization: Categories and tags can be provided as string arrays in your request. If you specify categories or tags that don’t exist yet, they will be automatically created in your account, making it easy to expand your content taxonomy organically. Media Integration: Featured images are always uploaded to your ButterCMS media library for reliable hosting. For images within the post body content, set upload_images_to_media_library=true to automatically download and host external images through ButterCMS’s CDN infrastructure. Publication & Scheduling: Blog posts default to draft unless status=published is provided. Scheduling future publication is not supported via the Write API; scheduling-related fields will result in validation errors. Asynchronous Processing: This endpoint returns 202 Accepted immediately to ensure fast response times for your application. The actual post creation, including media processing, category creation, and webhook notifications, happens in the background processing queue.

Authorizations

Authorization
string
header
required

Write-enabled API token required for creating content.

The API token you use for reading from the ButterCMS API will not allow you to create content in the API. For this you will need to use a different write-enabled token. Chat or email support@buttercms.com to get yours.

Set the Authorization header to Token your_write_api_token.

Example: Authorization: Token abc123def456

Your write-enabled token should never be used anywhere it would be exposed, e.g. in client-side JavaScript.

Body

application/json

Request schema for creating a new blog post

title
string
required

The title of the blog post

Maximum string length: 200
Example:

"This is a blog post"

slug
string

The slug of the blog post (must be unique).

Auto-Generation: If not provided, the slug will be automatically generated from the title using unicode slugification. You can provide a custom slug or let the API generate one for you.

Maximum string length: 100
Example:

"this-is-a-blog-post"

status
enum<string>
default:draft

The status of the post. Defaults to 'draft'. Cannot be 'scheduled'.

Available options:
draft,
published
Example:

"published"

author
object

Author reference for blog posts. Author must exist in your account prior to POST.

You can specify the author either by email or by slug. If no author is specified, defaults to the organization owner.

categories
string[]

Array of category names. Categories will be created if they don't exist.

Example:
["Recipes", "Meals"]
tags
string[]

Array of tag names. Tags will be created if they don't exist.

Example:
["Butter", "Sushi", "Really Good Recipes"]

Can be a remote URL to an image.

The image will always be uploaded to the media library (the value of upload_images_to_media_library is ignored for featured images).

Example:

"https://farm1.staticflickr.com/836/42903355654_8faa21171a_m_d.jpg"

Alt text for the featured image

Maximum string length: 250
Example:

"Featured image alt text example."

body
string

Should be a string of escaped HTML.

In case it contains any remote URLs to images, the upload_images_to_media_library flag controls the behavior.

Example:

"<h1>Butter</h1><p>I am so hungry!</p>"

summary
string

Plain-text summary of the blog post

Maximum string length: 2000
Example:

"This is a blog post summary."

seo_title
string

SEO title for HTML title tag

Maximum string length: 100
Example:

"This is a blog post"

meta_description
string

Meta description for SEO and social sharing

Example:

"This is a blog post to test the API."

upload_images_to_media_library
boolean
default:false

Defaults to false.

If set to true, any image URLs in the body property will be uploaded to the Butter Media Library and the original URL will be replaced with the media library URL.

Note: Featured images are always uploaded regardless of this setting.

Example:

false

Response

Accepted - Post Creation Initiated

A validated POST request will return a response with HTTP status code 202. Full post creation occurs asynchronously, meaning a successfully created post may not show immediately.

Posts are validated prior to returning the API response but it is also possible that post creation may fail after returning a 202 response. If this happens please contact support.

Success response for blog post creation (202 Accepted)

status
enum<string>

Indicates that the blog post creation is being processed asynchronously

Available options:
pending
Example:

"pending"