Content Delivery API Guide: Endpoints and Best Practices
You've finished the article, but you're still rewriting it for Substack, Medium, LinkedIn and X. The LinkedIn version has yesterday's headline. The X thread...
By Ian Kiprono
You've finished the article, but you're still rewriting it for Substack, Medium, LinkedIn and X. The LinkedIn version has yesterday's headline. The X thread points to an old URL. You corrected a paragraph on Substack, but the other copies still contain the mistake. Your publishing calendar looks organized until you need to change something, then you're opening tabs, checking drafts and wondering which version readers will see.
The problem isn't a lack of writing discipline. You're maintaining separate copies without a dependable relationship between them.
What a Content Delivery API Does for Writers
A content delivery API is an interface that serves one canonical content object, including its text, metadata and media references, in a machine-readable format such as JSON. A website, app or publishing automation requests that object and decides how to present it. Instead of treating each destination as another document to maintain, you treat it as a view or derivative of the same approved source.
A webpage combines content with presentation. An API separates those concerns: it returns fields such as title, body_blocks, tags, status and publish_at, rather than a finished page with navigation and styling.
The difference becomes clearer when you compare the workflows.

Separate the source from its destinations
Say you publish an essay about newsletter onboarding. Your canonical object holds the approved argument, illustrations and original URL. A LinkedIn adapter extracts the practical lesson; an X adapter produces a thread; a Substack Note introduces the question and links to the essay.
These aren't identical copies. They're channel-specific derivatives with a recorded source version.
Programmable delivery is established infrastructure: 82% of organizations used APIs internally and 71% used third-party APIs in 2024, according to Gartner's 2024 API Strategy Survey. Earlier, a 2016 academic study of firms in the United States and Europe found that the average company went from approximately 5 APIs in 2013 to about 32 in 2015, illustrating the move toward specialized, reusable interfaces.
For writers, that architecture supports distinct jobs:
- Syndication: Deliver an approved article to another destination without rebuilding the source.
- Repurposing: Derive shorter, destination-specific material while retaining its relationship to the original.
- Scheduling: Associate approved content with a publishing time instead of maintaining disconnected calendar reminders.
The one-edit test: Change the source article. Can every connected destination identify the change and update, or request approval, without another copy-and-paste operation?
A platform won't necessarily update an already published post automatically. That requires a supported update operation and an explicit workflow. The useful test is whether your system knows which destination copy came from which source version, not whether every platform displays identical text.
Authentication, Errors and Webhooks
Start with access. Issue a separate, scoped API key for each integration and send it through an Authorization: Bearer header when that authentication method is supported. Keep credentials on the server or in your automation tool's credential store, never inside an article or public browser bundle.
Give dashboards read-only access. Reserve publishing permissions for the workflow that releases content, rotate credentials on a documented schedule, and revoke them when an integration is retired.
Make failures actionable
Define an error contract that tells the client what to do next.
| Response | Meaning in this API design | Client action |
|---|---|---|
400 |
Malformed input, such as a timestamp without an offset | Correct the request |
401 |
Missing, invalid or expired credentials | Repair authentication |
403 |
Credentials lack the required permission | Review scopes |
404 |
Unknown article identifier | Check the stored reference |
412 |
Submitted version is stale | Fetch the current version |
429 |
Rate limit exceeded | Respect Retry-After before retrying |
These are proposed contract choices, not a claim that every publishing API behaves identically. Save the response body and request identifier so an editor can distinguish a rejected timestamp from a disconnected account.
Trigger work instead of checking repeatedly
Subscribe to events such as article.published, article.updated and distribution.failed. Verify each webhook signature against the raw request body, acknowledge accepted delivery quickly with a successful 2xx response, then queue heavier work.
For a concrete implementation reference, Outrank webhook documentation is useful when examining an event producer's contract. For publishing automation planning, consult our webhook workflow information.
- Deduplicate events: Store processed event identifiers because deliveries may repeat.
- Keep work asynchronous: Put transformations, cache purges and publishing requests in a queue.
- Test access first: Successfully retrieve an approved article before building the rest of the integration.
Core Endpoints and Primitives at a Glance
Core endpoints and primitives for a content delivery API
| Primitive | Method and path | Purpose | Key detail |
|---|---|---|---|
| List articles | GET /v1/articles?limit=20&cursor= |
Paginated collection of canonical articles | Cursor token, not page numbers |
| Read one article | GET /v1/articles/{id} |
Full canonical object for one piece | ETag response header |
| Create draft | POST /v1/articles |
New unpublished draft | Return 201 Created with the new ID |
| Partial update | PATCH /v1/articles/{id} |
Edit selected fields without resending the body | If-Match with the current ETag |
| Schedule | POST /v1/schedules |
Queue one post for a set time | publish_at in ISO 8601 with a UTC offset |
| Distribute | POST /v1/articles/{id}/distributions |
Send one version to one channel | channel: substack, medium, linkedin or x |
| Read stats | GET /v1/articles/{id}/stats |
Engagement and subscriber signals | Broken down by channel and by day |
These paths are an illustrative REST contract, not any vendor's specification. Adapt names, supported operations and authentication to the API you use. A content delivery API is often read-only; draft creation, updates and distribution may belong to separate management and publishing APIs.
Read a stable object
The read endpoint is your foundation. A feed might list approved articles, follow the returned cursor, then retrieve the selected article by its canonical ID.
Store that ID independently from the title or slug. Editors change headlines, and platforms generate their own identifiers. Neither should break the relationship between the original essay, its supporting posts and its analytics.
A useful response also distinguishes publication state from editorial approval. An article can be approved but scheduled for later, so the server must enforce visibility rather than asking every client to remember a filter.
Update only what changed
A partial update should name the fields being edited. If you're fixing preview text, don't resend an old body just because it happened to be present in the editor's local copy.
Require the client to identify the version it edited. Treat a rejected update as an editorial conflict to resolve, not an invitation to resend the same request until it succeeds.
Keep the canonical article ID stable. Give each destination post its own ID, then record the relationship between them.
Schedule a resource, not a reminder
A schedule resource should identify the source article, approved version, destination, derived content and intended publication time. That makes a queued Note inspectable: an editor can see what will publish, where it came from and whether it still matches the approved source.
Statistics need the same discipline. Record destination post identifiers beside the canonical article ID, and preserve each platform's metric names. A reaction, click and subscriber attribution aren't interchangeable measurements.
Build read and update primitives first. Scheduling and distribution become easier to reason about once identity, permissions and version checks already work.
Content Models and Format Rules by Channel
Suppose one article is destined for Substack, Medium, LinkedIn, and X. Keeping four independent copies invites drift: a corrected headline may reach one platform while an outdated version remains on another. Store one canonical article with structured blocks, then create channel-specific representations from that shared source.
A heading, paragraph, image, quote, or code block carries meaning an adapter can preserve or transform. An undifferentiated HTML string makes each destination infer that structure again. Keep the canonical model expressive and the delivery payload selective. The IONOS discussion of CMS delivery performance recommends keeping API payloads around 5 MB or less. For a long illustrated essay, fetch body blocks or media references separately rather than attaching every related object to every response.
Transform meaning before styling
Format and length rules by channel
| Channel | Length or format guidance | Transform before sending | Check before sending |
|---|---|---|---|
| X post | Keep each post short enough to read in the feed without truncation; split longer ideas into a thread | Give each post one point | Thread order and first-post hook |
| LinkedIn post | Keep the post focused and easy to scan in the feed | Remove Markdown symbols and preserve line breaks | Hashtags and opening line |
| Substack Note | Short form, one idea and one link | Shorten to one idea with one link | Link preview and image |
| Substack article | Full article with subtitle and preview text | Preserve block structure and set the paid split point | Preview text and paywall position |
| Medium article | Destination-compatible headings, images, and body | Convert blocks and add a canonical link where supported | Tags and canonical link |
| Canonical object payload | Keep the response focused on the requested content | Split long articles into retrievable blocks | Fetch localized variants only when needed |
Treat destination limits as configuration, not constants embedded throughout your code. An editorial model describes meaning; a transport format describes how a connector sends it. The canonical article can use structured blocks even when a destination expects HTML.
For a closer look at preserving native formatting during cross-platform publishing, compare the transformed draft with its source. Check headings, image captions, links, and emphasis, not only whether the request succeeded.
Serve the variant the channel needs
Localization can make a response larger than necessary. Request the intended language rather than shipping every translation, and exclude internal annotations from public representations.
Caching must respect those choices. RFC 9111 defines reusable cached responses and freshness controls. Design each representation so an intermediary can distinguish public content from private or language-specific material.
Writers can bring existing content into a workflow from Substack and Medium archives, personal blogs, WordPress, Ghost, Notion, Google Docs, public URLs, CSV, and Markdown. Normalize imported content before deriving destination posts, especially image references, embedded content, and paywall boundaries.
Caching and Conditional Requests That Protect Content
A fast response isn't enough if it contains yesterday's correction or someone else's draft. Separate freshness, validation and invalidation so each has a clear responsibility.
This hierarchy shows how the controls fit together.

