> For the complete documentation index, see [llms.txt](https://docs.premsoft.de/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.premsoft.de/en/plugins/product-configurator/store-api.md).

# Store API

> This page is aimed at **developers & integrators**. It describes the HTTP interfaces for using the configurator in a headless frontend (PWA, app, composable commerce).

The entire price-effective logic is available through the **Store API**. A headless client needs three building blocks: calculate the price, add to cart and (optionally) save/load configurations.

All Store API calls require the sales channel's `sw-access-key` header. The context (language, currency, customer) is carried as usual via `sw-context-token`. The configurator routes are **public** (`_loginNotRequired`), so they do not require a logged-in customer.

***

## Calculate the live price

```http
POST /store-api/prems/configurator/price
```

Recalculates the unit price, dimensions and interim results for a configuration. Not cached.

**Request body:**

```json
{
  "productId": "0199b586c0f273aa8d2f4e1b2c3d4e5f",
  "fields": {
    "color": "gold",
    "width": "30",
    "height": "20",
    "extras": ["gift_wrap", "express"]
  }
}
```

* `productId` *(string, required)* – ID of the product.
* `fields` *(object, required)* – map of **technical identifier → value**. Values are strings or arrays of strings (multiple choice).

**Response:**

```json
{
  "price": 149.0,
  "formattedPrice": "€149.00",
  "priceChanged": true,
  "measurements": { "width": 30.0, "height": 20.0, "length": 0.0, "weight": 2.5 },
  "interimResults": { "area": "Area: 0.06 m²" }
}
```

* `price` *(float)* – new unit price in the context currency.
* `formattedPrice` *(string)* – language/currency-formatted price.
* `priceChanged` *(bool)* – whether the configuration changed the price.
* `measurements` *(object)* – `width`, `height`, `length`, `weight` (recalculated or product values).
* `interimResults` *(object)* – map of field identifier → calculated display text.

If no (active) configurator exists for the product, the base price is returned with `priceChanged: false`.

***

## Add to cart

There is **no** dedicated cart route. Use the standard route and attach the `premsConfigurator` object at the **top level** of the request:

```http
POST /store-api/checkout/cart/line-item
```

**Request body:**

```json
{
  "items": [
    {
      "type": "product",
      "referencedId": "0199b586c0f273aa8d2f4e1b2c3d4e5f",
      "quantity": 1
    }
  ],
  "premsConfigurator": {
    "productId": "0199b586c0f273aa8d2f4e1b2c3d4e5f",
    "fields": {
      "color": "gold",
      "width": "30",
      "height": "20"
    }
  }
}
```

The server validates the fields server-side (required fields, e-mail/phone, min/max, allowed options). On violations it responds with a **ConstraintViolation**. On success the line item is enriched with the calculated price, the input values (for the checkout display) and, where applicable, calculated dimensions and a product number. Line items with different configurations are not merged.

> Price recalculation happens server-side on every cart operation – the client does not have to set the price itself.

***

## Save a configuration

```http
POST /store-api/prems/configurator/save
```

Requires **Save configuration** to be enabled in the sales channel (otherwise an error response).

**Request body:**

```json
{
  "productId": "0199b586c0f273aa8d2f4e1b2c3d4e5f",
  "fields": { "color": "gold", "width": "30", "height": "20" }
}
```

**Response:**

```json
{ "token": "8f14e45fceea167a5a36dedd4bea2543" }
```

* `token` *(string)* – public token of the saved configuration.

The token lets you restore the configuration later. In the classic storefront, the route `GET /prems/configurator/c/{token}` opens the share link and redirects to the product page with the query parameter `premsSavedConfig={token}`; a headless frontend reads the token itself and uses it to call the price route again or to load the saved values.

***

## Storefront routes (classic theme)

These routes are used by the bundled storefront and are usually not needed by headless clients:

| Route                               | Purpose                                          |
| ----------------------------------- | ------------------------------------------------ |
| `POST /prems/configurator/price`    | Storefront wrapper of the price route (XHR).     |
| `POST /prems/configurator/save`     | Save; additionally returns `shareUrl`.           |
| `POST /prems/configurator/change`   | "Change configuration" from the cart (redirect). |
| `GET /prems/configurator/c/{token}` | Open share link; redirect to the product page.   |

***

## Admin API: validate a formula

Only in the authenticated admin context (for custom backend extensions):

```http
POST /api/_action/prems-configurator/validate-formula
```

**Request (form-encoded):** `formula=<twig>` and optionally `variables[]=<name>`.

**Response:**

```json
{ "valid": false, "message": "Unknown variable \"fields.foo\"", "line": 1 }
```

* `valid` *(bool)*, `message` *(string|null)*, `line` *(int|null)*.

***

## Integration workflow (headless)

1. The product page renders the configurator form (field structure via your own data source/Admin API).
2. On every input change: `POST /store-api/prems/configurator/price` → update price & interim results.
3. "Add to cart": `POST /store-api/checkout/cart/line-item` with `premsConfigurator`. Show constraint violations to the user.
4. Optional "Save": `POST /store-api/prems/configurator/save` → share the token.
5. When opening a shared link: read the token, load the saved values and run step 2 again.


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.premsoft.de/en/plugins/product-configurator/store-api.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
