Authentication
OAuth2 client-credentials authentication for the Beta Ramps Gateway API.
The Beta Ramps Gateway API authenticates every request with an OAuth2 machine-to-machine (M2M) client-credentials token. You exchange your integration key for a short-lived bearer token, then send that token on each API call.
Client-credentials flow
Mint a token by posting your integration key credentials to the token endpoint:
curl -X POST https://api.betaramps.com/auth/token \
-H 'Content-Type: application/json' \
-d '{"client_id":"...","client_secret":"..."}'Send only client_id and client_secret. The gateway injects the OAuth2 grant
type and audience server-side, then returns the authorization server's token
response:
{
"access_token": "...",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "orders:read orders:write"
}Use the token on subsequent requests in the Authorization header:
curl https://api.betaramps.com/orders \
-H 'Authorization: Bearer <access_token>'Token lifetime
The token's lifetime is set by the authorization server and returned in the
expires_in field (in seconds). Clients MUST read expires_in and refresh the
token before it elapses — do not assume a fixed lifetime.
Read expires_in
Always refresh based on the expires_in value returned with each token. The
expires_in shown in the example above is illustrative only and is not a
guaranteed value.
Token caching
Mint a token once and reuse its access_token until shortly before expires_in
elapses, then mint a new one. Do not mint a token per request — the token
endpoint is rate-limited (see below).
Environments
Each environment has its own token endpoint:
| Environment | Token endpoint |
|---|---|
| Production | POST /auth/token |
| Sandbox | POST /auth/sandbox/token |
The Sandbox token endpoint is available only if sandbox is enabled for your account. A token minted at one endpoint is valid only against that environment's API — a Production token is rejected by the Sandbox API, and vice versa.
Scopes
Your token's scope is a space-separated list of the scopes granted to your
integration key. Scopes are chosen when the key is created. A request that
requires a scope your token lacks returns 403 insufficient_scope.
The partner-selectable scopes are:
| Resource | Read scope | Write scope |
|---|---|---|
| accounts | accounts:read | — |
| balances | balances:read | — |
| bank-accounts | bank-accounts:read | bank-accounts:write |
| integration-keys | integration-keys:read | — |
| orders | orders:read | orders:write |
| pool-bank-accounts | pool-bank-accounts:read | pool-bank-accounts:write |
| pool-wallets | pool-wallets:read | pool-wallets:write |
| quotes | — | quotes:write |
| reference | reference:read | — |
| subaccounts | subaccounts:read | subaccounts:write |
| wallets | wallets:read | wallets:write |
| webhooks | webhooks:read | webhooks:write |
dashboard:read
dashboard:read is also selectable when creating an integration key, but it
gates internal dashboard endpoints that are not part of this API reference.
Authentication errors
Authentication failures return the standard error envelope {code, message}:
| Status | code | Cause |
|---|---|---|
| 400 | invalid_request | Malformed token request body. |
| 401 | invalid_credentials | Wrong or revoked client credentials. |
| 403 | insufficient_scope | Token lacks a scope the request requires. |
| 429 | rate_limit_exceeded | Token endpoint rate limit exceeded (roughly 10 requests/minute per client). Honor the Retry-After header. |