Create and publish a Webflow CMS post with the Data API v2: a cms:write token, the collection's field slugs, HTML rich text and the rate-limit headers.
LLaunchScaler·Published ·9 min read
To publish a blog post to Webflow CMS through the API, create a site token with the cms:write scope, read your blog collection's ID and field slugs, then send the post to POST https://api.webflow.com/v2/collections/{collection_id}/items/insert with the body as HTML in the rich text field. New items are drafts, so follow up with POST /v2/collections/{collection_id}/items/publish, or create the item live in one call with /items/live.
Every endpoint, header and limit below comes from Webflow's Data API v2 documentation, checked in September 2026. The CMS endpoints changed recently, so if you are maintaining older code, the create section explains how the old and new endpoints map.
What do you need before calling the Webflow CMS API?
You need a Webflow site with a CMS collection for your posts, a site token that includes the cms:read and cms:write scopes, and the site's ID. Every request goes to https://api.webflow.com/v2/ and carries the token in an Authorization: Bearer <token> header.
Create the token in Webflow itself. Webflow's site token guide gives the path:
In your workspace, click the gear icon on the site to open its settings.
Select Apps & integrations in the left sidebar and scroll to the API access section.
Click Generate API token.
Name the token and choose its scopes. For publishing posts, pick CMS read and write; add Sites read if your script will look up the site ID itself.
Generate it, copy it and store it somewhere secret.
Only site administrators can create a site token. Webflow lists some limits worth knowing before you build on one: each site can have up to 5 tokens, a token expires after 365 consecutive days of inactivity (any call resets the clock), and a site token works for one site only. For an integration that serves many sites, Webflow points you to building a Webflow App with OAuth instead.
Questions, answered
What people ask about this
01
How do I create a Webflow CMS item through the API?
Send POST https://api.webflow.com/v2/collections/{collection_id}/items/insert with a Bearer token that has the cms:write scope and an items array, each entry holding fieldData with at least name and slug. Items are created as drafts unless you set isDraft to false.
Test the token with the call Webflow's docs use, GET https://api.webflow.com/v2/sites, which lists the sites it can reach. The response gives you each site's id.
How do you find the collection ID and field slugs?
List the site's collections with GET /v2/sites/{site_id}/collections, pick your blog collection's id, then fetch GET /v2/collections/{collection_id}. The second response lists every field with its slug, type, displayName and isRequired. The API writes fields by slug, not by the label you see in the Designer.
Both need cms:read. A typical blog collection returns something like this set of fields; your slugs will match however the collection was built:
Field in the Designer
Slug (example)
Type
What to send
Name
name
Plain text
The post title, required on every item
Slug
slug
Plain text
The URL segment, required on every item
Post body
post-body
Rich text
An HTML string
Post summary
post-summary
Plain text
A short string
Main image
main-image
Image
{ "url": "...", "alt": "..." }
Two fields exist on every item: name and slug. Webflow's item reference warns that changing an item's slug later "will break all links referencing the old slug," so set it once and leave it. Slugs for the other fields are lowercase with spaces turned into hyphens, which is why a field labelled "Post Body" usually has the slug post-body. Read them from the response rather than guessing.
How do you create a collection item?
Send the post to POST /v2/collections/{collection_id}/items/insert with an items array. Each entry holds a fieldData object keyed by field slug. Items are created as drafts unless the entry sets isDraft: false, and one request can create up to 100 items.
curl -X POST "https://api.webflow.com/v2/collections/$COLLECTION_ID/items/insert" \
-H "Authorization: Bearer $WEBFLOW_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"items": [{
"fieldData": {
"name": "How to publish to Webflow from a script",
"slug": "publish-to-webflow-from-a-script",
"post-summary": "The Data API v2 calls, in order.",
"post-body": "<p>First paragraph.</p><h2>A section</h2><p>More text.</p>",
"main-image": { "url": "https://example.com/cover.jpg", "alt": "Diagram of the publishing flow" }
}
}]
}'
The response returns the created items with their new id. Keep it: you need it to publish or update the post.
Webflow now has three endpoints that create items, and its "Creating collection items" guide says to use this one, "Create Items", for new integrations. The older POST /items and POST /items/bulk still work but are no longer listed in the reference navigation. Create Items validates strictly: unrecognized properties, including the old singular cmsLocaleId, return a 400. If you are moving old code, put the top-level fieldData inside one items entry and replace cmsLocaleId with a one-element cmsLocaleIds array. Without either locale selector, the item is created in the site's primary locale.
How do rich text and image fields work through the API?
A rich text field takes a string of HTML: paragraphs, headings, lists, links and blockquotes. Webflow's field reference adds one exception worth planning around: code blocks are not supported in rich text through the API, and "passing code blocks will result in an empty string." Image fields take an object with a public url and an optional alt.
Practical rules for the body HTML:
Start sections at <h2> and leave <h1> to the title your collection template displays.
Send only the article body, not a full document with <html> or <head>.
Replace code blocks with an embed or keep code in a separate field, since the API drops them.
Rich text can include Webflow components; Webflow's "Components in Rich Text" guide documents the markup.
For images, Webflow downloads the file from the URL you give it, so the URL must be publicly reachable. The maximum file size is 4MB per image. The Create Items endpoint takes a skipInvalidFiles query parameter that defaults to true, meaning an image Webflow cannot fetch is skipped and the item is still created. Set it to false if you would rather the whole request fail than publish a post without its image.
How do you publish the item?
You have three ways to get a post live. Publish specific items with POST /v2/collections/{collection_id}/items/publish. Create an item already live with POST /v2/collections/{collection_id}/items/live. Or set isDraft: false and let the next full site publish take it live. Most blog integrations use the first.
Webflow answers 202 with publishedItemIds and an errors list. Its reference says publishing a draft "automatically sets isDraft to false," so you don't need a separate update first.
Webflow's publishing guide explains the states through two properties on every item:
Status in the Webflow UI
lastPublished
isDraft
Published and visible
set
false
Live, with unpublished changes held in draft
set
true
Draft, never published
null
true
Queued for the next site-wide publish
null
false
Scheduled
Not controllable through the CMS API
Three details catch people out. Setting isDraft: true on a live item does not unpublish it; you need the unpublish live items endpoint for that. Scheduling a future publish time "can not be controlled by the CMS API," so a script that wants a post live at 9:00 has to call publish at 9:00. And a full site publish is limited to one successful publish per minute, which is one reason to publish items individually.
To correct a post that is already live, use the update live items endpoint, which Webflow's publishing guide describes as updating an item and publishing the change "in a single action." To stage a correction for review instead, update the staged item with isDraft: true; the live version stays visible until you publish again. Unpublishing keeps the item in the CMS and sets isDraft to true, while archiving (isArchived: true) removes the item from the live site at the next full-site publish and keeps it in the CMS.
How do you respect Webflow's rate limits?
Webflow limits requests per minute by site plan: 60 on Starter and Basic, 120 on CMS, eCommerce and Business, and a custom figure on Enterprise. Limits apply per API key. Read the X-RateLimit-Remaining header on every response, and on a 429 wait for the number of seconds in Retry-After before trying again.
Header
What it holds
X-RateLimit-Limit
Your overall limit per minute
X-RateLimit-Remaining
Requests left in the current minute
Retry-After
How long to wait before the next request, typically 60 seconds after a 429
A 429 body looks like {"message": "Too Many Requests", "code": "too_many_requests"}. Webflow's official SDK, webflow-api, retries with exponential backoff on its own. Without it, write your own retry that honours Retry-After. Publishing one post takes three or four calls, so a daily article is nowhere near the limit; the risk comes from backfills and from polling. Webflow suggests webhooks instead of polling, and it has a Collection Item Published event you can listen for.
What does the whole flow look like in JavaScript?
This function runs on Node 18 or later. It creates the item as a draft, publishes it, and retries once on a 429 after the wait Webflow asks for.
Swap the field slugs for the ones your collection returned. If the post needs a review step before going live, call only the create half and publish from the Webflow editor. The same create-then-publish pattern appears in Ghost's Admin API and in the WordPress REST API; if you run a CMS none of these cover, a signed webhook receiver lets you write the last step yourself.
Get a finished draft to send to Webflow every day
The API calls take an afternoon to wire up. Writing a post worth publishing every day is the part that doesn't get easier. LaunchScaler's content engine plans a month of articles from your own Search Console queries, writes one a day from what your product actually does, in your voice, and lands every draft in your workspace for you to rewrite, trim or scrap. By default, every draft waits for your review before it publishes; once you approve one, it goes to Webflow, or to WordPress, Ghost, Shopify, Notion, Medium or a signed webhook.
It costs $99/mo per website, with 3 days free before the first charge. Start the engine and the first draft arrives on day one.
Call POST /v2/collections/{collection_id}/items/publish with the item IDs; publishing a draft sets isDraft to false automatically. Or create it live in one call with POST /v2/collections/{collection_id}/items/live.
03
What format does a Webflow rich text field take through the API?
A string of HTML, such as paragraphs, headings and blockquotes. Webflow's reference notes that code blocks are not supported in rich text through the API and come back as an empty string.
04
What are the Webflow API rate limits?
60 requests per minute on Starter and Basic site plans, 120 on CMS, eCommerce and Business, and custom on Enterprise, counted per API key. Going over returns 429 with a Retry-After header, typically 60 seconds.
05
Where do I create a Webflow API token?
In the site's settings, open Apps & integrations, scroll to API access and click Generate API token, then name it and choose its scopes. Only site administrators can create one, and each site can have up to 5.
The Application Passwords section disappears when WordPress can't detect HTTPS or a plugin disables it. Every cause, how to spot it, and the exact fix.
Answer in the first two sentences, write 40 to 60 word passages under question headings, and back claims with sources and statistics. Rules with examples.