Authentication
Every request to the VirtuaBroker API carries a short-lived OAuth 2.0 bearer token scoped to a single workspace. You mint the token from your workspace credentials, send it on each call, and refresh it server-side before it expires.
Tokens are workspace-scoped: a token minted for one workspace can only read and write that workspace's data. Test everything against https://api-stage.virtuabroker.com first.
Get credentials
API access is provisioned per workspace during onboarding. To request credentials, contact integrations@virtuabroker.com. You'll receive a client_id plus an API username and password for the workspace.
Keep the API credentials server-side only. Never ship them in a browser bundle, mobile app, or public repository. Rotate them immediately if they are ever exposed.
Request a token
Exchange your credentials for an access token using the OAuth 2.0 password grant against the token endpoint (realm cryptobot). Send the request as application/x-www-form-urlencoded.
export VB_TOKEN=$(curl -s https://auth2.virtuabroker.com/realms/cryptobot/protocol/openid-connect/token \ -d "grant_type=password" \ -d "client_id=$VB_CLIENT_ID" \ -d "username=$VB_API_USERNAME" \ -d "password=$VB_API_PASSWORD" | jq -r .access_token)
const res = await fetch("https://auth2.virtuabroker.com/realms/cryptobot/protocol/openid-connect/token", { method: "POST", headers: { "Content-Type": "application/x-www-form-urlencoded" }, body: new URLSearchParams({ grant_type: "password", client_id: process.env.VB_CLIENT_ID, username: process.env.VB_API_USERNAME, password: process.env.VB_API_PASSWORD, }), }); const { access_token, expires_in } = await res.json();
import os, requests r = requests.post("https://auth2.virtuabroker.com/realms/cryptobot/protocol/openid-connect/token", data={ "grant_type": "password", "client_id": os.environ["VB_CLIENT_ID"], "username": os.environ["VB_API_USERNAME"], "password": os.environ["VB_API_PASSWORD"], }) access_token = r.json()["access_token"]
{
"access_token": "…",
"token_type": "Bearer",
"expires_in": 300
}
Use the token
Send the access token in the Authorization header as a bearer token on every request. Note that writes (any POST) are not de-duplicated — see Retrying a write before you build retry logic.
curl https://api.virtuabroker.com/v1/orders \ -H "Authorization: Bearer $VB_TOKEN" \ -H "Content-Type: application/json"
Token lifecycle
Access tokens are short-lived — they expire roughly five minutes after issue (expires_in is in seconds). Cache the token in your backend and reuse it until it nears expiry, then mint a fresh one from the token endpoint with your credentials.
Mint and cache tokens server-side only. Never expose a token — or the credentials that mint it — to a browser or mobile client. Refresh a few seconds before expires_in elapses to avoid mid-request expiry.
Auth errors
Both authentication failures (missing or invalid token) and authorization failures (valid token, out-of-scope resource) return HTTP 401 with an AuthorizationError error type. The only 403 the API returns is a business AllowanceError. See the Errors reference for the full error model and handling guidance.
| Status | When | Error type |
|---|---|---|
| 401 | Missing, malformed, or expired bearer token. Request a fresh token and retry. | AuthorizationError |
| 401 | Valid token, but the request targets a resource outside the token's workspace scope. | AuthorizationError |
| 403 | The workspace is not allowed to perform this operation — a business allowance rule, not an auth failure. | AllowanceError |