Skip to main content
The content API is headless. Your club writes articles in the 4D console; your website reads them over HTTP and renders them itself, on your own domain, with your own stylesheet. 4D stores and renders the article body; nothing about how it looks on your site is decided here. Two endpoints, both read-only: Both are documented in full on Articles.

Base URL

Production base URLs are provided during onboarding.

Before your first request

Two things have to be true, and both are done in the console rather than over the API:
  1. The content module is installed for your organization, on the integrations page. A club without it gets a 403 from both endpoints and loses no writing: uninstalling stops the API and deletes nothing.
  2. You hold a content key with your site’s origin on its allowlist. The key is publishable and the allowlist is what protects it. See Authentication.
Every request then has to carry an Origin header naming one of those registered origins. Browsers set it for you. A server-side caller has to set it itself, and a request without it is a 403 however good the key is, so this is the first thing to check when a curl that looks right is refused.

Two body formats

Every article is served either as rendered HTML or as a flat list of blocks. The default is HTML.
  • ?format=html (the default) gives you one html string: the whole article body, already rendered and sanitised. Drop it into a container and style it with your own CSS. If you have no reason to prefer blocks, use this.
  • ?format=blocks gives you an ordered array of top-level blocks. Choose it when you want to render your own components for images and video rather than accepting our markup: for example, to route images through your site’s responsive image component or your CDN, or to use your own video player. Text blocks still arrive as HTML fragments, so choosing blocks does not mean re-implementing rich text. See Block format.
Both formats come from one render performed when the article is published, so the same article requested in both formats describes the same content, and a read never re-renders anything. One thing to know before you take the default: a video embed is a <div> in the HTML, not a player. We serve the address on that element and never an <iframe> from a third party. It renders as nothing until your site does something with it, so an article carrying video wants blocks or wants your own handling of that element. Articles has its shape.

Drafts are unreachable

The read API serves published articles only. An unpublished draft is a 404 even when its slug is guessed exactly, and it never appears in a list.

Interaction events

Reporting what a reader did with an article is a separate, write-side surface: POST /v1/content-interactions, one report per request. It reads best through the engagement SDK, which is one call from the page that just rendered the article:
Three things about it are worth knowing before you wire it:
  • It authenticates with a different key. Interactions ride the engagement rail and take a publishable tracking key (ek_live_…), not the content key these read endpoints take. One key per direction.
  • You do not send tags. The server reads the article’s tags off the article, so a read raises the member’s affinity for exactly the tags the marketer chose.
  • Only signed-in readers count. The report needs the reader’s platform user id. An anonymous reader is invisible rather than counted anonymously, which is why these numbers sit below a club’s own web analytics.
A read counts once per member, per article, per day, so a refresh does not inflate it. Render a club’s articles puts the call on a working page. Content interactions do not earn XP. There is no path from reading an article to a member’s XP balance, and none is planned: a read reported by a browser cannot be trusted to pay out. XP comes from engagement events under the rules your organization configures.

Where to go next

Authentication

Publishable keys, the origin allowlist, and what a rejected request gets back.

Articles

Both endpoints, every query parameter, and every response.

Block format

The eight block types and the fields each one carries.

Render a club's articles

A working page that lists articles and renders one.

Report a read

The one call that tells us a member read an article.