# Authentication

Bearer tokens, modes and installation context.

Base URL:

```text
https://api.southbill.com/v1/app
```

Every request carries an installation access token:

```bash
curl "https://api.southbill.com/v1/app/payments?limit=10" \
  -H "Authorization: Bearer sb_at_live_…"
```

The token identifies the app **and** the merchant. There is no merchant id parameter — you cannot address a merchant that has not installed you.

## Getting a token

Tokens come from the OAuth flow at install time (`authorization_code`, PKCE supported) and are renewed with the `refresh_token` grant. See [Installs & OAuth](/docs/dev/apps/installs).

| Property | Value |
| --- | --- |
| Access token | `sb_at_live_…` / `sb_at_test_…`, valid **1 hour** (`expires_in: 3600`) |
| Refresh token | `sb_rt_live_…` / `sb_rt_test_…`, **single use and rotating** — store the new one on every refresh |
| Mode | Baked into the token, cannot be switched |
| Scopes | Exactly what the merchant approved |
| Reissue | Issuing a new access token revokes the installation's previous access tokens |

Because refresh tokens rotate, refreshing twice with the same token invalidates the installation's tokens — serialise your refresh calls.

## Failure modes

| Status | `error.type` | Do this |
| --- | --- | --- |
| 401 | `invalid_token` | Refresh, then retry once |
| 403 | `insufficient_scope` | Request the scope in a new version; do not retry |
| 403 | `installation_suspended` | Back off, retry later, keep data |
| 404 | `not_found` | Object does not exist for this merchant |
| 404 | `unknown_endpoint` | Path typo or unsupported resource |
| 405 | `method_not_allowed` | v1 is read-only; only `GET` |
| 429 | `rate_limit_exceeded` | Honour `Retry-After` |

Error bodies are uniform:

```json
{ "error": { "type": "insufficient_scope", "message": "Missing required scope: payments:read" } }
```

## Server-side only

The client secret and refresh tokens must never reach a browser or a mobile binary. Public clients use PKCE and keep only the short-lived access token.
