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

# Currency configuration

> Name your own loyalty currency and set what it is worth, so every price the API returns is already denominated for your members.

Your members spend your currency, not ours. `PUT /v1/configuration` sets what it
is called and how many units of it make a US dollar; every price the API returns
is then already converted, on the offer, the wallet, the balance and the
insufficient-funds errors.

<Note>
  This is a **server-to-server** call. It requires an Org-API-Key with the
  `config:write` scope, and the route is deliberately not reachable from a
  browser - see [Authentication](/authentication). `config:write` is not granted
  to a new key by default; ask your account team to add it.
</Note>

## Set your currency

```bash curl theme={null}
curl -X PUT https://api.expys.com/v1/configuration \
  -H "Authorization: Bearer YOUR_ORG_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currencyName": "Diamond Credits",
    "currencySymbol": "DC",
    "currencyUnitsPerUSD": 1
  }'
```

| Field                 | Type    | Description                                       |
| --------------------- | ------- | ------------------------------------------------- |
| `currencyName`        | string  | 1-40 characters. What your currency is called.    |
| `currencySymbol`      | string  | 1-8 characters.                                   |
| `currencyUnitsPerUSD` | number  | How many of your units equal **one US dollar**.   |
| `confirmReprice`      | boolean | Required to make a large ratio change; see below. |

Every field is optional; send only what you are changing. A body with no
recognised field is rejected rather than silently accepted. The response returns
the resulting configuration, so you can confirm without a second call.

## What `unitsPerUSD` means

You express the ratio **against dollars**, never against our internal settlement
units. If a credit is worth a dollar, send `1`. If a credit is worth a cent -
the common loyalty case - send `100`. If a credit is worth a hundred dollars,
send `0.01`.

A \$750,000 experience then renders as:

| `unitsPerUSD` | `display.amount` |
| ------------- | ---------------- |
| `1`           | 750,000          |
| `100`         | 75,000,000       |
| `0.01`        | 7,500            |
| `0.001`       | 750              |

`display.amount` is a **number, not an integer**, and nothing is rounded. Choose the
ratio that reads best to your members rather than one that makes prices land on whole
units - a \$1,650 experience at `0.001` returns `1.65`, which is the honest figure.

## Pricing an experience individually

A ratio applies to your whole catalog, so every price stays a fixed multiple of what you
pay us. When you want to price a marquee experience differently from an everyday one, set
that price directly:

```http theme={null}
PUT /v1/offers/{id}/price
Authorization: Bearer <your Org-API-Key>

{ "amount": 40 }
```

```json theme={null}
{
  "pointsPrice": 2000000,
  "valueUSD": 20000,
  "display": {
    "amount": 40,
    "source": "AUTHORED",
    "currency": { "name": "Diamond Credits", "symbol": "DC", "unitsPerUSD": 0.001 }
  }
}
```

The response is the whole offer, so you see exactly what your members will. `amount` is
returned verbatim - the ratio is ignored entirely, and fractional prices like `39.5` are
kept as-is. To go back to the derived figure:

```http theme={null}
DELETE /v1/offers/{id}/price
```

Both need the `config:write` scope and are server-to-server only, like this route.
`display.source` on any offer tells you which you are looking at: `AUTHORED` or `DERIVED`.

<Warning>
  **An authored price changes what you charge, not what you pay.** Settlement always
  debits `pointsPrice`, whatever `display.amount` says - the spread between the two is
  yours. Authored prices require pool settlement; on member-wallet settlement the request
  is refused with `OFFER_PRICING_UNAVAILABLE`, because a member's balance is denominated
  in points you have already paid us for.
</Warning>

<Note>
  Changing `currencyUnitsPerUSD` while prices are authored is refused with
  `AUTHORED_PRICES_WOULD_BE_STALE`. An authored price is a fixed number of credits, so
  moving the ratio changes what every one of them is worth without changing its number.
  Resend with `confirmReprice: true`, or clear the authored prices first.
</Note>

<Warning>
  **Changing `currencyUnitsPerUSD` reprices every experience immediately**, for
  every member, on the next request. There is no staging step. Change it when you
  intend to reprice your whole catalog, and not otherwise.
</Warning>

Because a decimal slip here is far more likely than a considered 100x change, a
move beyond **10x in either direction** is refused with
`400 LARGE_REPRICE_REQUIRES_CONFIRM`, naming both values. Resend the same call
with `"confirmReprice": true` to go ahead. Your first configuration, from the
untouched default, is never treated as a reprice.

## What is deliberately not writable

`settlementMode`, `creditLimit` and `ratePerPoint` are commercial terms, not
client preferences - a client cannot grant itself a better rate or a larger
overdraft. Sending any of them is **rejected**, not ignored, so a body that
contains one fails loudly rather than returning a success for a change that did
not happen. Those are a conversation with your account team.

## Auditing

Every real change is recorded with the key that made it: what changed, from what,
to what, and when. Sending a value that is already set writes nothing - the
record is a history of decisions, not of requests. Ask your account team if you
need to see it.
