Symptom
Posts that used to be reachable now return 404 Not Found on your site, disappear from your blog listing, and drop out of your sitemap. Nothing about your integration changed.
Check the post's status first
Archived is by far the most common cause, and it is invisible from the outside: the public API omits archived posts entirely, so a listing simply gets shorter and a post URL answers 404 exactly as if the post had never existed. The same is true of Unpublished and of a post that never left Scheduled.
The authenticated post list returns every post on the blog with its current status, which is what makes the difference visible:
curl -H "Authorization: Bearer your_token" \
https://api.postnomic.com/blogs/{blogId}/posts
The response is an array of post summaries; status is the field to read:
[
{
"publicId": "b2a1…",
"title": "How we sped up our build",
"slug": "how-we-sped-up-our-build",
"status": "Archived",
"publishedAt": "2023-04-17T09:30:00Z",
"createdAt": "2023-04-16T18:02:11Z",
"canonicalUrl": "https://example.com/blog/how-we-sped-up-our-build"
}
]
Any status other than Published explains a 404. The dashboard shows the same information: open the blog and read the Status column of the post list.
The token can be your dashboard session's JWT or a Personal Access Token; the same list is available to AI agents through the MCP list_posts tool.
What archives a post
- The Archive button. The post editor's lifecycle actions include Archive, and it is available in every state — including Published. There is no separate confirmation step.
- An integration. The MCP
delete_posttool archives the post rather than deleting it. Anything driving the API with your credentials can archive too. - A bulk operation. If several posts changed at once, look for something that ran against the blog rather than for a person.
Note that the REST DELETE blogs/{blogId}/posts/{postId} endpoint really deletes: a post removed that way is gone and cannot be recovered through the API.
Other causes worth ruling out
- Unpublished, not archived. The post was taken offline manually, or an automatic unpublish date set during scheduling arrived.
- Still Scheduled. If the post's Review required flag is set, automatic publishing is skipped until at least one review is assigned and every assigned review is approved — the post stays Scheduled indefinitely and never appears.
- A cross-post that was withdrawn. Posts cross-posted to your blog from another blog are visible on your site but are not listed under your blog's own posts. If the owning blog removed the cross-post, the post disappears from your site and will not show up in the list above at all.
- Caching. Public responses are cached briefly (a few minutes, per API replica) and the Client SDK has an optional cache of its own. A post you have just recovered can take a few minutes to reappear everywhere.
Recovering an archived post
The order of these three steps matters — doing them in a different order either fails outright or loses the post's publication date.
1. Unarchive. This returns the post to Draft, never straight to Published. The dashboard has no unarchive button, so use the API or the MCP unarchive_post tool:
curl -X POST -H "Authorization: Bearer your_token" \
https://api.postnomic.com/blogs/{blogId}/posts/{postId}/unarchive
2. Publish. Review the draft, then publish it. The slug is unchanged, so the original URL starts working again.
curl -X POST -H "Authorization: Bearer your_token" \
https://api.postnomic.com/blogs/{blogId}/posts/{postId}/publish
3. Restore the publication date. Publishing has just stamped the post with today's date. Put the original back with publishedAt on the update endpoint:
curl -X PUT \
-H "Authorization: Bearer your_token" \
-H "Content-Type: application/json" \
-d '{"title":"Your title","slug":"your-slug","content":"<p>…</p>","publishedAt":"2023-04-17T09:30:00Z"}' \
https://api.postnomic.com/blogs/{blogId}/posts/{postId}
Why the order cannot be changed:
publishedAtis only accepted while the post is Published or Unpublished. Sending it with step 1 or 2 still pending is rejected with 400 Bad Request.- Publishing after correcting the date would overwrite the correction with the current time.
PUTreplaces the post, so send the post's current title, slug, content, excerpt, tags and categories back with it — read them withGET blogs/{blogId}/posts/{postId}first. Anything you leave out is cleared.
If you recorded the original dates before recovering the posts, use those. If not, an archived post still carries its old publishedAt in the list response above — capture it before you publish, because that is the value publishing overwrites.
See Post Lifecycle for the full set of states and the rules on publishedAt.
If you cannot account for the change
Postnomic records every post status change — what changed, when, who made it, and whether it came from the dashboard, the API, an MCP agent or a background job. If posts changed status and nobody on your team recognises the action, open a support ticket with the blog slug, the affected post IDs and the approximate time. Support can look the change up and tell you where it came from.