Delivery receipts for social posts: what you actually get back
What a "receipt" for a social post attempt should contain — status, platform post ID and permalink, timestamp, and a structured error if it failed — and why the create-call response is not one.
A delivery receipt is the terminal, per-target record of what a post attempt actually produced: a status (published, failed, or skipped), a platform-issued post ID and permalink when it published, a timestamp, and a structured error with a retryable flag when it failed. The response to the original create call is not a receipt — it only confirms acceptance.
Buy something online and you get a receipt: what was bought, whether it went through, and a reference number if it didn't. Post something through most social publishing APIs and you get nothing comparable — just an acknowledgment that your request was accepted, with no durable record of what actually happened at each destination once the dust settled. A delivery receipt is that missing artifact: the terminal, per-target record of what a post attempt actually produced.
PostGate handles OAuth, publishing and delivery evidence for every network through one API. Start free or read the docs.
What goes on a delivery receipt?
Every target on a PostGate post ends up with the same four pieces of information once it reaches a terminal state, and together they form the receipt for that one destination:
- Status — the terminal outcome:
published,failed, orskipped. See Delivery lifecycle for the full state machine each target moves through before it gets here. - Platform identity — a
platform_post_idandpermalinkon any target that actually published, issued by the destination network itself, not by PostGate. - Timestamp —
occurred_aton the terminal webhook event tells you exactly when that outcome happened, independent of when your consumer received or processed it. - Error, if it failed — a structured
errorobject with a stablecodeand aretryableflag, not a free-text message you have to parse.
{
"id": "post_01JXYZ",
"status": "partial",
"targets": [
{
"profile_id": "pro_instagram123",
"status": "published",
"platform_post_id": "17895...",
"permalink": "https://instagram.com/p/Cxyz.../"
},
{
"profile_id": "pro_linkedin456",
"status": "failed",
"error": { "code": "platform_transient", "retryable": true }
}
]
}Where does a receipt come from — pulled or pushed?
You can pull the current receipt any time with GET /api/posts/{id}, or have PostGate push it to you the instant it's final by subscribing to post.published, post.partial, and post.failed — see Webhooks. The webhook payload carries the same envelope every event uses: a stable id, type, occurred_at, and a resource-specific data object holding the target-level detail above.
Is a receipt the same thing as acceptance?
The response to the original POST /api/posts call is not a receipt — it's a claim check. It confirms PostGate accepted the request and will attempt delivery; it says nothing about what happened at any destination, because delivery hasn't happened yet. Treating the create response as the receipt is the root cause of the worst failure mode in this category — covered in full in Scheduler says published, but the post never appeared.
Should you keep the receipt, or just a status field?
If your product only stores a boolean "did it post" per target, you're discarding exactly the information a customer will ask for later: the permalink to prove it went out, or the error code that explains why it didn't. Persist the full per-target payload from the terminal webhook or the read endpoint, not a summary of it — the receipt is the artifact, not the fact that one existed.
Frequently asked questions
Is the API response to creating a post proof that it published?
No. The response to the original POST /api/posts call is a claim check, not a receipt — it confirms the request was accepted and delivery will be attempted, but says nothing about what happened at any destination, because delivery hasn't happened yet. Treating the create response as the receipt is the root cause of the worst failure mode in this category: a scheduler that says published while nothing appeared.
How do I get a delivery receipt for a social media post?
Two ways: pull the current receipt any time with GET /api/posts/{id}, or have it pushed the instant it is final by subscribing to the post.published, post.partial, and post.failed webhook events. The webhook payload carries the same envelope every event uses — a stable id, type, occurred_at timestamp, and a resource-specific data object holding the per-target detail.
What information should a delivery receipt contain?
Four pieces per target: the terminal status (published, failed, or skipped); the platform identity — a platform_post_id and permalink issued by the destination network itself, not the middleware; a timestamp saying exactly when the outcome happened; and, on failure, a structured error object with a stable code and a retryable flag rather than a free-text message you have to parse.
Should I store the full receipt or just a posted/not-posted flag?
Persist the full per-target payload from the terminal webhook or the read endpoint. A boolean "did it post" discards exactly the information a customer will ask for later — the permalink to prove it went out, or the error code that explains why it did not. The receipt is the artifact, not the fact that one existed.
