PUBLISH API LAB / Publishing

A publish API workflow, from draft to delivery

Turn a publishing request into a clear lifecycle: content identity, approval, destination adapters, confirmation, and recovery.

Updated

PUBLISH. WITH A PLAN. — original neon PublishAPI.com featured image

A publish API sounds like a single operation: send some content and make it public. In a useful implementation, however, publishing is a sequence of decisions. Someone prepares a draft, someone decides that the draft is ready, software translates it for a destination, and another check confirms what readers can actually see. Collapsing those steps into one button makes the first demonstration easier and every later correction harder.

This guide proposes a destination-neutral workflow for a small editorial team. It is an architecture exercise, not documentation for a live PublishAPI.com endpoint. The goal is to make the path from a content record to a public page understandable enough that an editor and a developer can discuss the same release without guessing what “done” means.

Begin with the content record

Choose an internal identifier that stays the same when the title or public URL changes. Attach a revision to each saved editorial version. The identifier answers which story you are discussing; the revision answers which exact text was reviewed. A slug is useful for a public address, but using it as the only internal identity makes a routine headline change unnecessarily risky.

Keep the record small at first. A title, body representation, excerpt, intended destination, and editorial state may be enough. Add author attribution and image information when your publication needs them. Avoid a universal schema containing every field every future platform might support. A small contract with explicit transformations is easier to reason about than a giant record in which most fields have uncertain meaning.

Write down who controls each field. An editor may control the title, while your application assigns the identifier and the destination adapter stores the remote record reference. That distinction becomes especially valuable when automation or AI assists with drafting.

Separate saving from approving

A saved draft is not an approved publication. Represent that difference directly. A simple proposed sequence is draft, in review, approved, delivering, and confirmed. Your project may need fewer states, but each state should explain what the next actor is allowed to do. A color or progress animation is not a substitute for a written definition.

Attach approval to a particular revision. When an editor changes an approved claim, the changed version should return to review instead of inheriting permission from an older draft. Otherwise a background worker could release text that nobody actually approved. Decide how small typographic changes are handled, but make that exception explicit rather than assuming all edits are equivalent.

Keep rejection useful. Record whether the issue concerns missing evidence, an incorrect destination, unresolved image rights, or formatting. A specific return-to-editor message reduces the temptation to bypass the workflow simply to get something unstuck.

Give the destination adapter one job

A destination adapter translates an approved internal record into the format a target accepts. It should not invent editorial content or decide that a draft deserves publication. Keeping those responsibilities apart makes it easier to change the destination without changing the approval process.

For a CMS, the output may be a remote draft record and a later status change. For a static site, it may be a content file followed by a generated release. For a newsletter, it may be a prepared issue handed to a separate delivery system. These are different operations even when the source story is the same. The website publishing route explores the file and page side of this distinction.

Return a structured result from the adapter. Include the destination, source revision, remote identifier when available, and a clear state. Preserve enough diagnostic detail to explain a failure without copying secrets or unnecessary private content into logs.

Distinguish acceptance from completion

An application can accept a job before the resulting content is publicly visible. That is a useful design when work takes time, but only when the interface explains it honestly. Use labels such as queued or processing until the system has evidence for a stronger claim. Do not show “published” merely because the first request was sent.

HTTP method semantics also matter when designing a client. The MDN HTTP request methods reference distinguishes method purposes and properties such as idempotency. In particular, repeating a POST should not be assumed safe merely because some other HTTP methods are defined as idempotent. Your application still needs a destination-aware plan for repeated attempts.

Define a confirmation check suited to the destination. It might inspect the remote record or retrieve a public page. Record what was checked and which revision it confirms. A receipt for one destination should never be interpreted as confirmation for every channel in a multi-destination release.

Design the uncertain outcome first

Imagine that the destination creates a post but the response disappears before your worker receives it. From the worker’s perspective, the attempt failed. From the reader’s perspective, the post may already exist. Blindly repeating the create operation can produce a duplicate, while refusing every retry can leave legitimate work stranded.

A useful proposed strategy is to keep a stable job identity and retain the remote identifier whenever it is known. When an attempt ends ambiguously, reconcile with the destination before creating another record. The exact mechanism depends on what that destination supports. Do not claim duplicate prevention unless you have tested the relevant failure path.

Try an interrupted delivery during development. Ask the operator to recover the job using only the information shown in the interface. If they need to inspect raw database tables or guess which draft was sent, the workflow needs a better recovery surface. The webhooks and retry guide develops this scenario further.

Make the release reversible

Correction is part of publishing, not a special event outside the design. Decide how to update a remote record, remove an incorrect destination variant, and restore a previous static release. Keep the approved source revision even after publication so that a later investigation does not depend on whatever happens to be in the editor today.

Reversal is not identical across channels. A public webpage can be replaced, but a message already delivered to an inbox cannot simply be recalled by changing the source record. Build a correction plan around each channel’s real boundary. Sometimes the appropriate action is a visible correction or a follow-up issue rather than pretending the earlier version vanished.

Keep the first release narrow. One content type and one destination are enough to test the core design. Expand only after a real editor can prepare, approve, publish, correct, and recover a representative item without developer intervention.

A practical acceptance walkthrough

Before calling the workflow ready, walk through one ordinary story and one deliberately difficult story. The ordinary story should prove that the process is understandable. The difficult story should include a long title, a missing image description, an edited approval, and an interrupted delivery. Each failure should produce a clear next action rather than a generic red status.

Check the public result as a reader: title, body, links, metadata, images, and destination identity. Then check it as an operator: which source revision was used, who approved it, which adapter ran, and what confirmed completion. The two views should describe the same publication.

Walk through a two-destination release

Imagine an approved announcement that must become a website page and an RSS entry. Give the announcement one source identifier and a revision number, then keep a separate result for each destination. In your rehearsal, let the page succeed while feed generation stops. The source is still approved, but the distribution job is only partly complete.

Ask the operator to resume only the unfinished feed work. Check that the website page keeps its identity and that the feed points to the same canonical page. Next, change the announcement before resuming the old job. Your design should require a conscious choice about which approved revision to deliver, not silently combine the newer headline with the older body.

Keep the resulting record as an example for your team: source revision, approvals, two destination outcomes, and the evidence used to call the release complete.

Conclusion: publish is a lifecycle

The best starting point is not a larger collection of endpoints. It is a shared definition of the content record, the approval boundary, and the evidence required for completion. Once those decisions are explicit, the transport becomes a replaceable implementation detail. Start with the Publish API foundations, test an uncertain outcome, and make correction part of your first working release rather than a promise for later.

Have a correction or a useful perspective? Get in touch ↗

Before your next release, work through the six publishing checkpoints.