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.
Featured Journeys: GET /api/journeys/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:
descriptionis 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_idis the journey's theme, ornullwhen 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 whennull, 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 itsemblem, below: the theme supplies the treatment, the emblem is the journey's own picture.emblemis the journey's artwork as a rendition set ofsmall,medium,large,xlarge,xxlargeandoriginal, ornull. Useoriginalto 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_countis 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:
- Editor pins hold the front, in the editor's drag order. A pin only needs to be published to show.
- 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. - 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_lineis 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.imageis the piece's card image (Articlefeatured_imageor Writingimage) as a rendition set ofsmall,medium,large,xlarge,xxlargeandoriginal, ornull.read_time_minutescomes from the body word count. It isnullwhen there is no body.
Featured Books: GET /api/books/featured/¶
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:
synopsisis the Work's blurb, projected to Markdown. It is an empty string when unset.coveris the cover image as a rendition set ofsmall,medium,large,xlarge,xxlargeandoriginal, ornull.buy_ctais 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 isnullwhen blank, so the FE omits the CTA. The link is a discovery and buy hand-off, not an in-app purchase or paywall.publication_yearis the edition's year, ornull.
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.