Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.discovr.media/llms.txt

Use this file to discover all available pages before exploring further.

What is a row?

Rows are the horizontal recommendation rails on a page—each row is a scrollable list of titles, categories, or streaming providers. After you fetch a page, you paginate through its rows and load items (titles) from each row your user scrolls into. Rows come in four types: media (title thumbnails), top_n (ranked lists), navigation (drill-down destinations), and provider (filter by streaming service). You use the row type to pick the right cell layout, and each item’s type to render appropriately.
Rows APIs require an active profile session (start with selectProfile()). See Sessions, Profiles & Sign Out for setup. Code snippets use TypeScript, Kotlin, and Swift tabs.

How rows surface in your app

  • getRows() lists row shells on a page: id, title, pageId, type, createdAt. Rows are created on demand and the list is paginated (hasMore, nextPageToken).
  • getRow() loads one row by id if you only need a single rail’s metadata.
  • getRowItems() loads items for that row—also paginated. Every item includes a type discriminator: media, navigation, or provider.
Use row.type for the rail and each item’s type for the cell. Field names are spelled out under Row and Row item in Type referenceMedia, Navigation, Provider—and the same JSON is returned by getRow(), getRowItems(), and Get items in a row.
If the page is stale for the current session, getPage() can return 401 SESSION_EXPIRED; follow Error handling to recreate the page. Paging row items for rows you already hold is designed to stay usable while you finish scrolling a rail.

media rows

Classic horizontal title rails: items are type: "media" with poster/backdrop URLs and media_type (movie or tv). Use the same cell layout you would for any browse strip.
Light theme UI screenshot: horizontal media row labelled 'Media Row' with rectangular movie or TV thumbnail cards (posters visible), left-to-right scroll, typography and spacing typical of a streaming browse rail; illustrative Discovr client layout.

top_n rows

Visually, treat top_n like media: items are still media-shaped (same fields as media items). Discovr uses the separate top_n row type to signal editorial “top‑N” style rails versus generic media mixes—useful if you want different labels, ordering emphasis, or analytics. If you only need one poster rail renderer, media and top_n can share it—the only extra signal is type: "top_n" on the enclosing Row.
Light theme UI screenshot: horizontal top-N editorial row with a section title suggesting a ranked or curated list (e.g. top titles), rectangular poster-style cards similar to media rails, carousel-style horizontal layout; illustrative Discovr browse surface.
Navigation rows surface destination pages: each item is type: "navigation" and carries page_id for where to push next (stack depth lives in Pages overview). Optional vertical_path / horizontal_path back tile artwork.
Light theme UI screenshot: navigation rail with wide rectangular genre or destination tiles (category-style labels and artwork), horizontally scrollable, leading to nested browse pages via page identifiers; illustrative Discovr navigation row.

provider rows

Provider rails list streaming services: each type: "provider" tile exposes paths (square logo URLs keyed roughly by size—"60", "100", …) and a page_id for that provider hub. After a tap, load that page with getPage() / getRows().
Light theme UI screenshot: horizontal provider row labelled for streaming platforms, square logos of services in evenly spaced cells on a pale background, implying each logo maps to ProviderItem.paths and drills into ProviderItem.page_id; illustrative Discovr UI.

Load rows and items

After you have a pageId (from createPage() or a page_id on an item), fetch row metadata, then items for the rails you render.
import { DiscovrClient } from "discovr";

const discovr = new DiscovrClient("your-client-id", {
	basePath: "https://api.discovr.media",
});

const pageId = "your-page-id";
const { rows, hasMore, nextPageToken } = await discovr.getRows(pageId, { limit: 10 });

for (const row of rows) {
	switch (row.type) {
		case "media":
		case "top_n":
			break;
		case "navigation":
		case "provider":
			break;
	}
}

const first = rows[0];
if (first) {
	const items = await discovr.getRowItems(pageId, first.id, { limit: 20 });
	for (const item of items.items) {
		if (item.type === "media") {
			console.log(item.title, item.mediaType);
		} else if (item.type === "navigation" || item.type === "provider") {
			console.log(item.title, item.pageId);
		}
	}
}