Editing a post
Change a draft, scheduled or failed post the way the composer and the MCP tools change it.
https://antwork.io/api/v1/posts/{id}Scopewrite · publishRequest
PATCH /api/v1/posts/{id} changes only the fields you send. Text and hashtags are set and the post's media and tags stay; options are merged one setting at a time. A published post cannot be edited (409 post_already_published): the change would not reach the live post.
curl -X PATCH https://antwork.io/api/v1/posts/pQ7x... \
-H "Authorization: Bearer $ANTWORK_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $(uuidgen)" \
-d '{
"text": "Shipping the new editor today",
"options": {
"privacyStatus": "unlisted"
},
"scheduledFor": "2026-11-05T10:00:00Z"
}'textstringhashtagsstring[]accountIdstringoptions are checked against the new one.optionsobject | null{"privacyStatus": "unlisted"}; Pinterest {"boardId": "..."}). A setting given null is removed, and "options": null removes them all. TikTok's are the owner's to choose (tiktok_settings_need_the_creator).newBoardNamestringpinterest_board_create_failed if Pinterest refuses.scheduledForISO 8601publish scope. On a draft or a failed post it only proposes a time; schedule it with POST /api/v1/posts/{id}/schedule.status'draft'"draft": moves a scheduled post back to draft and cancels its queued publish.Needs the write scope, and publish as well when the edit moves a scheduled post to a new time, because that commits it again against your plan, the daily cap and the posting guards. The same rule as the MCP update_post tool. Send an Idempotency-Key: a retried request with a newBoardName must not create a second board.
Response
200 with the post as saved: the same shape as GET /api/v1/posts/{id}, with readiness and the composer links, plus pinterestBoardCreated when a board was made. A refused argument or a platform rule (text_too_long, media_required…) is a 400 and nothing is written. When the plan or the account has no room at the new time (quota_exceeded, daily_cap_reached, duplicate_post…), the answer is a 409, the edit IS saved and the post keeps its old time; post carries it as it now stands.
{
"error": {
"type": "invalid_request_error",
"code": "daily_cap_reached",
"message": "This account has reached its daily cap ... The edit is saved; the post keeps its old time."
},
"post": { "object": "post", "id": "pQ7x...", "status": "scheduled", ... }
}POST /api/v1/posts gives per target, so one handler covers both. See Errors for the full list.Setting the media
PUT /api/v1/posts/{id}/media with {"media": [...]} makes the post's media exactly that list, in that order: reorder it, trim it, or send [] to clear it. Each file must be in the workspace's media library (media_not_in_library otherwise); a file already on the post is always accepted. Needs the media scope. Sending the same list twice changes nothing, so no Idempotency-Key is needed.
curl -X PUT https://antwork.io/api/v1/posts/pQ7x.../media \
-H "Authorization: Bearer $ANTWORK_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"media": [
"https://firebasestorage.googleapis.com/v0/b/.../o/workspaces%2Fws_...%2Fmedia%2Fcover.jpg?alt=media"
]
}'200 with the post, its readiness saying whether the platform's media rule is now met. On Instagram, originalityWarning lists the account's other posts that already carried the same file: Instagram shows reposted media to fewer people.