Platforms
Connect a Webflow site to publish and edit items in its CMS blog collections and to add ad pixels to the site's custom code.
A connected Webflow site is a blog account. Every CMS collection on the site that has a rich text field shows up as a blog, and its items are articles you create, publish, edit and delete through the Blogs API. Webflow accounts are not social accounts and have no inbox or analytics.
#What you can do
| Job | Supported |
|---|---|
| Create, publish, edit, unpublish and delete CMS items | Yes |
Fill your collection's own fields (fieldData) |
Yes |
| Schedule an item for later | No. Webflow's API cannot schedule |
| SEO fields, localized items, Ecommerce products | No |
| Create, rename or delete collections | No (405) |
| Ad pixels | Yes, with the OAuth connection only |
| Property | Value |
|---|---|
| Platform id | webflow |
| Connect | OAuth with the Pozy Webflow app, or a site API token |
| Blog id | The collection id |
| Status | publish or draft |
#Before you start
You need a site on a CMS plan with a blog-style collection. The site must have been published at least once before items can go live.
#Connect with Webflow (OAuth)
Use this path when you also want to install pixels. There is nothing to copy.
curl "https://api.pozy.ai/v1/connect/webflow?profileId=6710c3a9e4b0d2f1a8c95e21&redirect_url=https://app.example.com/connected" \
-H "Authorization: Bearer $POZY_API_KEY"const res = await fetch("https://api.pozy.ai/v1/connect/webflow?profileId=6710c3a9e4b0d2f1a8c95e21&redirect_url=https:%2F%2Fapp.example.com%2Fconnected", {
headers: { Authorization: `Bearer ${process.env.POZY_API_KEY}` },
});
const data = await res.json();
if (!res.ok) throw new Error(data.error);import os, requests
resp = requests.get(
"https://api.pozy.ai/v1/connect/webflow",
headers={"Authorization": f"Bearer {os.environ['POZY_API_KEY']}"},
params={"profileId": "6710c3a9e4b0d2f1a8c95e21", "redirect_url": "https://app.example.com/connected"},
)The user picks exactly one site on Webflow's screen. Picking several connects none and returns error=webflow_pick_one_site. Connecting a site that was first connected with a token upgrades the same account.
#Connect with a site API token
Create the token inside Webflow: go to Site settings > Apps & integrations > API access, then generate one with Sites set to read-only and CMS set to read and write. Each site token works for a single site.
curl -X POST https://api.pozy.ai/v1/connect/webflow/token \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "profileId": "6710c3a9e4b0d2f1a8c95e21", "siteToken": "wf_site_token_..." }'Pozy confirms the token's permissions, looks up the site it belongs to, and saves it encrypted. Webflow cancels site tokens that go unused for 365 days. When a token dies, because someone deleted or regenerated it, the account is marked as needing a reconnect; connect it again with a fresh token.
#Publish an item
Find the collection with GET /v1/accounts/{accountId}/blogs, then create the item:
curl -X POST https://api.pozy.ai/v1/accounts/6710c4d1e4b0d2f1a8c95e4f/blogs/6512f0a8c1d2e3f4a5b6c7d8/articles \
-H "Authorization: Bearer $POZY_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"title": "How we cut page load time in half",
"bodyHtml": "<p>Three changes did most of the work.</p>",
"excerpt": "Three changes that halved our load time.",
"tags": ["performance"],
"image": { "url": "https://cdn.example.com/speed.png", "altText": "Load time chart" },
"fieldData": { "reading-time": "4 min" },
"isPublished": true
}'Pozy reads the collection's fields and maps article fields by type and slug:
| Article field | Webflow field it fills |
|---|---|
title, handle |
The item's name and slug. No handle? The slug is made from the title, plus a suffix when it is already used |
bodyHtml |
The collection's rich text field, choosing one called body, content or post when there are several |
excerpt |
A plain text field whose slug is summary, excerpt, description or intro |
image |
An image field, choosing one called main, cover, featured, hero, header or thumbnail when it exists |
tags |
A multi-reference field named tags, categories or topics. Missing tags are created and published |
author |
A reference field called author or writer. Pass the id of the item it points to |
publishDate |
A date field named publish or date |
Any other field of the collection goes in fieldData, keyed by its slug and written the way Webflow expects: an item id for a reference, { "url": "...", "alt": "..." } for an image. If a create would leave required fields empty, you get 400 naming all of them. You also get 400 for a slug the collection lacks, or one Pozy fills from the article fields above.
#Publishing rules
isPublished: truepublishes the item to the live site now. Leaving it out, orfalse, keeps a draft.isPublished: falseon a published item unpublishes it. Edits to a published item go live.publishDatecannot be in the future (400). On a draft (isPublished: false) it is simply stored in the date field.seoreturns400. Code blocks in the HTML are dropped by Webflow. Body images are copied to Webflow's asset hosting.- Delete unpublishes the item from the live site, then deletes it.
#Pixels
Installing a pixel needs the OAuth connection, not a site token. Webflow only ships custom code when the whole site is published, so the tag starts firing after your next publish, and the install response always says publishRequired: true. Pozy leaves publishing to you: publishing the site would also release every pending change in the Designer. See Site pixels.
#Errors
| Error | Cause | Fix |
|---|---|---|
400 "rejected the site token" |
Wrong, deleted or regenerated token | Generate a new site token |
400 "missing cms:write" |
The token cannot write to the CMS | Generate one with CMS set to read and write (Sites can stay read-only) |
400 "scoped to one site" |
You sent a workspace token, or a token for more than one site | Switch to a site API token |
400 "Publish the Webflow site once" |
The site was never published | Publish it once in Webflow, then retry |
403 |
Webflow does not accept the token | Connect again with a fresh token |
404 blog_not_found |
No collection with a rich text field has that id | Check the ids in the account's blog list |
429 |
Webflow caps each token at 60 to 120 requests per minute, depending on the site's plan | Wait for Retry-After, then retry |
#Endpoints
| Endpoint | What it does |
|---|---|
GET /v1/connect/webflow |
Get Webflow OAuth URL |
POST /v1/connect/webflow/token |
Connect Webflow with a site API token |
GET /v1/accounts/{accountId}/blogs |
List blogs |
GET /v1/accounts/{accountId}/blogs/{blogId}/articles |
List blog articles |
POST /v1/accounts/{accountId}/blogs/{blogId}/articles |
Create a blog article |
GET /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId} |
Get a blog article |
PATCH /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId} |
Update a blog article |
DELETE /v1/accounts/{accountId}/blogs/{blogId}/articles/{articleId} |
Delete a blog article |