Skip to content

Home

Status: Live

Today's Quote (CSL-141), Theme of the Week (CSL-137), Featured Journeys (CSL-145), What's New (CSL-142), Featured Books (CSL-143), and Further Reading (CSL-144) are implemented. All six sections are live.

The Home feed is the app's landing surface: a fixed sequence of six curated sections. It is editorially assembled, not algorithmic — editors decide what appears, with two sections drawing automatically. Home is configured from a single CMS screen (the Home settings record) and stands in for the eventual Home content type (CSL-42).

The six sections

Section order is fixed and known to the FE (not user-reorderable). An empty non-mandatory section renders nothing and the FE closes the gap; the hero is the one mandatory section (its absence is a page error, not an empty state).

# Section How it's populated Endpoint Status
1 Today's Quote (hero) Editorial — the Home quote queue in editor order, one a day; falls back to newest-published when the queue is empty GET /api/passages/todays-featured/ Live
2 Featured Journeys Editorial — the Featured Journeys list in editor order (≤5), published journeys only GET /api/journeys/featured/ Live
3 Theme of the Week Editorial — one editor-set theme + label; supplies the page wash GET /api/themes/featured/ Live
4 What's New Editorial + auto — editor pins first, then newest eligible Articles/Writings (cap 10) GET /api/whats-new/ Live
5 Featured Books Editorial — the editor's manual list order (cap 10) GET /api/books/featured/ Live
6 Further Reading (a.k.a. What's Trending) Automatic — random over essays + letters GET /api/further-reading/ Live

One endpoint per section

Home is served as one endpoint per section, not a single aggregate call: most of Home sits below the fold, so the FE loads the hero first and the rest lazily / in parallel, and each section carries its own cache window. Every section endpoint is public, app-key–gated, user-agnostic, and cacheable; per-user state (bookmarks, progress) is overlaid by the FE from the /api/account/ endpoints.

Conventions for all sections

Every section endpoint is app-key-gated (X-API-Key). The hero quote queue (/api/passages/todays-featured/) returns full passage text, so it also needs a content-access token and is cached by the app only (see Content access). The other sections use Cache-Control: public, max-age=<n> plus an ETag, a tunable window with cheap If-None-Match revalidation. For the details, see the Caching section in API Conventions. No response carries per-user fields. A section with nothing to show returns 200 with {"items": []}, and the FE hides it.

Endpoint map

Section Endpoint Guide
Today's Quote (hero) GET /api/passages/todays-featured/ Passages API
Theme of the Week GET /api/themes/featured/ Themes API
Featured Journeys GET /api/journeys/featured/ below
What's New GET /api/whats-new/ below
Featured Books GET /api/books/featured/ below
Further Reading GET /api/further-reading/ below

Today's Quote and Theme of the Week

These two sections reuse endpoints documented elsewhere, so this guide does not restate them. The Passages API guide covers todays-featured, which returns a rotating pool of up to 10 passages that the FE cycles per session. The Themes API guide covers themes/featured/, which returns the featured theme_id and its slot header, both null when nothing is featured.

Up to 5 journey cards in the editor's Featured Journeys list order.

What appears. The Journeys an editor added to the Featured Journeys list, in the order they arranged them. The list is fully manual, with no auto-fill, like Featured Books. Only published journeys appear: a draft is skipped, and a journey featured twice shows once. Deleting a Journey removes its featured entry automatically.

chapters_count is what a reader can open. For a live journey that is every chapter it was authored with, because the CMS refuses to unpublish a piece a live journey is built on. The count is derived rather than stored so it cannot drift, and a journey with nothing readable left would be dropped from the carousel rather than advertised. See Journeys.

The journey card. A journey has no reading surface of its own, its chapters do, so the card has no body and no read_time_minutes. This is a single-kind list, so the card carries no kind, the same convention as Featured Books. The fields worth knowing:

  • description is the pitch shown on the card. The app shows the opening lines behind a "see more". It is an empty string when unset.
  • primary_theme_id is the journey's theme, or null when an editor has not set one. It resolves the card's theme treatment — colour and surrounding design — from the client's cached theme set, falling back to the active theme when null, the same rule every other themed card follows. A journey has no colour of its own; that moved onto the theme. It does still own its emblem, below: the theme supplies the treatment, the emblem is the journey's own picture.
  • emblem is the journey's artwork as a rendition set of small, medium, large, xlarge, xxlarge and original, or null. Use original to tint it with the theme colour: the WebP sizes are lossy. It is one image doing two jobs: the card artwork and the thing the reader collects at the end. The app blurs it and lifts the blur as chapters complete, so there are no reveal states to serve.
  • chapters_count is how many chapters the reader can open, as above.

No reader state. The response carries no progress, no completed chapters, and no collected emblem, so it stays cacheable for everyone. Reader-specific journey state belongs on a separate per-user endpoint.

What's New: GET /api/whats-new/

Up to 10 content cards for the Home "What's New" carousel.

What appears. Articles (contemporary editorial) and Writings (letters, essays, and chapters). Passages are excluded, because they already headline the hero, so repeating them would be redundant.

Ordering. Pins come first, then auto-fill, capped at 10:

  1. Editor pins hold the front, in the editor's drag order. A pin only needs to be published to show.
  2. Auto-fill takes the remaining slots with the newest eligible pieces (flagged is_new_eligible), by publication date, newest first, merged across Articles and Writings.
  3. Auto-fill never repeats a pinned piece (it is deduped), and a piece pinned twice shows once.

The content card. What's New is a mixed-kind list, so every card carries a top-level kind of article, letter, essay, or chapter. Each card references a theme by theme_id only, and the FE resolves the design from its cached theme set. Three fields are derived, not stored:

  • supporting_line is a short second line: an article's subtitle, who a letter was written to, or the Work a writing is drawn from. It is empty when there is nothing to derive it from. The copy is provisional, pending FE and design.
  • image is the piece's card image (Article featured_image or Writing image) as a rendition set of small, medium, large, xlarge, xxlarge and original, or null.
  • read_time_minutes comes from the body word count. It is null when there is no body.

Up to 10 book cards in the editor's Featured Books list order.

What appears. The Books an editor added to the Featured Books list, in the exact order they arranged them. The list is fully manual, with no auto-fill, unlike What's New. Only published books appear. A draft is skipped, and a book featured twice shows once. Deleting a Book removes its featured entry automatically.

The book card. Books are reference and purchase objects, so the card has no reading surface: no body and no read_time_minutes. This is a single-kind list, so the card carries no kind, the same convention as the passage endpoints. The fields worth knowing:

  • synopsis is the Work's blurb, projected to Markdown. It is an empty string when unset.
  • cover is the cover image as a rendition set of small, medium, large, xlarge, xxlarge and original, or null.
  • buy_cta is an optional external link to buy this edition, for example on Amazon. When it is set, the FE renders a "buy" CTA that links out of the app. It is null when blank, so the FE omits the CTA. The link is a discovery and buy hand-off, not an in-app purchase or paywall.
  • publication_year is the edition's year, or null.

The cover, publication details, and purchase link should all describe the same edition. Keeping them in step is an editorial responsibility, supported by the cover guidance and validation in the CMS. See the Home editor guide.

Further Reading: GET /api/further-reading/

Up to 10 content cards for the Home "Further Reading" shelf, also called "Keep Discovering". This is the closing discovery section.

What appears. A pool drawn from all live essays and letters (Writing of kind essay or letter). It is auto-pulled, not curated, so there is no editorial list. Chapters (journey-internal), Passages (the hero), Books (no reading surface), and Articles (editorial) are all excluded.

How the pool is drawn. The draw is random but daily-stable. The server shuffles the eligible set with a per-day seed and returns up to 10. The pool is stable for a caller within the day (cacheable, with a steady ETag) and rotates day to day, so the whole corpus surfaces over time. As with the hero, per-session freshness is client-side: the FE cycles within the returned pool. This endpoint has no ?exclude= cursor, unlike the hero, and serves the pool whole.

The content card. The shape is identical to What's New: a mixed-kind card, where kind is letter or essay, with the same derived supporting_line, image, and read_time_minutes fields, and a theme_id reference. An empty pool returns {"items": []}.

See Swagger for the precise field lists, cache windows, and status codes.