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

# Authentication

A hostapp and a miniapp talk to each other through the platform. Each side authenticates with a different credential, and the credential changes with the direction of the call.

A hostapp and a miniapp must already have an accepted integration, and the feature in use (single sign-on, payments, or events) must be enabled on both apps and on the integration. Those checks run alongside authentication.

## Authentication types

Integration calls use one of two authentication types.

### 1. Basic authentication

This is the default. The client id is the username and the secret is the password:

```text theme={"system"}
Authorization: Basic base64(<client id>:<secret>)
```

Which pair depends on the direction:

| Direction | Client id | Secret |
| - | - | - |
| Host app calls the platform | Client ID, issued by the platform | Secret key, issued by the platform |
| Platform calls the host app | Host-app client ID, saved in the dashboard | Host-app secret key, saved in the dashboard |
| Miniapp calls the platform, and the platform calls the miniapp | App ID, issued by the platform | Secret key, issued by the platform |

<Frame caption="Hostapp Integration Keys">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-14.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=4fe36c6f0c1b9595eb223f2e1a0f389c" alt="Image" title="Image" className="mx-auto" width="736" height="683" data-path="images/image-14.png" />
</Frame>

<Frame caption="Miniapp Integration Keys">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-15.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=b52c1c0098596bc0a5465320c454c30a" alt="Image" width="980" height="788" data-path="images/image-15.png" />
</Frame>

### 2. Request signaturing

Turn this on per app when you want a stronger check than sending the secret on every call. The sender signs the request, and the receiver verifies the signature. That confirms the caller and that the request was not changed in transit. When request signaturing is enabled for an app, it replaces Basic authentication for that app.

How to set it up and verify signatures:

