> ## Documentation Index
> Fetch the complete documentation index at: https://docs.frontic.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

The API Builder turns your [Data Storages](https://docs.frontic.com/data-integration/data-storages.md) into the **exact API surface** each part of your experience needs.

**api-builder/overview**

API Builder overview showing a list of Detail Blocks and Search Listings

![API Builder overview showing a list of Detail Blocks and Search Listings](https://mintcdn.com/frontic/hS7rYTW0C-o2HHTZ/images/api-builder/overview-light.png?fit=max\&auto=format\&n=hS7rYTW0C-o2HHTZ\&q=85\&s=111e6ddd4d9b4042136c927af74a0bd0)

API Builder - Detail Blocks and Search Listings in the admin app

One block per component, one listing per collection, one page per route, one tree per hierarchy - nothing more, nothing less. Your frontend asks for what it needs, and the backend returns exactly that, already scoped to the caller's Request Context.

> [!TIP]
>
> [Buddy](https://docs.frontic.com/essentials/buddy.md) can create and configure Detail Blocks, Search Listings, and Page URLs for you. Describe what your experience needs and Buddy handles the setup.

## The primitives

> [card] [Detail Blocks](https://docs.frontic.com/api-builder/blocks.md)
>
> *What fields does this component need?* An API endpoint that returns
> the exact data one UI component needs - reusable, parameterized, nestable.

> [card] [Search Listings](https://docs.frontic.com/api-builder/listings.md)
>
> *How do I query a collection?* Filtering, sorting, full-text search,
> pagination, and facets - each item shaped like a block.

> [card] [Page URLs](https://docs.frontic.com/api-builder/pages.md)
>
> *What renders at this URL?* Ties a URL pattern to a Detail Block so
> your router resolves content in a single request.

> [card] [Menu Trees (Preview)](https://docs.frontic.com/api-builder/trees.md)
>
> *What's the hierarchy?* Returns records as a tree - navigation menus,
> category hierarchies, anything with a parent/child structure.

## How they compose

**1. Define a Block for each UI component**

A **Detail Block** is an API endpoint shaped like a component. You
define a `ProductCard` block with a schema that returns exactly the
fields that component renders - image, title, price, badges, CTA
text. The block connects to a Data Storage and describes which
fields map into its response shape.

**2. Define a Listing that returns block-shaped items**

A **Search Listing** returns a collection of items, each shaped like
a block. A `ProductListing` listing takes a `category` filter
parameter and returns a list of `ProductCard`-shaped items, with
facets and pagination attached. Listings handle the query layer -
filter, sort, search, paginate - and delegate the per-item shape to
the block from the previous step.

**3. Define a Page to wire it all to URLs**

A **Page URL** ties a URL pattern to a single Detail Block. A
`Product Detail` page binds `/products/{slug}` to the `ProductCard`
block - each URL resolves to exactly one record, and the same block
schema your grid uses also drives the detail view. The response
includes the page type and the matching data, so your frontend
router can pick the right component and render it straight away.
The block itself can nest a `ProductListing` (e.g. related products)
when the page needs collections.

## Request Context

Every Detail Block, Search Listing, and Page URL response is shaped by the caller's **Request Context**. That means one block can serve many markets, many audiences, and many languages from a single definition.

Request Context is a combination of three values that together tell the backend *who's asking*:

> [card] Scope
>
> The **audience variant** - B2B vs. B2C, different brands, wholesale vs. retail.

> [card] Region
>
> The **geography** - which locales are supported, which currency applies.

> [card] Locale
>
> The **language** (`en`, `de`, `fr`) - translatable fields return the matching variant.

### Where context comes from

Your project maps domains (or paths) to `scope + region + locale` combinations in [Project Settings → Domains](https://docs.frontic.com/project-settings/domains.md). Pass the domain as `contextDomain` and Frontic resolves the matching context automatically.

> [tab] Client SDK
>
> ```ts theme={"theme":"css-variables"}
> const data = await client.block('CategoryDetail', 'running-shoes', {
>   contextDomain: 'www.demo-shop.com/de',
> });
> // Resolves → German region, de locale, public scope
> ```

> [tab] Nuxt Module
>
> ```vue theme={"theme":"css-variables"}
> <script setup lang="ts">
> // Nuxt module resolves context automatically from the request URL
> const { data } = await useFronticBlock('CategoryDetail', 'running-shoes')
> </script>
> ```

A typical domain mapping:

| Domain | Scope | Region | Locale |
| - | - | - | - |
| `www.demo-shop.com` | `public` | United States (USD) | `en` |
| `www.demo-shop.com/de` | `public` | Germany (EUR) | `de` |
| `b2b.demo-shop.com` | `b2b` | United States (USD) | `en` |

### Why this matters

* A `ProductListing` listing in the German domain returns the German product catalog in EUR with German copy - without market-specific code.
* A `ProductCard` block in a B2B scope returns B2B-specific images, descriptions, and pricing for the same product - without a separate B2B block.
* A Page at `/products/:slug` resolves to different URLs and different records in every domain - without duplicate route definitions.

You write each primitive once. The backend delivers the right variant based on who's asking.

### Handle context keys

Every response includes a `contextKey` in the `fs-context` header. This key tracks the session's context settings - scope, region, locale - and lets overrides survive across requests.

* **No key sent** → Frontic generates a new one with the settings from the resolved domain and returns it in the response
* **Your own key sent** (any string, 36–50 characters) → Frontic persists it with the current context settings if it doesn't exist yet, or loads the stored settings if it does
* **Key sent on subsequent requests** → Frontic applies the stored settings, even if they differ from the domain default

Store the key from the first response and pass it on every subsequent request. When a visitor switches language or currency, update the key's settings - all following requests reflect the change without touching the domain mapping.

> [!NOTE]
>
> The [Nuxt module](https://docs.frontic.com/reference/nuxt-module.md#the-context-token) does this for you:
> it persists the key in a cookie and sends it on every call, so a switch through
> `useFronticContext` reaches the next request without any wiring.

#### Updating an existing contextKey

To change a visitor's active locale or region without minting a new key, update the stored settings on the current `contextKey` - the [Client SDK](https://docs.frontic.com/reference/client-sdk.md#client-contextupdate) and the [Nuxt module](https://docs.frontic.com/reference/nuxt-module.md#usefronticcontext) both expose methods for this so you don't hand-craft the HTTP call. Every subsequent request using the same key reflects the change.

> [tab] Client SDK
>
> ```ts theme={"theme":"css-variables"}
> await client.contextUpdate(
>   { region: 'eu', locale: 'de-DE' },
>   contextKey,
> );
> ```

> [tab] Nuxt Module
>
> ```ts theme={"theme":"css-variables"}
> const { update } = useFronticContext();
>
> await update({ region: 'eu', locale: 'de-DE' });
> ```

Common triggers:

* A visitor opens a language selector and switches from `en` to `de` - update the key with the new locale.
* A visitor picks a different market from a region dropdown (United States → Rest of Europe) - update the key with the new region; currency follows the region's setting.
* A visitor updates their preferences on a profile screen - update whichever settings changed.

### Missing or ambiguous context

If a request has no `contextDomain` or the domain doesn't match any configured mapping, Frontic falls back to the project's default region and locale. A missing `contextKey` is never an error - Frontic creates a new one automatically. An unknown key is treated the same way: persisted as a fresh context with the current domain settings. The only invalid key is one that doesn't meet the format requirements (36–50 characters).

## API Playground&#x20;

> [!NOTE]
>
> Preview - the API Playground is in early access. It runs against your live backend today, but the UI and feature set are still settling before general availability. [Reach out](mailto:support@frontic.com) if you want to try it.

Every Detail Block, Search Listing, Menu Tree, and Page URL has a built-in **API Playground** accessible from its detail page. It lets you send real requests against your backend, inspect responses, and experiment with API version, context, filters, and parameters - without writing code or leaving the admin app.

The playground shows the full endpoint URL, picks the [API version](https://docs.frontic.com/releases/overview.md#api-versions) to target (develop, preview or public), lets you configure headers (`fs-version`, `fs-secret`, `fs-domain`, `fs-context`), and generates ready-to-use code snippets from your current configuration. A resource sheet in the dialog header lets you swap between primitives - pages, blocks, listings, and trees - without closing and reopening. See [Detail Blocks](https://docs.frontic.com/api-builder/blocks.md#api-playground), [Search Listings](https://docs.frontic.com/api-builder/listings.md#api-playground), [Menu Trees](https://docs.frontic.com/api-builder/trees.md#api-playground), and [Page URLs](https://docs.frontic.com/api-builder/pages.md#api-playground) for the full details.

**api-builder/playground**

API Playground dialog showing request configuration on the left with parameters, filters, and sorting, and JSON response on the right with status and timing badges

![API Playground dialog showing request configuration on the left with parameters, filters, and sorting, and JSON response on the right with status and timing badges](https://mintcdn.com/frontic/YiN8HmiGFMy2ycGP/images/api-builder/playground-light.png?fit=max\&auto=format\&n=YiN8HmiGFMy2ycGP\&q=85\&s=b5f419ccd84519221a10a112e259ef8c)

API Playground - testing a Search Listing with filters and context

## Shipped through Releases

Changes to blocks, listings, and pages ship through [Release Control](https://docs.frontic.com/releases/overview.md) alongside Data Storage schema changes, Data Sync changes, and project settings. You don't ship API changes piecemeal: you preview a version that carries everything that changed, test it, and publish it as one unit.

## Where to go next

> [card] [Build a Block](https://docs.frontic.com/api-builder/blocks.md)
>
> Schema, parameters, storage connection, nesting - everything blocks can do.

> [card] [Build a Listing](https://docs.frontic.com/api-builder/listings.md)
>
> Filters, sorts, search, facets, and pagination.

> [card] [Build a Page](https://docs.frontic.com/api-builder/pages.md)
>
> Routing, URL patterns, localization, error handling.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.