API Access Token and ERC20 Token Management on BitGo

API Access Token and ERC20 Token Management on BitGo

Problem

Customers frequently encounter issues related to API access tokens and ERC20/token management on the BitGo platform. Common problems include: tokens disappearing from the UI due to unexpected expiration, errors when creating access tokens via the UI or API, needing new ERC20 token spending limits added to an existing access token, receiving HTTP 401 "Unauthorized" or "session expired" errors when using tokens, and confusion about how to enable or locate specific tokens (e.g., USDT on Ethereum, tokens on non-ERC20 chains). These issues affect both production and test environments across multiple coin types.

Diagnostics

  • Confirm the environment: Is the customer on production (app.bitgo.com) or test (app.bitgo-test.com)?
  • Identify the enterprise and user: Obtain the enterprise ID, the email address of the user who created the access token, and the user's role (owner, admin, member).
  • Check token existence: Log in as the user or use admin tools to verify whether the access token still appears under Profile Icon > Enterprise Settings > Developer Options. If it is missing, it likely expired.
  • Check token duration in logs: Use Grafana/Loki logs to search for the access token creation event. Look for the "duration" field (in seconds) in the request body to confirm actual expiration time vs. what the customer expected.
  • Check the error message and requestId: Ask the customer for the full API response including requestId. Key error signatures:
    • "error":"No access token" with "invalidToken":true → token not being sent in the request header.
    • "error":"session expired" → the session or short-lived token derived from the long-lived token has expired; distinct from access token expiration.
    • "Access token lacks required scope for this action" → missing permissions/scopes on the token.
    • "To enable <coin> for your account, contact support@bitgo.com" → coin/token not ungated for the user's account.
    • "password error - ccm: tag doesn't match" → wallet credential or key mismatch.
  • Check token spending limits: Verify whether a lifetime spending limit was configured and has been exhausted. Exhausted spending limits can cause 401 errors even if the token has not expired.
  • Check IP restrictions: If the token has IP restrictions configured, confirm the customer's calling IP matches the allowed list.
  • Check user permissions on the wallet: The access token inherits permissions from its creator. If the creator is only a "member" or "viewer," the token will not have admin/spend capabilities. Verify the creator's role on the enterprise and individual wallets.
  • Check for UI bugs: If the customer reports a UI error during token creation (e.g., overlay closing immediately, webhook-related errors), check the browser (recommend Google Chrome) and whether any adblockers are active. Also check for known bugs (e.g., block webhooks causing UI errors on test environment).

Resolution


Scenario: token-tokens-erc20-access#add-token-spending-limit-to-existing-key

Trigger: Customer requests that new ERC20 token spending limits (e.g., EURCV, PYUSD, TRAC, WECAN, LMWR, BLUR, VEXT) be added to an existing API access token.

Signals: add token to API key, spending limit, 999999999999999999999, ERC20, new asset, v2x access token

Steps:

  1. Confirm the access token ID (e.g., starts with v2x...), the token ticker(s) to add, and the desired spending limit from the customer.
  2. Updating token spending limits on an existing access token is not supported in the UI. The customer cannot do this self-service through the dashboard.
  3. BitGo engineering has provided an API that allows customers to update spending limits programmatically. Share the relevant documentation (created per WP-71) with the customer and ask if they can implement it.
  4. If the customer cannot implement the programmatic approach, escalate to the engineering team with the token ID, token ticker(s), and spending limit value. Confirm priority/timeline with the customer.
  5. After engineering confirms the update, ask the customer to verify the change in the web UI or via API.
  6. Note: Alternatively, the customer can create a new access token with the desired spending limits included, but this requires reconfiguring all existing spending limits on the new token.

Notes: Some tokens (e.g., WECAN) may encounter engineering challenges during addition—if the first update only partially succeeds, follow up with engineering for the remaining tokens. This is a recurring request pattern from institutional clients listing new assets.

"Updating token spending limits is not supported in the UI. However, you can just create a new token with the new spending limits." "We have added WECAN spending limits on the token. Thank you for your patience and apologies for all the inconvenience." "Our engineering team created this API so you can easily update your spending limits on the existing tokens programmatically on your end whenever it's required quickly."


Scenario: token-tokens-erc20-access#token-disappeared-unexpected-expiration

Trigger: Customer reports their access token disappeared from the UI without them deleting it, and they believe it should still be valid.

Signals: token disappeared, token deleted, missing token, expired tokens, duration, access token gone

