Posts
Update post draft
Updates a draft's title, content (saved as a new version), and/or assigned profile. Fails on scheduled/published posts.
PATCH
/api/public/posts/:idcURLPATCH /api/public/posts/:id
curl -X PATCH https://postiv.ai/api/public/posts/ID_ID \
-H "Authorization: Bearer pk_postiv_..." \
-H "Content-Type: application/json" \
-d '{
"title": "Launch lessons",
"content": "Three things we learned from launch week..."
}'200Response
{
"success": true,
"post": {
"id": "post1...",
"status": "draft",
"content": "Updated text..."
},
"version": {
"id": "v2...",
"versionNumber": 2,
"createdAt": "2026-07-19T09:05:00.000Z"
}
}Authorization
Requires an organization API key with the posts:write scope, sent as Authorization: Bearer or x-api-key.
Path parameters
idstringrequiredResource id from the corresponding list or create endpoint.
Body parameters
titlestring|nullMax 240 chars; null clears it.
contentstringMax 100000 chars; stored as a new post_versions row.
integrationIdint|nullAlias: integration_id. null unassigns.
Response
The updated post plus the new version (if content changed).
postobjectFull post object, same shape as GET.
versionobject|null{ id, versionNumber, createdAt }; null if content wasn't provided or was unchanged (no-op save).
Errors
| 400 | validation_error: none of title/content/integrationId provided |
| 404 | post_not_found |
| 409 | post_scheduled_locked: post is scheduled; unschedule first |
| 409 | post_published_immutable: post already published |
| 409 | content_plan_profile_locked: post is linked to a Bob plan item and the requested integrationId doesn't match that plan's profile |
| 404 | linkedin_profile_not_found: new integrationId not in this workspace |
Good to know
- A no-change content save (identical to the current version) is silently skipped: version returns null rather than creating a duplicate version row.