# Authentication

> For the complete documentation index, see [llms.txt](/llms.txt).

Every Unipaas API call is authenticated. Which credential you use depends on where the call comes from: your server, or the browser.

## Server to server

Server-side calls, the Pay-in, Account, and Payout APIs, the hosted onboarding link, and the checkout call, authenticate with your private key as a bearer token:

```plaintext
Authorization: Bearer <PLATFORM_API_KEY>
```

That header is all a server-side request needs. The [Quickstart](/docs/getting-started/) runs a full call end to end.

Caution

Your private key carries full access to your account. Keep it server-side; never expose it in the browser or commit it to source control.

## Client to server

When your app calls Unipaas from the browser, such as the embedded onboarding UI, it must not use the private key. Instead, your server calls `POST /authorize` with the private key to mint a short-lived access token, scoped to the operations you name, and the browser uses that token.

```curl
curl -X POST https://sandbox.unipaas.com/platform/authorize \
  -H "Authorization: Bearer <PLATFORM_API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "scopes": ["onboarding_write"],
    "vendorId": "<VENDOR_ID>"
  }'
```

`scopes` is required; `vendorId` is optional. The response returns the scoped token and its lifetime:

```json
{
  "accessToken": "eyJhbGciOiJI...",
  "expiresIn": "3600",
  "vendorId": "<VENDOR_ID>",
  "scopes": ["onboarding_write"]
}
```

The browser sends `accessToken` as its bearer token. It expires, so mint a new one when needed. Your private key stays on your server, and the browser only ever holds a limited, temporary token.