Steps:

  1. Explain that expired tokens are automatically deleted from the UI view. No audit log entry is created for automatic expiration (unlike manual deletion, which does appear in past activity).
  2. Ask the customer to confirm the exact account email and enterprise ID used to create the token.
  3. Search Grafana/Loki logs for the token creation event. Locate the "duration" field in the creation request body. The duration is specified in seconds.
  4. Calculate the actual expiration: creation timestamp + duration in seconds. Confirm whether the token expired earlier than the customer expected.
  5. A common mistake is setting a short duration (e.g., 572522.211 seconds ≈ ~7 days) when the customer intended a much longer period (e.g., 10 years). Another example: 560656.87 seconds ≈ ~6.5 days.
  6. Advise the customer to create a new token with the correct duration. Double-check the duration value before confirming creation.

Notes: If the customer manually deleted the token, this action will appear in the past activity logs. Absence from activity logs confirms automatic expiration, not manual deletion.

"I was able to locate the creation request in our logs, this is the duration in seconds that was used 'duration":572522.211' which is around 7 days." "The duration is in seconds, 560656.87 which means it expired roughly sometime on 22/01" "Please note that expired tokens are deleted from the view. The token must have expired and thus was deleted."


Scenario: token-tokens-erc20-access#401-unauthorized-no-access-token

Trigger: Customer receives HTTP 401 with "error":"No access token" and "invalidToken":true or "noAccessToken":true.

Signals: 401, Unauthorized, No access token, invalidToken, noAccessToken, API tokens stopped working

Steps:

  1. This error indicates the access token is not being sent in the API request header, not that the token itself is invalid.
  2. Ask the customer to share the full request (with the access token value replaced by dummy data) so you can verify the token is being included in the Authorization: Bearer header.
  3. Check server-side logs for the request. Look for noAccessToken: true which confirms the token was absent from the request.
  4. Verify the access token still exists in the user's account under Developer Options. If it does, the token itself is fine.
  5. Advise the customer to ensure the access token is correctly passed in every API call and that the correct token value is being used (not an old or rotated one).
  6. If IP restrictions are configured on the token, confirm the customer's server IP is in the allowed list.

Notes: This error is distinct from "session expired." Do not conflate the two.

"The error received indicates that you are not sending an access token in the request so the user is not authorized to do the call without an access token added with the needed permission... we see noAccessToken":true, like it's not being sent."

Scenario: token-tokens-erc20-access#session-expired-error

Trigger: Customer or third-party integrator receives "error":"session expired" on API calls despite the access token appearing valid in the UI.

Signals: session expired, 401, Unauthorized, reqId, fund admin, NAV, Hedgeguard, spending limit surpassed

Steps:

  1. A "session expired" error is not the same as an access token expiration. It indicates the session associated with the token has ended.
  2. Check whether the access token is still visible in the creator's account under Developer Options. If present, the token has not reached its expiration date.
  3. Investigate whether a lifetime spending limit configured on the token has been surpassed. Exhausted spending limits can trigger session/authorization errors, requiring the token to be recreated.
  4. Check whether the third party is using the long-lived token directly or deriving short-lived session tokens from it. If the latter, the short-lived tokens may be expiring.
  5. If spending limits are exhausted, advise the customer to create a new access token with updated limits.

Notes: This pattern is common when fund administrators (e.g., NAV Consulting, Hedgeguard) use tokens shared by the customer.

"It appears any lifetime spending limit configured on these tokens, may have been surpassed requiring these Access Tokens be recreated." "The error provided does not seem to indicated the Access Token Bill provided has expired, it is indicating the session expired which is similar to being logged out of the UI."


Scenario: token-tokens-erc20-access#scope-error-creating-token-via-api

Trigger: Customer receives "Access token lacks required scope for this action" when trying to create a new access token via the API.

Signals: Access token lacks required scope, scope, create access token, v2/user/accesstoken, bitgo-test

Steps:

  1. If the customer created their initial token via the UI and is using it to call v2/user/accesstoken to create a new token via API, this may trigger a known bug.
  2. Workaround: Advise the customer to create the first token (Token A) via the login API at https://developers.bitgo.com/api/v2.user.login, then use Token A to create Token B via the v2.accesstoken.add API.
  3. Alternatively, the customer can create access tokens directly from the UI as an interim measure.
  4. Confirm the customer's user role is Enterprise Admin or Owner; members may not have sufficient permissions.

Notes: This bug specifically affects token creation via API when the parent token was created through the UI. The workaround of using the login API first is the confirmed resolution from engineering.

"Please create the token A via this API https://developers.bitgo.com/api/v2.user.login and then use that to create token B via v2.accesstoken.add API. The method you used earlier—creating the first token via the UI—will result in an error." "Apologies for the inconvenience caused. when we tested it out there is a bug affecting the API for the creating the access token. we are currently working on a fix. In the meantime, please use the UI to create the access token."


Scenario: token-tokens-erc20-access#coin-not-enabled-for-account

Trigger: Customer receives an error like "To enable for your account, contact support@bitgo.com" when attempting to interact with a token/coin.

Signals: enable, contact support@bitgo.com, ungated, allowcoin, tbaseeth, ethx, token not enabled