Freshness governs reuse
Choose cache policies by representation, not by applying a single global header. A versioned image can remain reusable because changing the image creates a new URL. A publication feed needs a shorter freshness window because its contents change.
| Representation | Example policy pattern | Operational requirement |
|---|---|---|
| Versioned article body or image | public, long max-age, immutable |
Never change content at that versioned URL |
| Public article feed | Short s-maxage, optionally stale-while-revalidate |
Accept brief staleness deliberately |
| Authenticated editorial view | private where local caching is acceptable |
Prevent shared reuse |
| Sensitive draft | no-store |
Don't retain the response in caches |
private doesn't mean “never store.” It restricts shared caching; use no-store when retention itself is inappropriate.
Validators govern correctness
An ETag identifies a selected representation. On a later read, the client submits it through If-None-Match; an unchanged representation can produce 304 Not Modified without another response body, as described in the HTTP conditional-request specification.
For editing, use a strong validator with If-Match. Say an editor opens the approved introduction, another editor corrects it, and the first editor then saves an older draft. The server rejects the stale write rather than erasing the correction.
- Unchanged read: Handle
304by retaining the stored body. - Stale edit: Handle
412 Precondition Failedby fetching the latest representation and resolving the difference. - Missing write condition: In a contract requiring conditional writes, use
428 Precondition Requiredto request the missing precondition.
A matching ETag proves representation equality, not editorial approval. Store approval state separately, and make sure the release worker checks both.
Invalidation governs change
When an article is published or corrected, invalidate affected feed entries and mutable article URLs. Leave unrelated articles cached. Versioned URLs usually don't need purging because the new version gets a different address.
Include every representation-changing input in the cache design: language, compression, media type and authorization context. Don't solve authorization differences merely by adding a user identifier to a shared cache key; first decide whether shared caching is appropriate at all.
For multi-platform delivery, this keeps repeated article and public-summary reads away from the application database when cached reuse is safe. It also gives a correction a defined release path instead of relying on editors to refresh pages until the new text appears.
How to Schedule a Multi-Platform Publishing Sequence
Plan distribution around the reader's decision to open the article, not around the moment you finish writing it. A teaser, launch announcement and follow-up should offer different reasons to care.
The sequence below keeps the original article at the center.

