# API configuration and the Scalar playground

For developers

The API module comes with interactive documentation: **Scalar**, an OpenAPI playground in the browser where you can read every endpoint, authorise with a token and send real requests. There is one playground for each API - the **Backend API** (`v1`) for integrations and the **Frontend API** (`v2`) for headless and mobile frontends. This article explains the settings and walks through both.

### The settings

All in `App_Data/appsettings.json`, or as environment variables (`BackendAPI__SecretKey` and so on).

```
"FeatureManagement": {
  "Grand.Module.Api": true
},
"BackendAPI": {
  "Enabled": true,
  "SecretKey": "at least 32 random characters",
  "ValidateIssuer": false,
  "ValidIssuer": "",
  "ValidateAudience": false,
  "ValidAudience": "",
  "ValidateLifetime": true,
  "ValidateIssuerSigningKey": true,
  "ExpiryInMinutes": 1440
},
"FrontendAPI": {
  "Enabled": true,
  "JsonContentType": false,
  "SecretKey": "another 32+ character secret",
  "ValidateIssuer": false,
  "ValidIssuer": "",
  "ValidateAudience": false,
  "ValidAudience": "",
  "ValidateLifetime": true,
  "ValidateIssuerSigningKey": true,
  "ExpiryInMinutes": 1440,
  "RefreshTokenExpiryInMinutes": 1440
},
"AllowedHostOrigins": [ "https://shop-frontend.example.com" ]
```

| Setting | What it does |
|---|---|
| `FeatureManagement:Grand.Module.Api` | Loads the API module at all. Off by default; restart after changing it. |
| `Enabled` | Switches each API on or off independently. |
| `SecretKey` | Signs the tokens (HMAC-SHA256). Use a different key per API and per environment. Outside Development the application does not start while an enabled API has an empty key, the shipped placeholder, or one shorter than 32 characters. Changing it invalidates every issued token. |
| `ExpiryInMinutes` | Lifetime of an access token. |
| `RefreshTokenExpiryInMinutes` | Frontend API only: how long a refresh token can be exchanged for a new access token. |
| `ValidateIssuer` + `ValidIssuer`, `ValidateAudience` + `ValidAudience` | When set, tokens are issued with this issuer/audience and only tokens carrying them are accepted - useful when several systems share a signing key. |
| `ValidateLifetime`, `ValidateIssuerSigningKey` | Keep both `true`. Turning them off accepts expired or forged tokens. |
| `JsonContentType` | Frontend API: lets storefront actions bind request bodies sent as JSON (`Content-Type: application/json`) instead of form data. |
| `AllowedHostOrigins` | Origins allowed to call the API from a browser (CORS) in production. In Development every origin is allowed. |
| `SystemModel` | Present in the Backend API section but not used by the current code. |

### Where the playgrounds are

| Address | What |
|---|---|
| `/scalar/v1` | Scalar for the Backend API |
| `/scalar/v2` | Scalar for the Frontend API |
| `/openapi/v1.json`, `/openapi/v2.json` | The OpenAPI 3.0 documents - import them into Postman, Insomnia or a client generator |

They exist only when the application runs in the **Development** environment and the module and API are enabled. Use them on a development or staging copy; production does not publish the documents.

### Backend API in Scalar (v1)

![Scalar for the Grandnode Backend API v1 with the endpoint groups Brand, Category, Collection, Country, Customer and more in the sidebar, the Authentication box and client libraries](https://grandnode.com/Plugins/Theme.GrandNodeCom/Content/kb/developers/scalar-backend.webp)

/scalar/v1 - the Backend API: one group per entity, with GET, POST, PUT, PATCH and DELETE.

1. Create an API user under **System → Developer tools → Manage API Users**. Its e-mail must belong to an existing, active customer account with admin access; the API acts with that customer's permissions.
2. In Scalar open **Token → POST /Api/Token/Create** and send `{ "email": "...", "password": "<password in Base64>" }`. The response is the token as a JSON string.
3. In the **Authentication** box choose **Bearer** and paste the token (without the quotes).
4. Open, for example, **Product → GET /api/Product**, add query parameters and send:
   ```
   $top=2
   $select=Name,Price,Sku
   $orderby=Price desc
   $filter=Price > 300 and Name.Contains("Aurora")
   ```
   `$filter` uses C#-like expressions (`==`, `>`, `and`, `or`, `Contains`, `StartsWith`...), not OData words such as `gt`.

Scalar shows the request as code for many clients (C# HttpClient is the default, also cURL, JavaScript, Python, PHP...) - copy it into your integration.

### Frontend API in Scalar (v2)

![Scalar for the Grandnode Frontend API v2 with the Create token group (Guest, Login, Refresh, Antiforgery) and storefront groups such as Account, Catalog, Checkout and Order](https://grandnode.com/Plugins/Theme.GrandNodeCom/Content/kb/developers/scalar-frontend.webp)

/scalar/v2 - the Frontend API: the storefront's own actions, grouped by area.

1. Get a token from **Create token**: `POST /TokenWeb/Guest` for an anonymous shopper, or `POST /TokenWeb/Login` with a customer's e-mail and Base64 password. The response contains `AccessToken` and `RefreshToken`.
2. Put the `AccessToken` into **Authentication → Bearer**.
3. Try a call, for example `GET /Account/Info`: it returns the signed-in customer's data as JSON. Without a token the same call returns 403.
4. Operations in this document take an `X-CSRF-TOKEN` header: get its value from `GET /TokenWeb/Antiforgery` and send it with requests that change data.
5. When the access token expires, call `POST /TokenWeb/Refresh` with both tokens.

The Frontend API is the storefront itself: the same controllers serve HTML to browsers and JSON to API clients, so whatever the storefront can do - catalog, cart, checkout, account, blog, knowledgebase - is in v2.

### Tips

- 401 everywhere: the module flag is off, the token was signed with another key, or it expired.
- "User not exists or password is wrong": the password was not Base64-encoded, the API user is inactive, or there is no customer with that e-mail.
- Keep the Scalar instance away from production data: it sends real requests.

### Related

- [The REST API](https://grandnode.com/developers-rest-api)
- [Application settings (appsettings.json)](https://grandnode.com/system-appsettings)

- [Web page](https://grandnode.com/developers-scalar-api-playground)