Steps:

  1. This error means the specific coin or token is not yet enabled ("ungated") for the customer's user account.
  2. Use the admin tool command bga user allowcoin <coin> for the affected user account(s) to enable the coin.
  3. If multiple users on the enterprise need access, run the allowcoin command for each user.
  4. After enabling, ask the customer to retry and confirm the error is resolved.

Notes: This applies to both mainnet and testnet tokens. For testnet tokens (e.g., tbaseeth:xsgd), the same ungating process applies on the test environment.

"bga user allowcoin ethx" "Token has been ungated. Please try again."


Scenario: token-tokens-erc20-access#erc20-received-at-eth-address

Trigger: Customer asks how to receive an ERC20 token or does not understand which wallet to use for a specific token.

Signals: ERC20, receive, deposit, ETH wallet, same address, token, Arbitrum, ARBETH, network

Steps:

  1. ERC20 tokens are received at the same deposit addresses as ETH. The customer does not need to create a separate wallet for ERC20 tokens.
  2. Instruct: Once an ETH wallet is created, click the "Deposit" button next to the wallet to get the receive address.
  3. Important: The receiving wallet must match the network the token is being sent on. If a token is being sent on Arbitrum, it must be received in an ARBETH wallet, not an Ethereum wallet.
  4. For the USDT dropdown issue: The first Tether entry in the access token spending limit dropdown is ERC20 USDT. The second entry (e.g., EOS:USDT) is a different network. A UI bug previously made these indistinguishable; advise the customer to select the first entry for ERC20 USDT.
  5. Only Enterprise Owners can create wallets. If the user is a member, they will not see the wallet creation option. The current owner must remove and re-add the user as an owner, or the owner must create the wallet.

Notes: To change a user from member to owner, the user must be removed from the enterprise and re-added as an owner. Direct role changes from member to owner are not supported.

"Since this is an ERC20 token, it is received at the same receive addresses which receive your ETH. Once you or an Enterprise Owner has created an ETH wallet, you can choose the 'Deposit' button next to the wallet." "The Receiving Wallet should be of the same Network as where its being sent. If being sent on ARB, it should be sent to an ARBETH wallet." "The first Tether in the dropdown is erc20 USDT. The 2nd Tether (EOS:USDT) will be fixed to be distinguished from erc20 USDT."


Scenario: token-tokens-erc20-access#ui-error-creating-access-token

Trigger: Customer encounters a UI error (overlay closes immediately, error screen) when creating an access token in the BitGo web dashboard.

Signals: create access token error, web UI, overlay closed, Microsoft Edge, webhook error, block webhook

Steps:

  1. Recommend the customer use Google Chrome. The BitGo platform is developed and optimized for Chrome. Microsoft Edge and other browsers may exhibit UI issues.
  2. Advise the customer to pause or create an exception for any adblockers when using the BitGo site.
  3. If the error persists on Chrome, ask the customer to log out, log back in, and retry creating the access token.
  4. If the issue is on the test environment and involves webhook-related errors: check if a block webhook was created via API on one of the customer's wallets. Block webhooks created with incorrect parameters can cause UI errors during access token creation. The token may actually be created despite the error, but the key is not displayed.
  5. For block webhook issues, instruct the customer to remove the webhook via the API endpoint: https://developers.bitgo.com/api/v2.webhooks.remove. Block webhooks can only be removed via API, not the UI.
  6. If the issue was caused by a frozen wallet with a suspended webhook, advise accordingly once engineering has resolved the underlying bug.

Notes: A known bug caused the access token to be created successfully behind the scenes while the UI displayed an error and did not show the token key. Engineering fixed this specific issue.

"suggested step of logging out and then back in customer was able to resolve the issue." "We recommend using Google Chrome with our platform as our site is maximized and developed with Chrome in mind." "It does appear the Access Token was still created despite the error and unfortunately did not present the Token key to you on-screen. It appears this is connected to the webhook that was created."


Scenario: token-tokens-erc20-access#access-token-permissions-and-scopes

Trigger: Customer asks which permissions or scopes are required for specific API endpoints, or gets permission errors when calling wallet/key endpoints.

Signals: permissions, scopes, wallet_view_all, wallet_spend_all, Full Administrative Access, Viewer, key endpoint

Steps:

  1. The access token creator's role on the wallet determines what the token can do. The token inherits the creator's permissions.
  2. For reading wallet info (GET /api/v2/{coin}/wallet/{walletId}): The token creator needs at least "Viewer" permission on the wallet.
  3. For listing or getting keys (GET /api/v2/{coin}/key and GET /api/v2/{coin}/key/{id}): The token creator needs to be an Admin on the wallet, and the token needs Wallet - Full Administrative Access configured.
  4. For spending (wallet_spend_all or wallet_spend): The token creator must have spending rights on the wallet, and the token must include the corresponding spend scope.
  5. The "Users Can View All Wallets" enterprise feature provides limited view access that is less than full "Viewer" permission—do not confuse the two.
  6. If the customer's token was created before they were added to specific wallets, transactions on those wallets may not appear. The token reflects the creator's permissions at the time of the API call, but wallet share/access must already be in place.

