Skip to main content
You can use the blog post API to publish and manage blog posts. Learn more about how to create and maintain your blog on the HubSpot Knowledge Base.

Changes in V3

  • The following properties are deprecated and will not be included in the response of any of the V3 endpoints:
    • campaign_name
    • is_draft
    • keywords
  • The topicIds property has been renamed to tagIds.

Retrieve blog posts

You can retrieve blog posts either individually by ID or by retrieving all blog posts:
  • To retrieve all blog posts, make a GET request to /cms/v3/blogs/posts.
  • To retrieve an individual blog post, make a GET request to /cms/v3/blogs/posts/{postId}.

Retrieve all blog posts

When retrieving all blog posts, you can filter and sort the returned results using query parameters. For example, the following request would retrieve the first 10 blog posts created after January 1, 2024:
The following query parameters are available: The response includes a total count and an array of blog post objects:
The authorName field returns the name of the user who most recently published the blog post, not the name of the blog author associated with the post. To get the blog author’s information, use the blogAuthorId field to look up the author via the blog authors API.

Retrieve a single blog post

To retrieve details for a specific blog post, make a GET request to /cms/v3/blogs/posts/{postId}. For example, the request below would retrieve the details for the blog post with ID 184993428780:
You can optionally include the property query parameter to return only specific properties.

Filtering

You can filter blog posts using query parameters. Provide the property name, followed by two underscore characters, then include the associated operator as a suffix. For example, you can filter the results to only include blog posts where the name property contains the word marketing using the parameter: &name__contains=marketing. The table below lists the properties that can be filtered on, along with their supported filter types.

Filtering by publish state

The currentState field on the blog post object is a generated field which also reflects the blog’s publish state, but you cannot use it as a property to filter against in your requests.

Filtering for multi-language posts

Sorting and paginating

You can provide sorting and pagination options as query parameters. Specify the property name as the value to the sort query parameter to return the blog posts in the natural order of that property. You can reverse the sorting order by including a dash character before the property name (e.g., sort=-createdAt). By combining query parameters for filtering, sorting, and pagination, you can retrieve blog posts that match more advanced search criteria. For example, the request below fetches blog posts that have a language assigned, ordered by the most recently updated, and returns the second page of results:

Create a blog post

To create a new blog post, make a POST request to /cms/v3/blogs/posts. For example, the request below would create a new draft blog post:
The following request body parameters are available: By default, the post will be created as an unpublished draft. If needed, a blog post can be published at the time of creation as long as the properties necessary for publishing are set.
Editing blog post content directly in HubSpot using the content editor is the simplest way to modify content. While you can use the API to create and update blog post, it’s not recommended over using the editor, especially for blogs that rely on more complex modules.

Update a blog post

To update an existing blog post, make a PATCH request to /cms/v3/blogs/posts/{postId}. For example, the request below would update the title and URL slug of a blog post:
This request updates both the draft and live versions of the post. To update only the draft version without affecting the live content, make a PATCH request to /cms/v3/blogs/posts/{postId}/draft instead. The following request body parameters are available:
Properties you provide in the request payload will override existing draft properties without any complex merging logic. As a result, if you’re updating nested properties, you should provide the full definition of the object. Partial updates are not supported for nested objects.

Delete a blog post

To delete an existing blog post, make a DELETE request to /cms/v3/blogs/posts/{postId}. For example, the request below would delete the blog post with ID 184993428780:
A successful deletion returns a 204 No Content response with no body.
This is not the same as the in-app archive function. To perform a dashboard archive, send a normal update with the archivedInDashboard field set to true.

Draft and live versions

Blog posts in HubSpot have both draft and live versions.
  • Draft blog posts appear in HubSpot’s editor, but are not live on the website. They can be reviewed and edited by users in HubSpot or via the API, and can be published when needed. After a blog post is published, the draft version can be updated as needed, then later published to update the live content.
  • Live blog posts are blog posts that appear on the website. The draft version can be updated without affecting the live blog post content. Published posts can be unpublished to remove them from the website and return them to a draft version.

Retrieve the draft version

To retrieve the draft version of a blog post, make a GET request to /cms/v3/blogs/posts/{postId}/draft.

Update the draft version

To update only the draft version of a blog post (without affecting the live content), make a PATCH request to /cms/v3/blogs/posts/{postId}/draft.
Because this request only updates the draft, you would need to make a second request to publish the changes to the website.

Reset a draft

To reset the draft version of a blog post back to its current live version, make a POST request to /cms/v3/blogs/posts/{postId}/draft/reset. This endpoint does not require a request body.

Publishing blog posts

Depending on the state of the blog post, there are different endpoints you can use to publish it.

Publish a draft

If the blog post is currently a draft (not yet published), make a PATCH request to the /cms/v3/blogs/posts/{postId} endpoint. In the request body, include a JSON payload that sets the state to PUBLISHED:
The post must have the following properties set in order to be published:

Push draft changes live

If the blog post is currently published, you can publish any content that’s currently drafted by making a POST request to /cms/v3/blogs/posts/{postId}/draft/push-live. This endpoint does not require a request body.

Schedule a draft to be published

As an alternative to immediate publishing, you can schedule the draft version of your blog post to be published later by making a POST request to /cms/v3/blogs/posts/schedule. In the request body, include a JSON payload that contains the id of the target blog post and a publishDate (ISO 8601 format).

Clone a blog post

To create a copy of an existing blog post, make a POST request to /cms/v3/blogs/posts/clone.

Revisions

You can access previous versions of a blog post and restore them if needed.

Get all revisions

To retrieve all previous versions of a blog post, make a GET request to /cms/v3/blogs/posts/{postId}/revisions.

Get a specific revision

To retrieve a specific previous version, make a GET request to /cms/v3/blogs/posts/{postId}/revisions/{revisionId}.

Restore a revision

To restore a blog post to a previous version, make a POST request to /cms/v3/blogs/posts/{postId}/revisions/{revisionId}/restore. This will update both the draft and live versions. To restore a previous version to the draft only (without affecting the live content), make a POST request to /cms/v3/blogs/posts/{postId}/revisions/{revisionId}/restore-to-draft.

Multi-language management

To help you maintain blog posts across multiple languages, HubSpot’s CMS allows you to group together language variants of the same content. You can learn more about working with multi-language blog posts in on HubSpot’s Knowledge Base.

Create a new language variant

You can create a new language variant for an existing blog post by making a POST request to the /cms/v3/blogs/posts/multi-language/create-language-variation endpoint.

Attach a blog post to an existing multi-language group

You can add a blog post to an existing multi-language group by making a POST request to the /cms/v3/blogs/posts/multi-language/attach-to-lang-group endpoint.

Detach a blog post from a multi-language group

To detach a blog post from a multi-language group, make a POST request to the /cms/v3/blogs/posts/multi-language/detach-from-lang-group endpoint.

Set a new primary language

To change the primary language of a multi-language group, make a PUT request to /cms/v3/blogs/posts/multi-language/set-new-lang-primary:

Update languages in a multi-language group

To explicitly set new languages for each post in a multi-language group, make a POST request to /cms/v3/blogs/posts/multi-language/update-languages:
Last modified on April 13, 2026