Create Access Tokens
Create long-lived access tokens for integrations. See the Guide.
-
Log in to BitGo to obtain a short-lived access token (valid for ~24 hours). This token is required to authenticate the request that creates your long-lived access token.
In the test environment, the OTP is always
0000000. In production, use the OTP from your authenticator app.Prerequisites: You must have a BitGo account in the environment for which you're creating a token. See Environments.
-
Use the short-lived access token from the previous step to create a long-lived access token for your integration. Long-lived tokens can last up to 10 years and don't require an OTP for sensitive operations.
Best Practices:
- Rotate tokens frequently — don't let them last 10 years.
- Include a spending limit. If omitted, you must unlock the token regularly for sensitive operations.
- Practice the principle of least privilege (POLP) by assigning only necessary scopes.
- In production, IP address or CIDR block restrictions are required by default.
Save the
tokenvalue for use in your integration. This token is unrecoverable — if you lose it, you must create a new one.
// 1. Create Short-Lived Access Token
export EMAIL="<YOUR_EMAIL_ADDRESS>"
export OTP="<OTP>" # OTP is always 0000000 in test environment
export PASSWORD="<YOUR_LOGIN_PASSWORD>"
curl -X POST \
https://app.bitgo-test.com/api/v2/user/login \
-H 'Content-Type: application/json' \
-d '{
"email": "'"$EMAIL"'",
"otp": "'"$OTP"'",
"password": "'"$PASSWORD"'"
}'
// 2. Create Long-Lived Access Token
export ACCESS_TOKEN="<YOUR_SHORT-LIVED_ACCESS_TOKEN>"
export OTP="<OTP>" # OTP is always 0000000 in test environment
export DURATION="<DURATION>"
export LABEL="<DESIRED_TOKEN_NAME>"
export IP_RESTRICT="<IP_ADDRESS_OR_CIDR_BLOCK>" # Required in production
export ENTERPRISE_ID="<YOUR_ENTERPRISE_ID>"
export COIN="<ASSET_ID>"
export TX_VALUE_LIMIT="<TX_VALUE_LIMIT>"
curl -X POST \
https://app.bitgo-test.com/api/v2/user/accesstoken \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
"otp": "'"$OTP"'",
"scope": [
"openid",
"openid_enterprises",
"profile",
"wallet_create",
"wallet_freeze_all",
"wallet_manage_all",
"wallet_approve_all",
"wallet_spend_all",
"wallet_edit_all",
"wallet_view_all",
"settlement_network_read",
"settlement_network_write",
"trade_view",
"trade_trade",
"portfolio_view",
"pending_approval_update",
"metamask_institutional",
"crypto_compare",
"third_party_user_lookup",
"enterprise_view_all",
"enterprise_manage_all",
"auditlogs_view_all",
"ui_scope"
],
"duration": '$DURATION',
"label": "'"$LABEL"'",
"admin": false,
"enterprise": "'"$ENTERPRISE_ID"'",
"spendingLimits": [
{
"coin": "'"$COIN"'",
"txValueLimit": "'"$TX_VALUE_LIMIT"'",
"maxLimit": false
}
]
}'
// 1. Create Short-Lived Access Token
import { BitGoAPI } from '@bitgo/sdk-api';
const bitgo = new BitGoAPI({ env: 'test' });
const auth_res = await bitgo.authenticate({
username: "user@example.com",
password: process.env.PASS,
otp: "0000000",
});
// 2. Create Long-Lived Access Token
const access_token = await bitgo.addAccessToken({
otp: "0000000",
label: "Admin Access Token",
scope: [
"openid",
"pending_approval_update",
"profile",
"settlement_network_read",
"settlement_network_write",
"trade_trade",
"trade_view",
"user_manage",
"wallet_approve",
"wallet_approve_all",
"wallet_create",
"wallet_edit",
"wallet_edit_all",
"wallet_edit_enterprise",
"wallet_freeze",
"wallet_freeze_all",
"wallet_manage",
"wallet_manage_all",
"wallet_manage_enterprise",
"wallet_spend",
"wallet_spend_all",
"wallet_spend_enterprise",
"wallet_view",
"wallet_view_all",
"wallet_view_enterprise"
],
spendingLimits: [
{
coin: "tbtc4",
txValueLimit: "1000000000", // 10 TBTC4 (10 * 1e8)
},
],
});
console.log(access_token);
// 1. Create Short-Lived Access Token Response
{
"token_type": "bearer",
"access_token": "cb4125818839d3695e51ad74443e8362105f315e2495b3e905454430e948d556",
"expires_in": 86400,
"expires_at": 1763745105,
"scope": [
"user_manage",
"openid",
"openid_enterprises",
"profile",
"wallet_create",
"wallet_freeze_all",
"wallet_manage_all",
"wallet_approve_all",
"wallet_spend_all",
"wallet_edit_all",
"wallet_view_all",
"settlement_network_read",
"settlement_network_write",
"trade_view",
"trade_trade",
"portfolio_view",
"pending_approval_update",
"metamask_institutional",
"crypto_compare",
"third_party_user_lookup",
"enterprise_view_all",
"enterprise_manage_all",
"auditlogs_view_all",
"ui_scope"
],
"grant_type": "password",
"user": {
"id": "62ab90e06dfda30007974f0a52a12995",
"username": "janedoe@email.com"
}
}
// 2. Create Long-Lived Access Token Response
{
"id": "693f4ee8b6f82977fda4793bf81dcfef",
"client": "bitgo",
"user": "62ab90e06dfda30007974f0a52a12995",
"scope": [
"openid",
"openid_enterprises",
"profile",
"wallet_create",
"wallet_freeze_all",
"wallet_manage_all",
"wallet_approve_all",
"wallet_spend_all",
"wallet_edit_all",
"wallet_view_all",
"settlement_network_read",
"settlement_network_write",
"trade_view",
"trade_trade",
"portfolio_view",
"pending_approval_update",
"metamask_institutional",
"crypto_compare",
"third_party_user_lookup",
"enterprise_view_all",
"enterprise_manage_all",
"auditlogs_view_all",
"ui_scope"
],
"created": "2025-11-20T17:24:56.537Z",
"expires": "2035-11-18T17:24:56.537Z",
"ip": "75.237.71.150",
"ipRestrict": [],
"origin": "app.bitgo-test.com",
"label": "My Bitcoin Token",
"isExtensible": false,
"enterprise": "62c5ae8174ac860007aff138a2d74df7",
"unlock": {
"time": "2025-11-20T17:24:56.543Z",
"expires": "2035-11-18T17:24:56.537Z",
"spendingLimits": {
"tbtc4": { "txCount": 1, "txValue": 0, "txValueLimit": 100 }
}
},
"token": "c1d856191baa8a0c16af7583aa6d4a4b3b222081361461b40041602ce0470ed6"
}