Notes: For institutional accounts, refer sales inquiries to sales@bitgo.com.

"For returning a GET on a specific Wallet ID, the Access Token Creator would need to have 'Viewer' permission on the wallet for a user of the token to return info for the wallet." "For https://developers.bitgo.com/api/v2.key.list and https://developers.bitgo.com/api/v2.key.get, the 'ID' shown corresponds to the Wallet ID the key belongs to. For these to return results, the expectation is the Access Token Creator needs to be an Admin on the wallet and the Token will need Full Admin Priv configured."


Scenario: token-tokens-erc20-access#token-enablement-algo-hbar-sol

Trigger: Customer asks for the API endpoint to enable tokens on ALGO, HBAR, or SOL chains.

Signals: token enablement, ALGO, HBAR, SOL, enabletoken, TxRequest, sendtomany

Steps:

  1. Point the customer to the SDK documentation for token enablement: https://developers.bitgo.com/guides/transact/token-enablement.
  2. For SOL specifically, the API endpoint is https://developers.bitgo.com/api/v2.wallet.tx.initiate with type = "enabletoken".
  3. For programmatic (non-SDK) usage: Within the SDK, the sendtomany call creates a TxRequest with intentType set to enableToken. The TxRequest API endpoints should work for this purpose.

Notes: This applies to chains that require on-chain token association/enablement (e.g., Solana token accounts, HBAR token association, Algorand ASA opt-in).

"This is for SOL - https://developers.bitgo.com/api/v2.wallet.tx.initiate. type ='enabletoken'" "Within the SDK, all the sendtomany call is creating a TxRequest with intentType enableToken. The TxRequest API endpoints should work for this."


Scenario: token-tokens-erc20-access#finding-access-token-in-ui

Trigger: Customer cannot locate where to create or find their access token in the BitGo UI.

Signals: access token, developer portal, where to find, Developer Options, Enterprise Settings

Steps:

  1. Instruct the customer to log in to the BitGo platform at https://app.bitgo.com/auth/log-in.
  2. Click the Profile Icon at the top of the dashboard.
  3. Select Enterprise Settings.
  4. When the screen refreshes, navigate to the Developer Options tab.
  5. Access tokens can be created and viewed from this section.

Notes: For institutional features (omnibus wallets, multi-currency), customers need a contracted Institutional Account. Refer them to sales@bitgo.com for more information.

"You will want to login to the platform, choose the Profile Icon > Enterprise Settings. When the screen refreshes, you should see a Developer Options tab."

Scenario: token-tokens-erc20-access#password-error-ccm-tag

Trigger: Customer receives "password error - ccm: tag doesn't match" when making API calls with their access token.

Signals: password error, ccm, tag doesn't match, sendmany, 400

Steps:

  1. This error indicates a wallet credential or encryption key mismatch, not an access token configuration issue.
  2. Ask the customer to confirm which user created the access token and whether that user is still an admin on the affected wallet.
  3. Recommend having a wallet admin remove and re-add the affected user from the wallet, then retry.
  4. If the original wallet creator is no longer available (e.g., left the organization), identify another admin on the wallet and have them create a new access token for API operations.
  5. If the issue persists, request the full error log including requestId for further investigation.

Notes: This may occur when an access token is created by a user whose wallet share/keychain state is inconsistent, such as after enterprise migrations.

"Please have [the user] removed from this wallet and then re-added. Once this has been performed, can you re-attempt this action?"

Scenario: token-tokens-erc20-access#test-erc-token-minting

Trigger: Customer asks how to obtain test ERC20 tokens (e.g., BGERCH) on the Holesky testnet.

Signals: test, Holesky, BGERCH, testnet, mint, ERC Token, test token

Steps:

  1. Install the MetaMask Chrome extension and create an account.
  2. Enable test networks in MetaMask and add the Holesky network.
  3. Fund the MetaMask test wallet with Holesky ETH.
  4. Visit the token contract on Holesky Etherscan (e.g., https://holesky.etherscan.io/token/<contract_address>#writeContract).
  5. Select "Write Contract" > "Connect To Web3" and connect MetaMask.
  6. Use the mint function to mint tokens. The minting limit per transaction is 10*(10^decimals).
  7. After minting, import the token into MetaMask using the token contract address.
  8. Send the minted tokens to the BitGo test wallet address.

Notes: NFT testing on testnet is not covered in the available documentation. The minting limit is a security measure to prevent rendering the contract useless.

Related