Queue the editorial sequence
Introduce the question before publication. In a worked schedule, place a pre-article Note two to three days ahead of the essay. Ask the question the article answers, without promising conclusions you haven't approved.
Publish the Substack article. Record the final title and canonical URL after confirming that the intended audience can access it. For paid content, verify that discovery posts expose only the intended preview.
Follow with a launch-day Note. Schedule it after the article's release, using the approved URL and a representative quote. The dependency matters more than simultaneous timestamps: the link should resolve before the Note appears.
Add a later follow-up. Choose another angle, such as an objection, example or practical application. Don't repost the same announcement with a different opening sentence.
Queue LinkedIn, X and Medium derivatives. Give each destination an appropriate introduction and route readers toward the original article. Where Medium supports a canonical setting in your publishing method, verify it rather than assuming a body link performs the same job.
Check the time zone before saving. Substack's scheduling interface uses the creator's local time zone, according to Substack's scheduling announcement. Your proposed API contract should require an ISO 8601 timestamp with an explicit UTC offset.
Keep the queue editable
On the web, open the Notes composer, select the calendar icon, choose the date and time, save, then confirm scheduling; on iOS and Android, open the three-dot menu and select Schedule, following Substack's Notes guide. Scheduled Notes remain in Drafts, where you can revise them before publication.
Treat the queue as editorial work, not a locked batch. Recheck queued links when the canonical URL changes, and remove supporting posts if the article is delayed.
A scheduled post is a promise to publish a particular version, not permission to publish whatever happens to be in the editor later.
Use a multi-channel publishing checklist to review the whole sequence together. The outcome is an article with several purposeful distribution moments, rather than an announcement burst followed by silence.
Automating Distribution to Substack, Medium, LinkedIn and X
| Stage | Illustrative operation | Required check |
|---|---|---|
| Ingest | GET /v1/articles/{id} |
Approved version matches the retrieved representation |
| Derive | Run a transformation operation or internal function | Each derivative passes destination validation |
| Schedule | POST /v1/schedules |
Time, offset and dependencies are correct |
| Distribute | POST /v1/articles/{id}/distributions |
Destination, version and idempotency key are recorded |
| Measure | GET /v1/articles/{id}/stats |
Results map to the source and destination post IDs |
The publishing process should include an explicit review gate before release.

