Docs › Concepts › Posts and results
Posts and results: how delivery really works
One post, one result per channel. How a result moves from waiting to posted, and why OmniPosts checks instead of resending.
You write one post and choose the channels it goes to. OmniPosts keeps one result for each channel. A post to five channels has five results, and each one succeeds or fails on its own. One channel rejecting the post does not stop the others.
The API calls a post sent to several channels a group, and the result for one channel a target. The app calls them a post and a result.
What OmniPosts guarantees
- A post and the job that publishes it are saved together. There is no state where a post exists but nothing will ever send it.
- A dispatch that may have reached a platform is never sent again. If the platform does not answer clearly, OmniPosts looks the post up on the platform instead of resending it.
- Posted is final. Once a result is posted it can never change back or be sent again. The database enforces this, not only the code.
- Every channel is reported separately. You get a result per channel, each with its own reason and one thing to do.
- Missing numbers say "Not available". They are never shown as 0. See Honest numbers.
The life of a result
A result moves through these steps. The wording is what you see in the app.
Waiting to send -> Checking the post -> Scheduled -> Sending now
|-> Posted
|-> Not posted
|-> Waiting for the platform to finish -> Posted / Not posted
|-> Checking whether this posted -> Posted / Not posted
Cancelled (only before sending starts)
| Step | API status | Meaning |
|---|---|---|
| Waiting to send | pending |
Saved, not yet looked at. |
| Checking the post | preflight |
OmniPosts is checking the text, media and the channel before it sends. |
| Scheduled | queued |
Ready, waiting for its time or for a free worker. |
| Sending now | publishing |
OmniPosts has started handing the post to the platform. |
| Waiting for the platform to finish | awaiting_platform |
The platform took the post and is still processing it. |
| Checking whether this posted | unknown |
The post was sent but the platform did not confirm. |
| Posted | published |
It is live. The result has a link to the post. |
| Not posted | failed |
It did not go out. The result has a reason and one action. |
| Cancelled | cancelled |
You cancelled it before sending started. |
Every status, and which are final, is in Post statuses.
Checking whether this posted
Sometimes OmniPosts sends a post and then loses the answer: the connection drops, the platform times out, or it replies in a way that does not say yes or no. The post may or may not be live.
Resending would risk a double post to a real audience, and a double post cannot be undone. So OmniPosts does not resend. The result shows Checking whether this posted while OmniPosts looks the post up on the platform. Then one of two things happens:
- The post is found. The result becomes Posted, with its link.
- The post is not found. The result becomes Not posted. Only now, because OmniPosts has confirmed it did not go out, can the result be retried.
If OmniPosts cannot confirm either way, the result says so and offers an Open button for the platform (for example Open Bluesky), so you can look yourself. See Failure classes.
The status of the whole post
The post as a whole gets a status from its results. It is Posted everywhere only when every channel that was not cancelled has posted. While any channel is still being sent or checked, the post stays Sending. Once nothing is left to send, a mix of posted and not posted is Posted to some channels. The rules are in Post statuses.
Cancelling and retrying
You can cancel a post, or move it to another time, until sending starts for a channel. After that, the
result can no longer be cancelled, because it may already be on the platform. Cancelling works per
channel: results already sending or finished stay as they are, and the response lists which were
cancelled and which were not. In the API: POST /v1/groups/{id}/cancel.
A result that failed can be retried only when its failure says a retry is safe. The app shows Try
again on those results. In the API: POST /v1/groups/{id}/retry. A result that is still Checking
whether this posted is never retried.