A page is the personalized browse screen your user sees after selecting a profile. It has two main parts: a hero carousel at the top (featured titles), and recommendation rows below (each row is a horizontal “rail” of media). After your user selects a profile, you fetch a page withDocumentation Index
Fetch the complete documentation index at: https://docs.discovr.media/llms.txt
Use this file to discover all available pages before exploring further.
createPage() and getPage(). Discovr fills the page’s rows with personalized recommendations based on that profile’s viewing history. Rows come in four types—media (movie/TV thumbnails), top_n (ranked lists), navigation (drill-down destinations), and provider (filter by streaming service). See Rows overview for details and pagination.
Pages APIs require an active profile session. Start with
selectProfile(), then fetch pages. See Sessions, Profiles & Sign Out for setup. Code snippets use TypeScript, Kotlin, and Swift tabs.getPage(), stacked rails from getRows().

Hero vs rows
getPage()returns the page envelope, includinghero(the large carousel at the top—ten spotlight-style items).getRows()returns rows on that page, created on demand and paginated. Your UI stacks them vertically and scrolls; each row can be tapped for items or destinations as the row type implies.
createPage() calls with the same pageFilters in the same session reuse the same page id (deterministic snapshot for that browse context).
Typical “tabs”: Home, Movies, Series
Apps often expose top-level browsing as tabs or modes. Discovr does not ship tab UI—you map each tab to a page created with filters:| Idea | Approx. createPage body | Purpose |
|---|---|---|
| Home / mixed | {} — omit pageFilters or send empty filters | Broad, default browse |
| Movies | { "pageFilters": { "media_type": "movie" } } | Movie-first rail mix |
| Series | { "pageFilters": { "media_type": "tv" } } | TV-first rail mix |
name ("Movies", "Series", etc.) when you store or debug tabs—responses can surface it depending on origin.
Stack-like navigation from rows
Some navigation-style rows don’t stop at scrolling: choosing an item pushes the user onto another page (a newpageId and its own hero + rows). Treat that like a navigation stack: opening a drill-in pushes a page on your stack; system back pops it.
Today, deepest reachable depth is three levels counting the root—think root, then one drilled page, then one more leaf page. Going further purely via row-based navigation isn’t supported; design your UX accordingly.
Build the first surfaces
Use this flow once the SDK has a session for the chosen profile (selectProfile()).
Create pages for each top-level tab
Call
createPage() for Home (no filters), Movies (media_type: "movie"), and Series (media_type: "tv"). Persist each returned id for that tab.Fetch hero metadata and rows
Render the carousel from
getPage(tabPageId) and list rails from getRows(tabPageId) (optionally getRow() / getRowItems() once you drill into one row).Handle push navigation from rows
When a navigation item resolves to another destination, you usually receive a distinct
pageId: push that screen and load it with the same layering—getPage for the hero, getRows (then getRow() / getRowItems() when you open a rail). Pop back to the previous browse surface when the user navigates backward. Respect the three-level cap above when designing nested browse.What’s next
- Rows overview — row
type, item shapes, and pagination withget-row/get-row-items - Media details — open a title from hero or rails:
getMedia, images, TV seasons/episodes, similar - Profile context — like/watchlist/playback, overlays, and scrobbling for the active profile
