1
Create a draft Post
Create one Post for each channel. A draft uses a channel instead of a destination.Send this body to
POST /workspaces/{workspace_id}/posts.Before you write X copy, get the selected Destination.
Inspect capabilities.body_text_limit in the response.
Each X thread item uses that Destination’s effective limit.
Refresh Destinations after an X subscription change.2
Store the Post version
Store the returned Post
id and version. Use them when you publish the draft.3
Publish the same Post
Send the draft Post and its destination to Add a unique
POST /workspaces/{workspace_id}/posts/publish.
If the group contains multiple draft Posts, include every Post in this request.Idempotency-Key header.OpenPMM returns after it accepts the state change. It does not wait for the
provider. Immediate, nonterminal publication returns 202 Accepted and a
Retry-After header. The response contains every Post ID and all stored
receipts. OpenPMM returns status 422 when a file needs your decision.4
Check the Post status
Use
GET /workspaces/{workspace_id}/posts/{post}. The response includes
lifecycle fields, receipts, and available_actions. Use include=attempts
to get sanitized provider attempt diagnostics. A queued Post can include deferred and
a future next-attempt time. The reason is publishing_velocity for a local
dispatch delay or provider_cooldown when OpenPMM is waiting before it
contacts that destination again. A failed Post stays failed while the
deferral reports when OpenPMM can try it again.Poll only while terminal and action_required are both false. Stop
when the Post is terminal or needs action. Do not send Publish Posts again.
Use retry_safety before you retry a failed Post.A direct or scheduled Post uses
destination_id instead of channel. Put
destination-specific settings in destination_options. For example, an
Instagram Post needs { "instagram": { "placement": "post" } }. OpenPMM checks these
settings during Create Post and Publish Post. If a required setting is
missing, the API returns publisher_validation_failed with status 422.reel placement automatically.
Do not send a facebook member in destination_options. The API rejects this
retired input.
If one destination reaches a provider publishing limit, only that destination’s
Post fails. OpenPMM continues the other destination Posts. Use confirmed manual
Retry later for the affected Post.
An X body item above the connected Destination’s limit fails with
x_character_limit_exceeded. Shorten the item and retry. OpenPMM checks the
capability again immediately before publishing a long X item, so a scheduled
Post can fail safely before it creates provider content if the account was
downgraded.