> ## 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.

# Storage Field Types

[Data Storages](/data-integration/data-storages) support the following field types.

<Note>
  The composite and enum shapes below are the **minimum guaranteed contract** every Frontic project ships with. Each can be extended — added fields on a composite, added keys on an enum — from **Settings → Data Types**. Custom additions appear alongside the built-ins on every record that uses the type, but the built-in fields and keys themselves can't be removed or renamed. Code written against the shapes below stays safe across every project; code that wants extensions reads them off the response when they're present. See [Data Types](/project-settings/data-types#extending-the-built-ins) for the extension flow.
</Note>

## Field capabilities

Each field on a storage carries a small set of flags that change how its value is stored, returned, and resolved per request. They're independent — a field can be array + translatable + scoped at the same time — and you set them when [adding or editing the field](/data-integration/data-storages#add-fields).

### `isArray`

Whether the field stores a list of values rather than a single value. The JSON return type becomes the array form (`string[]`, `Price[]`, and so on). Some composites are **always** arrays by design — `Option` and `Sorting` exist to be lists of attribute/value pairs and can't be set to single-value mode.

```json theme={"theme":"css-variables"}
{ "colors": ["Red", "Blue", "Green"] }
```

### `isTranslatable`

Whether the field has per-locale variants. The same field on the same record can hold different values per project locale; the API returns the value for the caller's resolved locale, falling back to the project's default locale when a translation is missing. Use this for any user-visible copy — product names, descriptions, marketing text.

```json theme={"theme":"css-variables"}
// Same record, different responses depending on the resolved locale
// en-US
{ "name": "Aurora Trail Runner" }
// de-DE
{ "name": "Aurora Trail-Läufer" }
```

### `isScoped`

Whether the field is segmented by [scope](/project-settings/scopes). A scoped field can hold a different value per scope (e.g. `b2b` vs `public`); the API returns the value for the caller's resolved scope. Use this for content that legitimately diverges across audiences — wholesale pricing on a B2B scope, audience-specific descriptions, scope-specific imagery.

`isTranslatable` and `isScoped` compose. A field that's both gives you one value per `(scope, locale)` pair.

<Note>The following capability applies only to fields on a Products storage.</Note>

### `sharedAcrossVariants`

This controls whether the field's value lives at the **product level** (one value shared across every variant of the product) or at the **variant level** (each variant has its own value).

* Shared examples: name, description, brand, breadcrumbs, hero imagery — they describe the product as a whole.
* Variant-level examples: price, size, SKU, stock — they describe a specific buyable item.

See [Product Models](/commerce-concepts/product-models#sharing-fields-across-variants) for the deeper trade-off and when to use which level.

## Primitives

Scalar values for simple data.

| Type       | JSON      | Description             |
| ---------- | --------- | ----------------------- |
| `String`   | `string`  | Text data.              |
| `Integer`  | `number`  | Whole numbers.          |
| `Float`    | `number`  | Floating-point numbers. |
| `Boolean`  | `boolean` | True/false values.      |
| `DateTime` | `string`  | ISO-8601 date and time. |
| `Any`      | `any`     | Any valid JSON value.   |

## Composites

Structured data types covering common commerce use cases. Each composite has a fixed inner shape that other configurations (Data Storages, Blocks) can reuse by reference.

### `Media`

Images, video thumbnails, and other assets — with alt text, MIME type, and an optional thumbnail variant.

<Expandable title="Fields">
  <ParamField path="key" type="string" required>
    Stable identifier for the media item.
  </ParamField>

  <ParamField path="src" type="string" required>
    Source URL.
  </ParamField>

  <ParamField path="mimeType" type="string" required>
    Asset MIME type (e.g. `image/jpg`).
  </ParamField>

  <ParamField path="altText" type="string">
    Alt text for accessibility.
  </ParamField>

  <ParamField path="thumbnailSrc" type="string">
    URL of a thumbnail variant.
  </ParamField>

  <ParamField path="type" type="string">
    Optional asset type marker.
  </ParamField>

  <ParamField path="position" type="integer">
    Sort position when the field is used as an array (gallery ordering).
  </ParamField>
</Expandable>

### `Option`

Product options (color, size, material). Always used as an array — auto-generates dynamic facets grouped by attribute when used as a filter in a [Search Listing](/api-builder/listings#dynamic-filters).

<Expandable title="Fields">
  <ParamField path="attribute" type="string" required>
    The option key (e.g. `color`). Keep this stable across translations for consistent filtering.
  </ParamField>

  <ParamField path="value" type="string" required>
    The specific choice (e.g. `Red`).
  </ParamField>

  <ParamField path="label" type="string">
    Display name for the attribute (e.g. `Color`).
  </ParamField>
</Expandable>

### `Price`

Prices with currency, precision, and optional reference price + tiered scales. The price `amount` is stored as an **integer in the smallest unit at the configured precision** — `amount: 4999, precision: 2` represents `49.99`. Resolved to the caller's currency via [Request Context](/api-builder/overview#request-context).

<Expandable title="Fields">
  <ParamField path="amount" type="integer" required>
    Price value, stored as an integer at `precision` decimal places (`4999` with `precision: 2` = `49.99`).
  </ParamField>

  <ParamField path="currency" type="string" required>
    ISO 4217 currency code (e.g. `eur`, `usd`).
  </ParamField>

  <ParamField path="precision" type="integer" required>
    Decimal places used to interpret `amount`. Typically `2` for major currencies.
  </ParamField>

  <ParamField path="ref" type="integer">
    Optional reference price for sale comparisons (e.g. the strike-through "was" price). Same precision as `amount`.
  </ParamField>

  <ParamField path="scales" type="PriceScale[]">
    Optional tiered prices for quantity discounts. See `PriceScale` below.
  </ParamField>
</Expandable>

### `PriceScale`

A single tier of a tiered price ladder — used inside `Price.scales` for quantity discounts.

<Expandable title="Fields">
  <ParamField path="amount" type="integer" required>
    Tier price, stored at the parent `Price`'s precision.
  </ParamField>

  <ParamField path="from" type="integer" required>
    Quantity threshold at which this tier applies.
  </ParamField>
</Expandable>

### `SEO`

Meta titles, descriptions, and keywords. Typically translatable. See [URLs & SEO](/commerce-concepts/urls-seo#seo-metadata).

<Expandable title="Fields">
  <ParamField path="title" type="string" required>
    Page title (`<title>`).
  </ParamField>

  <ParamField path="description" type="string" required>
    Meta description.
  </ParamField>

  <ParamField path="keywords" type="string[]">
    Optional keyword list.
  </ParamField>
</Expandable>

### `Sorting`

Parameterized sort positions for category-specific or collection-specific ordering. Always used as an array — when used as a [sort option in a listing](/api-builder/listings#dynamic-sortings), the parameter value is matched against the key to determine order.

<Expandable title="Fields">
  <ParamField path="key" type="string" required>
    Matches a listing parameter value (e.g. a category ID).
  </ParamField>

  <ParamField path="position" type="integer" required>
    Numeric sort position.
  </ParamField>
</Expandable>

### `Swatch`

Color or material swatches with a label, optional swatch image, and an optional hex color — for variant pickers and product grids.

<Expandable title="Fields">
  <ParamField path="label" type="string" required>
    Human-readable swatch label (e.g. `Forest Green`).
  </ParamField>

  <ParamField path="color" type="string">
    Hex color value for solid-colour swatches.
  </ParamField>

  <ParamField path="image" type="Media">
    Image for material/pattern swatches.
  </ParamField>
</Expandable>

### `Vendor`

Vendor/supplier identity — a key, display label, and optional logo.

<Expandable title="Fields">
  <ParamField path="key" type="string" required>
    Stable vendor identifier.
  </ParamField>

  <ParamField path="label" type="string" required>
    Human-readable vendor name.
  </ParamField>

  <ParamField path="image" type="Media">
    Vendor logo or brand image.
  </ParamField>
</Expandable>

### `Weight`

Weight value with unit.

<Expandable title="Fields">
  <ParamField path="value" type="float" required>
    Numeric weight value.
  </ParamField>

  <ParamField path="unit" type="string" required>
    Unit string (e.g. `kg`, `g`, `lb`).
  </ParamField>
</Expandable>

## Enums

String values with a discrete set of possible keys. You can customize the available keys.

### `Availability`

Availability status for products. Default keys: `in-stock`, `out-of-stock`, `preorder`, `backorder`. Google Merchant Center-compatible.

### `StockLevel`

Simplified stock display without exposing real inventory counts. Default keys: `low`, `medium`, `high`.

## Specials

### `Mapped Value`

A storage field whose value is resolved from another storage at query time, based on a shared key. Configure a target storage, a target field to read, and a source field on the current storage that holds the matching key. Good for brand names, category labels, or any reference data you'd rather not duplicate into every record. See [Mapped fields](/data-integration/data-storages#mapped-fields) for the full setup flow and constraints.
