# Client reference (https://docs.salla.dev/twilight/react/api/client)



Look here when you need to know exactly what `api` sends, or how long it waits. For the reason to use it at all, read the [Overview](https://docs.salla.dev/twilight/react/api).

```ts title="import"
import { api, cdn, filesCdn } from '@salla.sa/twilight-theme-engine/api/client';
```

All three are [ky](https://github.com/sindresorhus/ky) instances. ky is a small wrapper around `fetch`.

## `api` [#api]

The client for the Store API. Its methods are `api.get`, `api.post`, `api.put`, `api.patch`, `api.delete` and `api.head`. Each takes a path relative to the base URL and returns a promise with `.json()`, `.text()` and so on.

| Setting  | Value                                                                   |
| -------- | ----------------------------------------------------------------------- |
| Base URL | `https://api.salla.dev/store/v1` by default. See [Base URL](#base-url). |
| Timeout  | 8000 ms per attempt                                                     |
| Headers  | Added to every request, listed below                                    |

```ts title="app/lib/example.ts"
const { data } = await api.get(`cart/${cartId}`).json<{ data: CartApiResponse }>();
```

Use paths like `'cart/1'`. A per-request `timeout`, `headers`, `signal` or `retry` option overrides the defaults for that call.

### Base URL [#base-url]

The client picks its base URL once, when the module loads, in this order:

1. The `apiBase` the server published into the page, so the browser keeps talking to the backend that rendered it.
2. `VITE_API_URL`, at build time or from the server's environment.
3. `https://api.salla.dev/store/v1`.

A live storefront sets neither, so it uses the default. `VITE_API_URL` exists to point a preview at another backend.

## `cdn` and `filesCdn` [#cdn-and-filescdn]

Ky instances for static files. `cdn` has base URL `https://cdn.salla.network` and `filesCdn` has `https://cdn.files.salla.network`; both time out after 5000 ms. They send none of the store, token or scope headers. The [`translations`](https://docs.salla.dev/twilight/react/api/modules/translations) module uses them.

## Headers on every `api` request [#headers-on-every-api-request]

| Header                                                                                  | Value                                         | When                                                                        |
| --------------------------------------------------------------------------------------- | --------------------------------------------- | --------------------------------------------------------------------------- |
| `accept`                                                                                | `application/json`                            | Always                                                                      |
| `accept-language`                                                                       | Current locale                                | Always                                                                      |
| `s-source`, `s-theme-type`, `s-store-api-version`, `x-requested-with`, and a few others | Fixed identification values                   | Always                                                                      |
| `store-identifier`                                                                      | The resolved store                            | Unless you set one on the request                                           |
| `s-version-id`                                                                          | Theme version id                              | When a version applies                                                      |
| `currency`                                                                              | The currency the shopper chose, such as `EUR` | When the shopper picked one (see [`getActiveCurrency`](#getactivecurrency)) |
| `Authorization`                                                                         | `Bearer <token>`                              | When a token exists                                                         |
| `s-scope-id`                                                                            | Scope id                                      | When a scope is active                                                      |
| `s-scope-type`, `s-scope-allocation-type`, `s-scope-allocation-id`                      | From the scope                                | When the scope has them                                                     |

The client sets these just before sending, so a value you pass for `accept` or `accept-language` is overwritten. Only `store-identifier` keeps your value. Where the token, scope and version come from is explained in [Authentication and scope](https://docs.salla.dev/twilight/react/api/authentication-and-scope).

## `getActiveCurrency` [#getactivecurrency]

A store can let shoppers see prices in another currency. The Salla SDK keeps the choice in the `s-curr` cookie. `getActiveCurrency()` returns that code, such as `'EUR'`, or `null` when the shopper kept the store's own currency. Pass a fallback to get it instead of `null`.

```ts
function getActiveCurrency(): string | null
function getActiveCurrency(fallback: string): string
```

The client sends the same value as the `currency` header, on the server and in the browser, so the API answers with converted amounts. It reads the request cookie on the server and `document.cookie` in the browser, and returns only a three-letter code.

```tsx title="app/components/PriceLabel.tsx"
import { getActiveCurrency } from '@salla.sa/twilight-theme-engine/api/client';
import { CurrencySymbol } from '@salla.sa/twilight-theme-engine/common';
import type { Product } from '@salla.sa/twilight-theme-engine/types';

export function PriceLabel({ product }: { product: Product }) {
  return (
    <span>
      {product.price} <CurrencySymbol currency={getActiveCurrency(product.currency)} />
    </span>
  );
}
```

<Callout type="warn">
  The API converts the amounts but still labels products with the store's own currency (`currency: 'SAR'` on a Saudi store). Label a converted price with `getActiveCurrency(product.currency)`, not `product.currency` alone. An amount that has its own currency, such as a past order total, keeps that currency.
</Callout>

[`useMoney().format`](https://docs.salla.dev/twilight/react/hooks/use-money) already labels amounts with the chosen currency when you pass no `currency`.

## Timeouts and retries [#timeouts-and-retries]

All three keep ky's default retry behaviour:

| Setting               | Value                                                                                     |
| --------------------- | ----------------------------------------------------------------------------------------- |
| Retries               | 2 (3 attempts in total)                                                                   |
| Retried methods       | `get`, `put`, `head`, `delete`, `options`, `trace` (never `post` or `patch`)              |
| Retried statuses      | 408, 413, 429, 500, 502, 503, 504 (413 only when the response has a `Retry-After` header) |
| Retried failures      | Network errors (offline, DNS, refused connection) on the retried methods                  |
| Wait before a retry   | 300 ms, then 600 ms                                                                       |
| `Retry-After`         | Honoured for 413, 429 and 503                                                             |
| Retry after a timeout | No                                                                                        |

The timeout applies to each attempt. A failure throws `HTTPError` (non-2xx), `TimeoutError` or `NetworkError`.

## Next [#next]

* [Authentication and scope](https://docs.salla.dev/twilight/react/api/authentication-and-scope): where the token, scope and version come from.
* [Errors, timeouts and retries](https://docs.salla.dev/twilight/react/api/errors-timeouts-and-retries): handling the errors above.
* [Write your own endpoint](https://docs.salla.dev/twilight/react/api/write-your-own-endpoint)