* [Request signaturing for host apps](https://docs.boxo.io/host-apps/Signaturing)
* [Request signaturing for miniapps](https://docs.boxo.io/miniapp/Signaturing)

Why Connect and Payments use it: [Security measures](https://docs.boxo.io/host-apps/SecurityMeasures#request-signaturing) and [Miniapp security](https://docs.boxo.io/miniapp/Security#request-signaturing).

<Frame caption="Hostapp Request Signature Configuration">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-5.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=56926c2fc7df4ab37331a8711cb0e827" alt="Image" width="942" height="1264" data-path="images/image-5.png" />
</Frame>

<Frame caption="Miniapp Request Signature Configuration">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-16.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=bd628e4ec5731f33957e88732c446401" alt="Image" width="1159" height="1288" data-path="images/image-16.png" />
</Frame>

## Credentials

The platform issues one pair when an app is created. The hostapp issues a second pair and stores it on the platform so the platform can call the hostapp.

| Credential | Issued by | Used for |
| - | - | - |
| Client ID and Secret key | Platform, under Integration keys on the host app. The Client ID looks like `host_` followed by 12 characters. | The host app calling the platform. |
| App ID and Secret key | Platform, on the miniapp. | The miniapp calling the platform, and the platform calling the miniapp. |
| Host-app client ID and Host-app secret key | Host app. Entered under Integration keys. | The platform calling the host app. |
| User access token | Host app, during single sign-on. Stored per user. | The platform calling the host app on behalf of a signed-in user. |

Client ID and App ID also name the apps. They appear in request bodies so the platform can find the integration. They are sent again on outbound calls as headers:

* `X-Hostapp-Client-ID` is the host app Client ID
* `X-Miniapp-App-ID` is the miniapp App ID

Those headers identify the integration. The secret travels in `Authorization`, or in a signature.

## Calls into the platform

On each protected call the platform can apply up to three checks, in this order:

1. Basic authentication, where that endpoint requires it.
2. A request signature, when request signing is enabled for that app.
3. An IP allowlist, when the app has one configured.

### Hostapp Basic authentication

Turn this on with **Basic auth validation** on the host app. The host app then sends:

```text theme={"system"}
Authorization: Basic base64(<Client ID>:<Secret key>)
```

The platform compares that pair with the credentials it issued. This applies to:

| API | What the hostapp is doing |
| - | - |
| `POST /api/v1/connect/` | Sending a user into a miniapp. |
| `POST /api/v1/orders/complete-order/` | Reporting that a payment has finished. |

Client ID is still sent in the body of other APIs so the platform can find the host app. The Secret key is checked on the two APIs above.

### Miniapp Basic authentication

`POST /api/v1/analytics/miniapp-transactions/` requires Basic authentication on every call:

```text theme={"system"}
Authorization: Basic base64(<App ID>:<Secret key>)
X-Miniapp-App-Id: <App ID>
X-Hostapp-Client-Id: <Client ID>
```

The platform loads the miniapp from `X-Miniapp-App-Id` and the host app from `X-Hostapp-Client-Id`, then checks that the Basic username and password match that miniapp's App ID and Secret key.

### Request signatures

When Request Signature is enabled, the caller signs the request and the platform verifies it. Signature settings are stored per app. Host apps and miniapps each have their own.

Setup for each side:

* [Request signaturing for host apps](https://docs.boxo.io/host-apps/Signaturing)
* [Request signaturing for miniapps](https://docs.boxo.io/miniapp/Signaturing)

What signing is for, and why Connect and Payments use it, is in [Security measures](https://docs.boxo.io/host-apps/SecurityMeasures#request-signaturing) and [Miniapp security](https://docs.boxo.io/miniapp/Security#request-signaturing).

Supported algorithms:

| Algorithm | Key material |
| - | - |
| HMAC | Shared HMAC secret on the signature settings. |
| RSA2 | The partner signs with its private key. The platform verifies with the Partner public key. |
| ECDSA | Same split as RSA2. |

The signed string is built from the Signature payload template. The default is:

```text theme={"system"}
{request_method}.{url}.{client_id}.{timestamp}.{payload}
```

Default headers:

| Header | Meaning |
| - | - |
| `X-Client-Id` | Api client ID from the Request Signature settings. |
| `X-Timestamp` | Timestamp, at the precision configured for the app. |
| `X-Signature` | The signature. |
| `X-Identity` | Optional fixed identity string. |
| `X-Nonce` | Optional random nonce. |
| `X-Merchant-Id` | Merchant id from the integration, when the template includes it. |

Header names, the Signature payload template, hash function, encoding, nonce, and key sorting are all configurable per app. HMAC, RSA2, and ECDSA share that template. RSA2 and ECDSA keys are PEM or DER. The Appboxo public key is what the partner uses to verify calls the platform signs.

If request signing is enabled and the signature settings are missing, the call is rejected.

### IP allowlist

When IP whitelist is on, the caller's IP must be in Whitelisted IPs. The platform's own payment-service addresses are allowed as well.

How to set the allowlist, and which platform IPs to allow on your side: [Whitelisting](https://docs.boxo.io/host-apps/Whitelisting) and [Security measures](https://docs.boxo.io/host-apps/SecurityMeasures#whitelisting). Miniapps: [Miniapp security](https://docs.boxo.io/miniapp/Security#whitelisting).

<Frame caption="IP whitelisting">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-7.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=a488083deb34e4bf4770c18ea572b41e" alt="Image" title="Image" className="mx-auto" width="757" height="252" data-path="images/image-7.png" />
</Frame>

### Encrypted login payload

`POST /api/v1/partner/login/` takes the Client ID and a payload encrypted with AES, using the host app Secret key. The platform decrypts it, then posts the result to the miniapp. This endpoint does not use the Basic header.

Passing encrypted user data on Connect is described in [Security measures](https://docs.boxo.io/host-apps/SecurityMeasures#passing-encrypted-user-data).

## Calls out of the platform

When the platform calls a hostapp or a miniapp, it authenticates as itself, unless the call is on behalf of a user.

### Basic authentication

This is the default, used when request signing is off for the app being called.

Calls to the host app:

```text theme={"system"}
Authorization: Basic base64(<Host-app client ID>:<Host-app secret key>)
```

Calls to the miniapp:

```text theme={"system"}
Authorization: Basic base64(<App ID>:<Secret key>)
```

The hostapp is expected to check the first pair. The miniapp is expected to check the second. Both calls also include `X-Hostapp-Client-ID` and `X-Miniapp-App-ID`.

| Platform API that triggers the call | Destination |
| - | - |
| `POST /api/v1/authorize/` | `POST` to the host app Access token URL |
| Refresh during a payment | `POST` to the host app Refresh token URL |
| `POST /api/v1/orders/create-order-payment/` | `POST` to the host app Create order payment URL |
| `POST /api/v1/orders/get-payment-status/` | `POST` to the host app Get order payment status URL |
| `POST /api/v1/events/miniapp/` | `POST` to the host app Events bridge URL |
| `POST /api/v1/authorize/` and `POST /api/v1/connect/` | `POST` to the miniapp Get auth token URL |
| `POST /api/v1/orders/complete-order/` | `POST` to the miniapp Webhook URL |
| `POST /api/v1/events/hostapp/` | `POST` to the miniapp Events bridge URL |

### Request signatures

When Request Signature is on for the app being called, the platform does not send the Basic credentials above. It sends the same style of signature headers described in the inbound section. Host apps verify those calls with the steps in [Request signaturing](https://docs.boxo.io/host-apps/Signaturing). Miniapps use [Request signaturing](https://docs.boxo.io/miniapp/Signaturing).

Outbound RSA2 and ECDSA signatures are produced with the platform private key. HMAC signatures use the HMAC secret. The partner verifies them with the Partner public key, the Appboxo public key, or the HMAC secret, depending on the algorithm.

### Partner client access token

Some hostapps issue their own client access token (a client-credentials style call). When that is configured, the platform requests the token from the hostapp, then sends:

```text theme={"system"}
Authorization: Bearer <access_token>
```

`Bearer` is the default. The host app can return another token type. This header replaces Basic authentication and the signature `Authorization` value for that call. The token is cached until it expires.

### User access token

Single sign-on produces a second credential: the hostapp user's access token. The platform stores it with the user's refresh token and uses it when the call is about that user.

The header is:

```text theme={"system"}
Authorization: <Access token prefix> <access token>
```

The default Access token prefix is `Token`. It is configurable per host app.

A `GET` to the host app User data URL always uses this user token. Payment calls use it when Use access token is enabled. In that case the order includes the host app user id, and the platform also sends `X-User-ID`. If the host app responds with 401, the platform calls the Refresh token URL with the platform credentials, saves the new tokens, and retries once.

<img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-18.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=179a3591e80c2d75b987b80dc79c5cfc" alt="Image" width="773" height="563" data-path="images/image-18.png" />

Two host app settings are returned to the SDK with the miniapp settings and describe how the user signs in. They are not secrets.

* One tells the SDK to collect consent in a popup.
* One tells the SDK that the host app completes sign-on on the server.

## How the flows fit together

### Single sign-on via authorize

`POST /api/v1/authorize/` starts from an auth code the hostapp gave the miniapp. The product flow is [Boxo Connect](https://docs.boxo.io/host-apps/BoxoConnect) for host apps and [Connect](https://docs.boxo.io/miniapp/Connect) for miniapps.

1. The caller sends the Client ID, the App ID, and an auth code. The platform finds the integration from those ids.
2. The platform calls the host app Access token URL as itself, with the Host-app client ID and Host-app secret key, or with a request signature.
3. The host app returns an access token and, optionally, a refresh token.
4. The platform calls the host app User data URL as that user.
5. The platform calls the miniapp Get auth token URL as itself, with the miniapp App ID and Secret key, or with a request signature.
6. The response to the original caller is the miniapp auth token.

### Single sign-on via connect

`POST /api/v1/connect/` is the path where the hostapp already knows the user.

1. The host app sends the Client ID, the App ID, and the user data. If Basic auth validation is on, it also sends the Client ID and Secret key. A signature and IP check apply when those are configured.
2. The platform stores the user against the host app.
3. The platform calls the miniapp Get auth token URL as itself and returns that miniapp token.

### Create a payment

Endpoint contracts are in [Boxo Payments](https://docs.boxo.io/host-apps/BoxoPayments) and [Payment](https://docs.boxo.io/miniapp/Payment).

1. The miniapp calls `POST /api/v1/orders/create-order-payment/` with the Client ID and App ID. If the miniapp has Request Signature or an IP whitelist, those are checked here.
2. The platform calls the host app Create order payment URL. It authenticates as itself, unless Use access token is on, in which case it sends the user's access token.

`POST /api/v1/orders/get-payment-status/` follows the same split: the miniapp calls in, and the platform calls the host app Get order payment status URL with either the platform credentials or the user token.

<Frame caption="Hostapp Payment URLs">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-8.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=76079e8dd25beec7176f53fac8475ad0" alt="Image" title="Image" className="mx-auto" width="767" height="381" data-path="images/image-8.png" />
</Frame>

<Frame caption="Miniapp payment and connect URLs">
  <img src="https://mintcdn.com/boxo/sCwlaMBdajLgqNCq/images/image-9.png?fit=max&auto=format&n=sCwlaMBdajLgqNCq&q=85&s=2167ac8e1298bc9a0562161843688f44" alt="Image" title="Image" className="mx-auto" width="773" height="380" data-path="images/image-9.png" />
</Frame>

### Complete a payment

1. The hostapp calls `POST /api/v1/orders/complete-order/`. Hostapp Basic authentication, the signature, and the IP allowlist apply when they are configured.
2. The platform calls the miniapp payment webhook as itself.

### Events

`POST /api/v1/events/<sender>/` accepts `sender` as `hostapp` or `miniapp`. The event bridge is documented in [Boxo Event Bridge](https://docs.boxo.io/host-apps/CES#boxo-event-bridge) and [Custom Events](https://docs.boxo.io/miniapp/CES).

The inbound check on this endpoint is the miniapp's signature and IP allowlist, for both sender values.

* `POST /api/v1/events/hostapp/` delivers the event to the miniapp Events bridge URL.
* `POST /api/v1/events/miniapp/` delivers the event to the host app Events bridge URL.

The outbound call uses that receiver's credentials: Basic authentication, or a signature when request signing is enabled for the receiver.