Make every stage inspectable
Say an approved essay becomes a Substack Note, a LinkedIn post and an X thread. Store each derivative with its source article ID, source version, destination and review status. If the author changes the conclusion, the system can identify which queued derivatives require another review.
Not every stage needs an external HTTP call. Derivation might be an internal function, while publication uses a supported connector or native workflow. An endpoint named distributions doesn't create access to a destination that hasn't granted publishing permissions.
Apply these safety rules:
- Ingest: Fetch the approved representation, not just the most recently edited draft.
- Derive: Preserve the meaning and distinguish paid-source material from public previews.
- Schedule: Record dependencies so supporting posts don't precede an unavailable article.
- Distribute: Recheck the source version and send an
Idempotency-Keyscoped to the article version and destination operation. - Measure: Retain platform-specific metrics and label attribution limits instead of treating every interaction as a subscriber conversion.
Idempotency requires server-side support. The receiver must store the operation's outcome and return it for a repeated key; adding a header alone doesn't prevent duplication.
Coordinate without replacing the channels
Teams can keep Substack, Medium, LinkedIn and other channels while using Narrareach as the operating layer across them. Our workflow helps prepare, schedule, distribute and evaluate content, so writers can grow their audience through consistent, platform-specific distribution without maintaining unrelated manual queues.
Review the available publishing integrations against the operations your workflow needs. Confirm that an article shows selected platforms, scheduled items, related follow-up posts and available subscriber or engagement signals.
This demonstration provides another view of the publishing workflow.
After publishing, verify the destination post itself. A successful submission can mean accepted for processing, not publicly available, so keep separate states for queued, submitted, published and failed.
Common Integration Mistakes and How to Fix Them
The most expensive failure is a pipeline that relocates copy-and-paste work into scripts without removing it. Editors still repair formatting, developers maintain destination-specific exceptions, and nobody can show that publishing takes less effort.
For a full CMS replacement, Mordor Intelligence's headless CMS market analysis includes a 2025 enterprise estimate of 16 to 24 weeks for core model configuration and integration wiring. That isn't a small writer's distribution timeline, and it doesn't cover every frontend, governance or training cost.
Diagnose the symptom before rebuilding
Common integration problems, symptoms and fixes
| Problem | Symptom | Fix |
|---|---|---|
| Stale overwrite | One edit erases another | Send If-Match; resolve a rejected write against the current article |
| Oversized payload | Slow responses and timeouts | Enforce a response budget and retrieve body blocks selectively |
| Deep nested includes | Latency grows with each channel | Keep reference depth low and request only needed fields |
| Wrong cached variant | Old or inappropriate text appears | Separate representation keys and invalidate affected resources |
| Timezone drift | Posts go out at the wrong hour | Require an explicit offset and preview the local publication time |
| Duplicate post | The same post appears twice | Use supported idempotency and retain destination operation receipts |
| Migration overrun | Launch slips by months | Separate CMS replacement from distribution automation and phase coexistence |
“One source” shouldn't mean “one oversized response for every consumer.” A feed needs summary fields; a renderer needs body blocks; a performance report needs delivery identifiers and metrics. Requesting everything for each job increases transfer, parsing and debugging work without improving editorial reuse.
Prove that the migration removes work
Keep the existing publication route available while testing a new derivative workflow. Start with approved articles and a limited destination set rather than importing every abandoned draft and historical embed.
- Inventory dependencies: List media storage, previews, paywalls, scheduled items and existing integrations.
- Set rollback criteria: Pause automated release if permissions, destination verification or source-version tracking fails.
- Count the full cost: Include editorial retraining, integration maintenance, preview environments and observability.
Don't retire the old workflow merely because the new API returns successful responses. Retire it when editors can complete the publishing job with less manual repair.
Run a worked comparison over at least four weeks of publishing. Log copy-pasting and correction time per article, include failed deliveries, and compare like-for-like destination sets. Keep the migration only if it reduces operational work rather than hiding it in a different team's queue.
Start Your First Automated Publishing Workflow
A practical target for this week is straightforward: turn an approved article into a scheduled Substack Note, LinkedIn post and X thread without manually reconstructing the argument for each destination. Start with an article you already trust, not a simultaneous experiment in writing, migration and automation.
Ready to automate
Sign up with Narrareach, connect Substack and another destination, and run your next article through ingestion, derivation, review, scheduling and verification. We're designed for writers who already publish consistently and need scheduled distribution across channels.
Developers can begin with our REST API endpoints or Narrareach n8n node. Our LLM connector also lets Claude, ChatGPT, Gemini or any MCP-compatible agent read drafts, schedule posts and automate supported Substack, Medium, LinkedIn, X, Bluesky and Threads workflows.
Prefer to keep your current tools
Bookmark this reference and keep the endpoint and formatting tables beside your editor. Follow the Narrareach blog for distribution and API practice, then apply the same source-version discipline to your current scheduler.
Use this acceptance checklist before expanding:
- Identity: Every derivative retains its canonical article reference.
- Approval: The scheduled version is the version you reviewed.
- Destination: Formatting, links and visibility pass inspection.
- Timing: Publication times display correctly in the intended local zone.
- Verification: Published posts have destination receipts and reviewable results.
For a four-week self-test, publish an article each week and record the minutes spent copying, reformatting and repairing its distribution. Compare the opening and closing weeks without claiming an audience-growth result from such a small sample. Less manual handling is the first outcome to prove; better audience decisions come from reviewing what readers engage with.
Narrareach helps you turn approved articles into platform-specific posts and Notes, schedule their distribution, and review what resonates across channels. If you're ready to replace disconnected publishing queues, visit Narrareach and start with your next article. If you're not ready to change tools, bookmark this guide and follow our blog while you test the workflow in your existing setup.