# Connect as a platform

> One set of credentials for the whole journal system, one token per clinic.

Your journal system serves many clinics. You integrate with Rivr **once**, as a platform, and every clinic that switches Rivr on becomes a merchant under you. Everything that touches money — orders, devices, settlements — then happens for one clinic at a time.

- Market: Sweden (`se`). Norway differs in currency, payment methods and what happens when nobody pays: https://developers.rivr.io/guides/connect.md?market=no
- Language: English (`en`). Svenska: https://developers.rivr.io/guides/connect.md?lang=sv
- 4 min read · 5 steps
- Page in the portal: https://developers.rivr.io/guides/connect

Every example targets the sandbox (`https://api.test.rivr.io`) and needs test credentials. A platform client's tokens come from `https://auth.test.rivr.io`, an organisation key's from `https://auth.test.rivr.tech`.

## 1. You receive platform credentials

*Rivr → Journal system*

Rivr creates a client for your platform in the test environment and hands over `client_id` and `client_secret`. The same client covers all your clinics.

**Why:** A clinic should never have to handle API keys of its own. It switches Rivr on, and you reach it through your platform client.

**What your system does:** Put the credentials in your secret store — never in code or a browser. Test credentials only work against the test environment.

## 2. Get a platform token

*Journal system → Rivr*

Exchange the credentials for an access token with `grant_type: client_credentials`. The token is valid for one hour.

> **Warning.** The token endpoint takes **JSON**, not the form-encoded body most OAuth libraries send by default.

**Request:** `POST /connect/token` · No token

```bash
curl -X POST https://auth.test.rivr.io/connect/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "client_credentials",
    "client_id": "'"$RIVR_CLIENT_ID"'",
    "client_secret": "'"$RIVR_CLIENT_SECRET"'"
  }'

# → { "access_token": "eyJ…", "token_type": "Bearer", "expires_in": 3600, "scope": "public:merchants:read …" }
```

## 3. List your clinics

*Journal system → Rivr*

`GET /api/public/merchants` with the platform token returns the clinics connected to your platform: `id`, `name`, `organisationNumber` and `externalId`. The list is paged, 100 per page.

That is as far as the platform token goes. Orders, devices and settlements answer `401` or `403` until you have a merchant token.

**What your system does:** Store the merchant `id` on the clinic in your system. It is the key for every call that follows. The list shows only clinics already connected to your platform. Never let an organisation number on its own tie a clinic to an organisation at your end: the guide Connect a clinic that already has a Rivr account shows how the clinic approves for itself (the sandbox first, production when Rivr confirms).

**Request:** `GET /api/public/merchants` · Platform token · [Reference](https://developers.rivr.io/reference/api-public/listMerchants.md)

```bash
curl -X GET https://api.test.rivr.io/api/public/merchants \
  -H "Authorization: Bearer $PLATFORM_TOKEN"
```

## 4. Get a token for the clinic

*Journal system → Rivr*

The same endpoint, with `grant_type: merchant_token` and the clinic's `merchant_id`. The token carries the clinic, and Rivr rejects an order whose `merchantId` is a different clinic.

**Why:** One token per clinic makes it impossible to create a payment at the wrong clinic by mistake — the boundary lives in the token, not only in your code.

**What your system does:** Cache the token per clinic and fetch a new one shortly before it expires. There is no refresh token — just ask for a new one.

**Request:** `POST /connect/token` · No token

```bash
curl -X POST https://auth.test.rivr.io/connect/token \
  -H "Content-Type: application/json" \
  -d '{
    "grant_type": "merchant_token",
    "client_id": "'"$RIVR_CLIENT_ID"'",
    "client_secret": "'"$RIVR_CLIENT_SECRET"'",
    "merchant_id": "MERCHANT_ID"
  }'
```

## 5. Make your first clinic call

*Journal system → Rivr*

With the merchant token you reach the clinic's orders, devices and settlements. `GET /api/public/devices` is a harmless first call: it lists the clinic's devices and whether they are online.

**Request:** `GET /api/public/devices` · Merchant token · [Reference](https://developers.rivr.io/reference/api-public/getDevices.md)

```bash
curl -X GET https://api.test.rivr.io/api/public/devices \
  -H "Authorization: Bearer $MERCHANT_TOKEN"
```

## Common pitfalls

- Sending the token request form-encoded. Rivr only reads a JSON body.
- Calling `/orders` with the platform token. The answer is `401` or `403` — and for an unknown order id even `204` — so the mistake doesn't always show. Every clinic call needs a merchant token.
- Fetching a new token for every call. It lasts an hour — cache it per clinic.

## Next guide

- [Receive webhooks](https://developers.rivr.io/guides/webhooks.md): The webhook is the truth about an order. How to receive it safely, and only once.
- [Connect a clinic that already has a Rivr account](https://developers.rivr.io/guides/connect-clinic-account.md): The clinic signs in at Rivr with BankID and approves the connection to your system, and you get the clinic's id through an OAuth 2.0 code exchange. The sandbox first, production when Rivr confirms.
- [Errors and retries](https://developers.rivr.io/guides/errors-retries.md): One way to handle errors against /api/public: read the code, decide whether to send the call again, wait the right time and send the same Idempotency-Key again.
- [Payment at the clinic](https://developers.rivr.io/guides/pay-at-clinic.md): The patient checks out at reception and pays on the device before leaving.
- [Which key do I need?](https://developers.rivr.io/guides/which-key.md): The platform client and the organisation key open different doors. How to tell which one you need for which call, and which capabilities control what.
