Home API guide¶
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.
Orientation for the Home section endpoints. Swagger (/api/docs/, /api/redoc/) and the Linear
tickets hold the exact request and response schemas. This guide covers what each endpoint is and how
it behaves, not every field.
See Home for the concept and the six-section overview, and API Conventions for auth, errors, and caching.
Conventions for all sections¶
Every Home section endpoint is public, app-key-gated (X-API-Key), user-agnostic, and cacheable.
Caching uses 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:
editorial_framingis the pitch shown on the card. The app shows the opening lines behind a "see more". It is an empty string when unset.colouris the journey's own hex colour, for example#2F4858, ornulluntil design supplies one. Because the card is coloured by this, it carries notheme_id.emblemis the journey's artwork as a rendition set ofsmall,medium,large,xlarge, andxxlarge, ornull. 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, andxxlarge, 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, andxxlarge, 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.