NAV Navbar
Logo
javascript shell

Getting Started on Platform V2

Overview

BitGo provides a simple and robust RESTful API and client SDK to integrate digital currency wallets with your application. In Platform V2, we have extended our API and SDK to allow the management of multiple digital currencies and wallets through a single, unified interface.

The BitGo SDK enables the following:

Legacy users may also refer to the V1 Bitcoin API, which is still available today. There is no dependency for developers to integrate with V1 or read the legacy documentation in order to take advantage of Platform V2.

Multi-Signature Wallets

The primary advantage of multi-signature wallets is the ability for multiple machines and people to work together to approve a given transaction. Without multiple signatures on a transaction, all credentials to approve a transaction must reside with a single person on a machine. If that person or machine is compromised by an attacker, all funds can be taken with no recourse and no ability to audit the individual that invoked the key.

BitGo’s multi-signature wallets allow you to keep control of your Bitcoin or other cryptocurrency despite introducing the concept of a co-signer. This allows enterprises to set up and maintain roles, policies, and rules on the wallet, making digital currency usable for businesses.

For more information, please read the BitGo Whitepaper.

Software Development Kit

To initialize your environment and authorize, use the following code:

const BitGoJS = require('bitgo');
// Read the user authentication section to get your API access token
const bitgo = new BitGoJS.BitGo({ env: 'test', accessToken: process.env.ACCESS_TOKEN });
let coin = bitgo.coin('tbtc');

The BitGo web APIs provide developers with the capability to create and manage multi-signature wallets, manipulate their policies and interact with multiple digital currencies over a single robust interface. Several sensitive operations, such as the creation of user private keys and signing of transactions, must to be performed client-side.

For this reason, we provide and recommend the use of our Software Development Kit (SDK), which implements these client-side wallet features and interfaces with our APIs.

Currently, our SDK is available in Javascript and runs in either node.js or a browser. If your application does not use native Javascript, you may refer to the BitGo Express REST API guide, which offers the same feature set via a local server daemon.

Installing the Javascript SDK (via npm)

npm install bitgo --save

Installing the Javascript SDK (via Github)

node auth.js <testusername> <testpassword> 0000000

BitGo Express REST API

The REST API is only relevant through the Shell interface because it is a local server.

./bitgo-express --debug --port 3080 --env test --bind localhost

BITGO_EXPRESS_HOST='localhost'
curl http://$BITGO_EXPRESS_HOST:3080/api/v2/ping

The BitGo Express REST API is a lightweight service for developers that want to take advantage of BitGo, but are developing in a language without a native BitGo SDK.

BitGo Express runs as a service in your own datacenter, and handles the client-side operations involving your own keys, such as partially signing transactions before submitting them to BitGo. This ensures your keys never leave your network, and are never seen by BitGo. BitGo Express can also proxy the standard BitGo REST APIs, providing a unified interface to BitGo through a single REST API.

To use BitGo Express:

./bitgo-express --debug --port 3080 --env test --bind localhost

Environments

BitGo has two separate environments available for development and production. For security reasons, all BitGo API requests are made using TLS over HTTPS.

All responses are of content-type application/json.

Test Environment

The BitGo test environment is used by default in our examples and the SDK. It is entirely separate from BitGo’s production environment and there is no overlap in either data or accounts. You will need to create accounts at test.bitgo.com.

In the test environment, you can use 0000000 in place of the OTP when authenticating with BitGo (for the purpose of automated tests).

This environment is connected to the TestNet networks of various digital currencies we support. Tokens on these networks can be obtained from faucets and do not represent real money.

Production Environment

The BitGo production endpoint is live and used by partners and our own web application on www.bitgo.com.

To use this environment, specify { env: 'prod' } when using the SDK or -e prod when running BitGo Express. SSL certifications should be provided to secure traffic to and from the BitGo Express instances when operating on the Production environment.

Coin / Digital Currency Support

BitGo Platform V2 supports a variety of digital currencies, with more being added every quarter.

To take advantage of BitGo’s V2 platform, download the existing SDK, and select the currency / coin of choice as in the example below:

var bitgo = new BitGoJS.BitGo({ env: 'test', accessToken: process.env.ACCESS_TOKEN });

var coin = bitgo.coin('btc');

(replace btc with your desired coin identifier)

The base API urls have been changed from

https://www.bitgo.com/api/v1/..

to

https://www.bitgo.com/api/v2/btc/..

Identifier Digital Currency Family BitGo Environment Release status
btc Bitcoin UTXO-based Production General availability
bch Bitcoin Cash UTXO-based Production General availability
btg Bitcoin Gold UTXO-based Production General availability
eth Ethereum Account Production Enterprise access
ltc Litecoin UTXO-based Production General availability
xrp Ripple Account Production Enterprise access
rmg Royal Mint Gold UTXO-based Production Enterprise access
bat Basic Attention ERC20 token Account Production Enterprise access
brd Bread ERC20 token Account Production Enterprise access
cvc Civic ERC20 token Account Production Enterprise access
fun FunFair ERC20 token Account Production Enterprise access
gnt Golem ERC20 token Account Production Enterprise access
knc Kyber Network ERC20 token Account Production Enterprise access
mkr Maker ERC20 token Account Production Enterprise access
nmr Numeraire ERC20 token Account Production Enterprise access
omg OmiseGo ERC20 token Account Production Enterprise access
pay TenX ERC20 token Account Production Enterprise access
qrl Quantum ERC20 token Account Production Enterprise access
rep Augur ERC20 token Account Production Enterprise access
rdn Raiden Network ERC20 token Account Production Enterprise access
wax Worldwide Asset eXchange ERC20 token Account Production Enterprise access
zil Zilliqa ERC20 token Account Production Enterprise access
zrx 0x ERC20 token Account Production Enterprise access
tbtc Bitcoin Testnet UTXO-based Test General availability
tbch Bitcoin Cash Testnet UTXO-based Test General availability
teth Ethereum Kovan Testnet Account Test Enterprise access
terc Ethereum ERC20 Token Testnet Account Test Enterpise access
tltc Litecoin Testnet UTXO-based Test Generic availability
txrp Ripple Testnet Account Test Enterprise access
trmg Royal Mint Gold Testnet UTXO-based Test Enterpise access

Read the section on coin-specific implementations for more information.

Client Constants

bitgo.fetchConstants()
.then(function(constants) {
  // print constants
  console.dir(constants);
})
curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v1/client/constants

Example JSON Response:

{
  "maxFee": 100000000,
  "maxFeeRate": 1000000,
  "minFeeRate": 0,
  "minInstantFeeRate": -1000,
  "fallbackFeeRate": 1016,
  "minOutputSize": 2730,
  "defaultGasPrice": 30000000000000,
  "bitgoEthAddress": "0x0f47ea803926926f299b7f1afc8460888d850f47",
  "enableSegwit": true,
  "eth": {
    "tokens": [{
      "type": "terc",
      "tokenContractAddress": "0x945ac907cf021a6bcd07852bb3b8c087051706a9",
      "decimalPlaces": 0
    }]
  }
}

BitGo uses certain constant values for providing the SDK service.

Currently you can take a look at a list of ERC20 tokens, their contract addresses and the number of decimal places the token supports.

Error Handling

Example JSON Error:

{
  "status":  "400 Bad Request",
  "error": "missing user name"
}

All errors follow general REST principles. Included in the body of any error response (e.g. non-200 status code) will be an error object of the form:

Parameter Value
status The HTTP error status returned
error The detailed description of the error

The BitGo API uses the following error codes:

Error Code Meaning
202 Accepted (but requires approval, if for transaction sends)
400 Bad Request
401 Unauthorized
403 Forbidden
404 Not Found
429 Too Many Requests
500 Internal Server Error
503 Service Unavailable
504 Gateway Timeout

Pagination

bitgo.coin('tbtc').wallets().list({ limit: 50 })
.then(function(wallets) {
  // print wallet list
  console.dir(wallets);
});
curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet?limit=50

Example JSON Response:

{
  "coin": "tbtc",
  "wallets": [
    {
      "_wallet": {
        "id": "585a0860c5a04c696edd2c331ce2f346",
        "users": [
          {
            "user": "55cce42633dc60ca06db38e643622a86",
            "permissions": [
              "admin",
              "view",
              "spend"
            ]
          }
        ],
        "coin": "tbtc",
        "label": "V2 TBTC Test Wallet",
        "m": 2,
        "n": 3,
        "keys": [
          "585a085cc5a04c696edd2c285839ba20",
          "585a085cc5a04c696edd2c2a0ec9c72d",
          "585a085c00cdd96a6ec41eb0d189d80b"
        ],
        "tags": [
          "585a0860c5a04c696edd2c33"
        ],
        "disableTransactionNotifications": false,
        "freeze": {},
        "deleted": false,
        "approvalsRequired": 1,
        "coinSpecific": {},
        "balance": 0,
        "confirmedBalance": 0,
        "spendableBalance": 0,
        "balanceString": "0",
        "confirmedBalanceString": "0",
        "spendableBalanceString": "0"
      }
    },
  ],
  "count": 50,
  "nextBatchPrevId": "590b73478c8fc40727b0c3d421ec909c"
}

Certain routes, such as listing wallets or transactions, may return an array of results.

By default, the API will return 25 results per request. The limit parameter may be used to increase the number of results per request, up to a maximum of 500.

To get the next batch of results, call the same route again with a prevId request parameter corresponding to the nextBatchPrevId property received in the last call.

Notes for BitGo V1 Integrators

BitGo values our loyal customers that have developed with us on the V1 platform. There are no plans to deprecate the V1 platform at this time. If you’ve read up to here, you may be interested in using BitGo’s V2 platform to gain access to the new digital currencies we support.

BitGo has developed the V2 API and SDK to be similar to the interfaces you are familiar with. We encourage you to refer to this document when building your new integration, as certain properties and interfaces may have changed.

For your convenience, here are some of the more notable differences you should pay attention to.

Users and authentication

The V2 platform uses the same user database as the V1 platform. You will not need to create new users or access tokens.

BitGo has developed a more secure authentication mechanism that we call Auth V2, which you can take advantage of simply by using the latest version of our SDK / BitGo Express.

Balance Strings

On most digital currencies, the wallet, transaction and address objects all contain a balance property.

In BitGo Platform V2, we have introduced a String suffix for all balances, as certain digital currencies (such as Ethereum) feature balance ranges which exceed those that can be stored as a typical number in Javascript.

While the balance property will continue to be a number, it will not be available on all currencies across the V2 platform. We recommend using balanceString instead of balance for this reason, and balanceString will be available as a property over all digital currencies on V2. This applies to all number properties.

For more information on whether the coin of choice supports balance numbers, you may refer to the coin support section of the document. All coins will have the balanceString property.

Pagination

In BitGo’s V1 APIs, pagination was often done via limit and skip. In BitGo Platform V2, we have moved to the limit and prevId method of iteration.

Wallet Transfers

In the past, the wallet transactions model was the primary way of tracking and listing deposits/withdrawals from your wallet.

We now introduce the transfers model, which serves this purpose generically across digital currencies and has a cleaner interface that is recommended for tracking deposits and withdrawals.

Transaction information is still available on your wallets, but may differ between digital currencies, and contain entries that do not impact the wallet balance. For example, in certain digital currencies such as Ethereum, a deployment transaction is made to deploy your wallet, but does not involve a funds transfer affecting your balance.

User Authentication

BitGo’s authentication utilizes the Authorization header, which allows the caller to specify an access token.

Access tokens are used to maintain a session and are created via password login (requires OTP) or OAuth login paths. Typical access tokens obtained via the web interface are locked to a single IP-address and are valid for 60 minutes, although developers may create long lasting tokens.

For sensitive API calls (such as those that spend funds), a valid session token is not sufficient. To access these API calls, the session must be explicitly unlocked using the Unlock API by using an additional OTP. A single unlock call enables the user to do one transaction of any size (still subject to wallet policy), or any number of transactions up to an internal BitGo-managed quota.

Alternatively, custom access tokens can be created bound to specific scopes for expiration time, permission level, and spending amount.

API Access Tokens

For the purposes of automation, developers can request long-lived access tokens with a custom expiration time and unlock them for a specified spending limit. These access tokens must be locked to an IP address.

Creation via the web interface

  1. Access the BitGo dashboard and head into the “User Settings” page from the top right menu.
  2. Click on the “Developer” tab.
  3. You can now create a long-lived access token.

The token will come unlocked by default with your specified spending limit. Do not attempt to unlock the token again via API as this will reset the unlock.

Creation via the API

ACCESS_TOKEN='DeveloperAccessToken'

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{}' \
-H "Content-Type: application/json" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/user/session
var bitgo = new BitGoJS.BitGo({ accessToken:'v2xDeveloperAccessToken' });
bitgo.session({}, function callback(err, session) {
  if (err) {
    // handle error
  }
  console.dir(session);
});

Alternatively, custom access tokens can be requested via the API command addAccessToken. This call requires an OTP, a label, and an authorization scope. It may specify an expiration time, an IP whitelist, and a spending limit.

Security note

BitGo’s SDK and Express App secures tokens using our Auth V2 protocol, which does not send the access token over the wire. We recommend you secure the token carefully and do not send them over curl or any other means!

HTTP Request

POST /api/v2/user/session

Body Parameters

Parameter Type Required Description
label String Yes The label identifying the token, e.g. for subsequent revocation.
otp String Yes The 2-factor-authentication otp code.
ipRestrict String Array Yes A whitelist of IP addresses that may use the token.
scope String Array Yes The list of privileges authorized by this token. Follow principles of least privilege (only spend and not manage) for automated tokens.
duration Number No The duration in seconds for which the token will be valid. If this parameter is not set, the duration defaults to ten years.
txValueLimit Number No The total spending allowance permitted by this token given in satoshis. Do not attempt to unlock the token via API as this will reset the limit.

Current User Profile

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/user/me
bitgo.me({}, function callback(err, user) {
  if (err) {
    // handle error
  }
  // etc
});

This API call retrieves information about the current authenticated user. You can use this API call as a sort of sanity test or if you use multiple users in your code.

HTTP Request

GET /api/v2/user/me

Example User Model response

{
  "user": {
    "id": "53532a4b43fd69a42f000005f0a2ed87fd8b020040739beb513524b5",
    "isActive": true,
    "name": {
      "first": "Jane",
        "full": "Jane Doe",
        "last": "Doe"
    },
    "username": "janedoe@bitgo.com"
  }
}

Response

Returns a User Model object for the currently authenticated user.

Session Information

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{}' \
-H "Content-Type: application/json" \
https://test.bitgo.com/api/v2/user/session
bitgo.session({}, function callback(err, session) {
  if (err) {
    // handle error
  }
  console.dir(session);
});

Example response

{
  "client": "bitgo",
  "user": "5458141599f715232500000530a94fd2",
  "scope": [
    "user_manage",
    "openid",
    "profile",
    "wallet_create",
    "wallet_manage_all",
    "wallet_approve_all",
    "wallet_spend_all",
    "wallet_edit_all",
    "wallet_view_all"
  ],
  "expires": "2015-01-21T02:18:11.534Z",
  "origin": "test.bitgo.com",
  "unlock": {
    "time": "2015-01-21T01:20:25.366Z",
    "expires": "2015-01-21T01:30:25.366Z",
    "txCount": 0,
    "txValue": 0
  }
}

This API call retrieves information about the current session access token.

You can use this API call if you’d like to verify the scope of your access token, which will include allowed scopes as well as the expiration date of the token and any associated unlocks.

HTTP Request

GET /api/v2/user/session

Response

Field Description
client OAuth client ID where the user token was obtained
user BitGo user ID
expires Timestamp which the login session is good until
scope List of allowed privileges for this session token
origin Origin hostname where token was created, if the session was initiated in the browser
unlock Available if session is unlocked. Shows number of transactions and expiry time of the unlock

Lock

curl -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/user/lock \
bitgo.lock({})
.then(function(lockResponse) {
  // …
});

Locks the current session, preventing future automated sends without a subsequent unlock (OTP will be required for the unlock).

HTTP Request

POST /api/v2/user/lock

Response

None

Errors

Response Description
401 Unauthorized The authentication parameters did not match

Unlock

curl -X POST -H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{"otp": "0000000"}' \
-H "Content-Type: application/json" \
https://test.bitgo.com/api/v2/user/unlock
bitgo.unlock({ otp: '0000000' })
.then(function(unlockResponse) {
  console.dir(unlockResponse);
});

Unlock the current session, which is required for certain other sensitive API calls.

HTTP Request

POST /api/v2/user/unlock

Body Parameters

Parameter Type Required Description
otp String Yes An OTP code for the account obtained using the second factor authentication device
duration Number No Desired duration of the unlock in seconds (default=600, max=3600)

Response

None

Errors

Response Description
400 Bad Request The request parameters were missing or incorrect
401 Unauthorized The authentication parameters did not match, or OTP code was incorrect

Login

bitgo.authenticate({ username: user, password: password, otp: '0000000' })
.then(function(response) {
  var token = response.token;
  var user = response.user;
  // etc
});
EMAIL="janedoe@bitgo.com"
PASSWORD="mypassword"

curl -X POST \
-H "Content-Type: application/json" \
-d "{\"email\": \"$EMAIL\", \"password\": \"$PASSWORD\", \"otp\": \"0000000\"}" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/user/login

Example Response:

{
  "access_token": "3fe0bf671c943af5ee3b739d2b17ffced7fdde62",
  "expires_in": 3600,
  "token_type": "bearer",
  "user": {
    "id": "53532a4b43fd69a42f000005f0a2ed87fd8b020040739beb513524b5",
    "isActive": true,
    "name": {
      "first": "Jane",
      "full": "Jane Doe",
      "last": "Doe"
    },
    "username": "janedoe@bitgo.com"
  }
}

Note: The rest of the shell examples assume the shell variable ACCESS_TOKEN contains the access token.

Get a token for first-party access to the BitGo API. First-party access is only intended for users accessing their own BitGo accounts. For 3rd party access to the BitGo API on behalf of another user, please see Partner Authentication.

HTTP Request

POST /api/v2/user/login

Body Parameters

Parameter Type Required Description
email String Yes The user’s email address
password String Yes The user’s password
otp String Yes The 2nd-factor-authentication token
extensible Boolean No True if the session is supposed to be extensible beyond a one-hour duration.

Response

Returns a token for use with the API.

The token must be added as a HTTP header to all API calls in the HTTP “Authorization” header:

Authorization: Bearer <your token goes here>

Errors

Response Description
400 Bad Request The request parameters were missing or incorrect.
401 Unauthorized The authentication parameters did not match.

Logout

curl -X GET -H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/user/logout
bitgo.logout({})
.then(function() {
  // the user is now logged out
});

Log out of the BitGo service. This will disable an access token.

HTTP Request

GET /api/v2/user/logout

Response

None

Wallets

All BitGo Wallets are multi-signature wallets comprised of N keys, and require M keys to sign a transaction before the transaction is valid. This is called an M-of-N wallet. BitGo currently supports only 2-of-3 wallets.

To create a wallet, 3 keychains must be provided. The first two keychains are provided and under control of the user; the last must be a BitGo keychain.

While BitGo can see the public portion of the first two keys, BitGo never has access to the private portion of these keys and therefore cannot conduct transactions without the user. The third BitGo key is not sufficient to sign transactions alone, and BitGo will only use this key in accordance with the policies set forth by the user.

List Wallets

bitgo.coin('tbtc').wallets().list({})
.then(function(wallets) {
  // print the wallets
  console.dir(wallets);
});
curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet

The above will print an object structured as follows:

{
  "wallets": [
    {
      "id": "585951a5df8380e0e3063e9f",
      "users": [
        {
          "user": "55e8a1a5df8380e0e30e20c6",
          "permissions": [
            "admin",
            "view",
            "spend"
          ]
        }
      ],
      "coin": "tbtc",
      "label": "Alex's first wallet",
      "m": 2,
      "n": 3,
      "keys": [
        "585951a5df8380e0e304a553",
        "585951a5df8380e0e30d645c",
        "585951a5df8380e0e30b6147"
      ],
      "tags": [
        "585951a5df8380e0e30a198a"
      ],
      "disableTransactionNotifications": false,
      "freeze": {},
      "deleted": false,
      "approvalsRequired": 1,
      "coinSpecific": {}
    },
    
  ]
}

This API call lists all of a user’s wallets for a given coin. This is useful when you have over 500 wallets as you will not be able to use the Web UI.

HTTP Request

GET /api/v2/:coin/wallet

Query Parameters

Parameter Type Required Description
limit Integer No Max number of results in a single call. Defaults to 25.
prevId String No Continue iterating wallets from this prevId as provided by nextBatchPrevId in the previous list
allTokens Boolean No Gets details of all tokens associated with this wallet. Only valid for eth/teth

Response

Returns an array of Wallet Model objects. See Get Wallet for the wallet object.

Field Description
wallets Array of wallet model objects
nextBatchPrevId Can be used to iterate the next batch of results

Errors

Response Coins Description
400 Bad Request ETH Insufficient funds in fee address: ${WALLET-ADDRESS}
400 Bad Request ALL Wallet already exists
400 Bad Request ALL Missing keys or missing label
400 Bad Request ALL Keys must be unique
400 Bad Request ETH Token wallet creation unsupported, please use Ethereum wallet instead
400 Bad Request XRP Please contact support@bitgo.com for the ability to create more than 5 Ripple wallets
401 Unauthorized ALL Access token lacks required scope for this action
401 Unauthorized XRP,ETH Cannot access this route with coin type xrp/eth, please contact sales@bitgo.com to enable these coin types
401 Unauthorized ALL Invalid enterprise
404 Not Found ALL At least one key not found

Generate Wallet

bitgo.coin('tltc').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/tltc/wallet/generate

The newly minted wallet object looks as follows:

{
  "wallet": {
    "_wallet": {
      "id": "591a40dd9fdde805252f0d8aefed79b3",
      "users": [
        {
          "user": "55cce42633dc60ca06db38e643622a86",
          "permissions": [
            "admin",
            "view",
            "spend"
          ]
        }
      ],
      "coin": "tltc",
      "label": "My Test Wallet",
      "m": 2,
      "n": 3,
      "keys": [
        "591a40dc422326ff248919e62a02b2be",
        "591a40dd422326ff248919e91caa8b6a",
        "591a40dc9fdde805252f0d87f76577f8"
      ],
      "tags": [
        "591a40dd9fdde805252f0d8a"
      ],
      "disableTransactionNotifications": false,
      "freeze": {},
      "deleted": false,
      "approvalsRequired": 1,
      "isCold": false,
      "coinSpecific": {},
      "balance": 0,
      "confirmedBalance": 0,
      "spendableBalance": 0,
      "balanceString": "0",
      "confirmedBalanceString": "0",
      "spendableBalanceString": "0",
      "receiveAddress": {
        "address": "QRWXF9VxJnbSx5uYbX99kuw55pUW4DrmTx",
        "chain": 0,
        "index": 0,
        "coin": "tltc",
        "wallet": "591a40dd9fdde805252f0d8aefed79b3",
        "coinSpecific": {
          "redeemScript": "522103e8bc…c7ac0e53ae"
        }
      },
      "pendingApprovals": []
    }
  }
}

This API call creates a new wallet. Under the hood, the SDK (or BitGo Express) does the following:

  1. Creates the user keychain locally on the machine, and encrypts it with the provided passphrase (skipped if userKey is provided).
  2. Ceates the backup keychain locally on the machine, and encrypts it with the provided passphrase (skipped if backupXpub or backupXpubProvider are provided).
  3. Uploads the encrypted user and backup keychains to BitGo.
  4. Creates the BitGo key (and the backup key if backupXpubProvider is set) on the service.
  5. Creates the wallet on BitGo with the 3 public keys above.

HTTP Request

POST /api/v2/:coin/wallet/generate

Body Parameters

Parameter Type Required Description
label String Yes Human-readable name for the wallet.
passphrase String Yes Passphrase to decrypt the wallet’s private key.
userKey String No Optional xpub to be used as the user key.
backupXpub String No Optional xpub to be used as the backup key.
backupXpubProvider String No Optional key recovery service to provide and store the backup key.
enterprise String No ID of the enterprise to associate this wallet with.
disableTransactionNotifications Boolean No Will prevent wallet transaction notifications if set to true.
gasPrice Integer No Custom gas price to be used for the deployment of the wallet (only for Ethereum)
passcodeEncryptionCode String No Encryption code for wallet passphrase (used for lost passphrase recovery)

Online Generation

Usually, when a wallet is generated in the browser, people want their user key to be encrypted with their wallet password. For that, no userKey needs to be passed, as it is generated randomly by the SDK.

Cold Storage

Some users may not want to have any explicit access to their private key, but rather want to keep it safe on a hardware device, such as a Ledger or a Trezor. In such cases, we recommend users simply pass through the xpub their hardware wallet returns in the userKey parameter.

Backup Keys

Depending on how secure users feel holding their own backup keys, they may choose to either use a Key Recovery Service (KRS) for their backup key storage, or opt to store the key themselves. For Bitcoin, you can pass keyternal through the backupXpubProvider parameter. For other currencies, please contact us.

If no backup provider is specified, users have a choice of either letting the SDK generate the backup key or passing through an already existing one. The latter route may be convenient if a user opts to have a hot wallet, but keep the backup key in cold storage to guarantee permanent fund availability.

Response

Field Description
id Id of the wallet (also the first receiving address)
label The wallet label, as shown in the UI
coin The digital currency this wallet holds
users Array of users and their permissions on this wallet
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
balance The amount of satoshis you will have in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The amount of satoshis that is currently spendable. (May not be set for some coins.)
confirmedBalance The amount of satoshis you have within your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
coinSpecific Currency-specific information about the new wallet
coinSpecific.feeAddress Fee address for this wallet (Ethereum only)
coinSpecific.lowPriorityFeeAddress Low priority fee address for this wallet (Ethereum only).

Add Wallet (Advanced)

bitgo.coin('teth').wallets()
.add({
  label: "My Wallet",
  m: 2,
  n: 3,
  keys: [
    "591a40dc422326ff248919e62a02b2be",
    "591a40dd422326ff248919e91caa8b6a",
    "591a40dc9fdde805252f0d87f76577f8"
  ]
})
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
USER_KEY_ID=591a40dc422326ff248919e62a02b2be
BACKUP_KEY_ID=591a40dd422326ff248919e91caa8b6a
BITGO_KEY_ID=591a40dc9fdde805252f0d87f76577f8

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"My Wallet\", \"m\": 2, \"n\": 3, \"keys\": [\"$USER_KEY_ID\", \"$BACKUP_KEY_ID\", \"$BITGO_KEY_ID\"]}" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/teth/wallet

The newly minted wallet object looks as follows:

{
  "wallet": {
    "_wallet": {
      "id": "591a40dd9fdde805252f0d8aefed79b3",
      "users": [
        {
          "user": "55cce42633dc60ca06db38e643622a86",
          "permissions": [
            "admin",
            "view",
            "spend"
          ]
        }
      ],
      "coin": "teth",
      "label": "My Wallet",
      "m": 2,
      "n": 3,
      "keys": [
        "591a40dc422326ff248919e62a02b2be",
        "591a40dd422326ff248919e91caa8b6a",
        "591a40dc9fdde805252f0d87f76577f8"
      ],
      "tags": [
        "591a40dd9fdde805252f0d8a"
      ],
      "disableTransactionNotifications": false,
      "freeze": {},
      "deleted": false,
      "approvalsRequired": 1,
      "isCold": false,
      "coinSpecific": {},
      "balance": 0,
      "confirmedBalance": 0,
      "spendableBalance": 0,
      "balanceString": "0",
      "confirmedBalanceString": "0",
      "spendableBalanceString": "0",
      "coinSpecific": {
        "deployedInBlock": false,
        "deployTxHash": "0x37b4092509254d60a4c29464f6979dcdaa3b10bd7fa5e388380f30b94efa43bf",
        "lastChainIndex": {
          "0": -1,
          "1": -1
        },
        "baseAddress": "0x10c208fa7afe710eb47272c0827f58d3d524932a",
        "feeAddress": "0xb0e3a0f647300a1656c1a46c21bbb9ed93bf19ab",
        "pendingChainInitialization": true,
        "creationFailure": []
      },
      "pendingApprovals": []
    }
  }
}

This API creates a new wallet for the user. The keys to use with the new wallet (passed in the ‘keys’ parameter) must be registered with BitGo prior to using this API.

BitGo currently only supports 2-of-3 (e.g. m=2 and n=3) wallets. The third key, and only the third key, must be a BitGo key. The first key is by convention the user key, with it’s encrypted xprv stored on BitGo.

HTTP Request

POST /api/v2/:coin/wallet

Body Parameters

Parameter Type Required Description
label String Yes Human-readable name for the wallet.
m Number Yes Number of signatures required for wallet (must be 2).
n Number Yes Number of total signers on wallet (must be 3).
keys Array Yes Array of keychain IDs previously created using Keychain API. There must be three IDs in the following order: user key, backup key, and BitGo key.
enterprise String No ID of the enterprise to associate this wallet with.
isCold Boolean No Whether the wallet is a cold wallet (BitGo only knows public portion of user key).
disableTransactionNotifications Boolean No Will prevent wallet transaction notifications if set to true.

Response

Field Description
id Id of the wallet (also the first receiving address)
label Human-readable name for the wallet.
coin The digital currency this wallet holds
users Array of users and their permissions on this wallet
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
balance The amount of satoshis you will have in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The amount of satoshis that is currently spendable. (May not be set for some coins.)
confirmedBalance The amount of satoshis you have within your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.

Get Wallet

let walletId = '585c51a5df8380e0e3082e46';
bitgo.coin('tbtc').wallets().get({ id: walletId })
.then(function(wallet) {
  // print the wallet
  console.dir(wallet._wallet);
});
WALLET="585c51a5df8380e0e3082e46"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET

The fetched wallet object has the following form:

{
  "id": "585c51a5df8380e0e3082e46",
  "users": [
    {
      "user": "55e8a1a5df8380e0e30e20c6",
      "permissions": [
        "admin",
        "view",
        "spend"
      ]
    }
  ],
  "coin": "tbtc",
  "label": "My first wallet",
  "m": 2,
  "n": 3,
  "keys": [
    "585951a5df8380e0e304a553",
    "585951a5df8380e0e30d645c",
    "585951a5df8380e0e30b6147"
  ],
  "tags": [
    "585951a5df8380e0e30a198a"
  ],
  "disableTransactionNotifications": false,
  "freeze": {},
  "deleted": false,
  "approvalsRequired": 1,
  "coinSpecific": {},
  "balance": 0,
  "confirmedBalance": 0,
  "spendableBalance": 0,
  "balanceString": 0,
  "confirmedBalanceString": 0,
  "spendableBalanceString": 0,
  "receiveAddress":{
    "address":"2MyzG53Z6nF7UdNt7otEMtGNiEAEe2t2eSY",
    "chain":0,
    "index":3,
    "coin":"tbtc",
    "wallet":"597a1eb8a4db5fb37729887e87d18ab5",
    "coinSpecific":{
      "redeemScript":"52210338ee0dce7dd0ce8bba6686c0d0ef6d55811b7369144367ae11f70a361a390d812103ebc32642cba79aefb993f7646a923a2163cbd0134a2b0cf5f71c55a80b067bef210348487f5f97bc53e0155516cbb41650686988ae87de105f6035bd444cd2de605f53ae"
    }
  },
  "admin":{
    "policy":{
      "id":"597a1eb8a4db5fb37729887f0c3c042b",
      "label":"default",
      "version":4,
      "date":"2017-05-12T17:57:21.800Z",
      "rules":[
        {
          "id":"pYUq7enNoX32VprHfWHuzFyCHS7",
          "coin":"tbtc",
          "type":"velocityLimit",
          "action":{
            "type":"getApproval"
          },
          "condition":{
            "amountString":"100000000",
            "timeWindow":0,
            "groupTags":[
              ":tag"
            ],
            "excludeTags":[

            ]
          }
        }
      ]
    }
  }
}

This API call retrieves wallet object information by the wallet ID.

This is useful to get the balance of the wallet, or identify the keys used to sign with the wallet using the Get Keychain API.

HTTP Request

GET /api/v2/:coin/wallet/:id

Query Parameters

Parameter Type Required Description
id String Yes Wallet ID.
allTokens Boolean No Gets details of all tokens associated with this wallet. Only valid for eth/teth

Response

Returns a wallet model object.

Field Description
id ID of the wallet (also the first receiving address)
label The wallet label, as shown in the UI
coin The digital currency this wallet holds
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
enterpise Enterprise ID if wallet belongs to an enterprise
users Array of users and their permissions on this wallet
approvalsRequired Number of approvers needed to confirm transactions or policy changes on the wallet
balance The amount of satoshis you will have in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The current amount of satoshi that is currently spendable. (May not be set for some coins.)
confirmedBalance The amount of satoshis you have within your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
admin An object containing the policies set on the wallet
pendingChainInitialization True if the wallet initialization transaction(s) is(are) still unconfirmed (see Ethereum)
isCold True if wallet is a cold wallet

You may have noticed that there are three 'balance’ key-value pairs. To illustrate an example, if you have 10 BTC in the form of 2 unspents that are both '5’ BTC, and you send Bob 1 BTC, your confirmed balance is 9 BTC, while your 'spendableBalance’ is 5 BTC and your balance is 9 BTC.

Errors

Response Description
400 Error Invalid wallet id.
400 Bad Request The request parameters were missing or incorrect.
404 Error Wallet not found.

Update Wallet

WALLETID='59d2d3a4f68130b507c437e485763ab2'
COIN=teth

curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{ "tokenFlushThresholds": { "terc": 100 } }' \
https://test.bitgo.com/api/v2/$COIN/wallet/$WALLETID

HTTP Request

PUT /api/v2/:coin/wallet/:id

Body Parameters

Parameter Type Required Description
label String No Change UI label
disableTransactionNotifications Boolean No Change transaction notification settings
approvalsRequired Number No Change number of required approvals
tokenFlushThresholds Object { [tokenName]: threshold } No Change threshold for erc20 forwarder (only coin teth)

Response

Updated wallet, same as in GET.

Errors

Response Description
400 Error Invalid wallet id.
400 Bad Request The request parameters were missing or incorrect.
404 Error Wallet not found.

Get Wallet By Address

let address = '2MyzG53Z6nF7UdNt7otEMtGNiEAEe2t2eSY';
bitgo.coin('tbtc').wallets().getWalletByAddress({ address: address })
.then(function(wallet) {
  // print the wallet
  console.dir(wallet._wallet);
});
ADDRESS="2MyzG53Z6nF7UdNt7otEMtGNiEAEe2t2eSY"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/address/$ADDRESS

The fetched wallet object has the following form:

{
  "id": "585951a5df8380e0e3063e9f",
  "users": [
    {
      "user": "55e8a1a5df8380e0e30e20c6",
      "permissions": [
        "admin",
        "view",
        "spend"
      ]
    }
  ],
  "coin": "tbtc",
  "label": "My first wallet",
  "m": 2,
  "n": 3,
  "keys": [
    "585951a5df8380e0e304a553",
    "585951a5df8380e0e30d645c",
    "585951a5df8380e0e30b6147"
  ],
  "tags": [
    "585951a5df8380e0e30a198a"
  ],
  "disableTransactionNotifications": false,
  "freeze": {},
  "deleted": false,
  "approvalsRequired": 1,
  "coinSpecific": {},
  "balance": 0,
  "confirmedBalance": 0,
  "spendableBalance": 0,
  "balanceString": 0,
  "confirmedBalanceString": 0,
  "spendableBalanceString": 0,
  "receiveAddress":{
    "address":"2MyzG53Z6nF7UdNt7otEMtGNiEAEe2t2eSY",
    "chain":0,
    "index":3,
    "coin":"tbtc",
    "wallet":"597a1eb8a4db5fb37729887e87d18ab5",
    "coinSpecific":{
      "redeemScript":"52210338ee0dce7dd0ce8bba6686c0d0ef6d55811b7369144367ae11f70a361a390d812103ebc32642cba79aefb993f7646a923a2163cbd0134a2b0cf5f71c55a80b067bef210348487f5f97bc53e0155516cbb41650686988ae87de105f6035bd444cd2de605f53ae"
    }
  },
  "admin":{
    "policy":{
      "id":"597a1eb8a4db5fb37729887f0c3c042b",
      "label":"default",
      "version":4,
      "date":"2017-05-12T17:57:21.800Z",
      "rules":[
        {
          "id":"pYUq7enNoX32VprHfWHuzFyCHS7",
          "coin":"tbtc",
          "type":"velocityLimit",
          "action":{
            "type":"getApproval"
          },
          "condition":{
            "amountString":"100000000",
            "timeWindow":0,
            "groupTags":[
              ":tag"
            ],
            "excludeTags":[

            ]
          }
        }
      ]
    }
  }
}

This API call retrieves wallet object information by an address belonging to the wallet.

This is useful to get the balance of the wallet, or identify the keys used to sign with the wallet using the Get Keychain API.

HTTP Request

GET /api/v2/:coin/wallet/address/:address

Query Parameters

Parameter Type Required Description
address String Yes The address

Response

Returns a wallet model object.

Field Description
id ID of the wallet
label The wallet label, as shown in the UI
coin The digital currency this wallet holds
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
users Array of users and their permissions on this wallet
approvalsRequired Number of approvers needed to confirm transactions or policy changes on the wallet
balance The amount of satoshis you will have in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The current amount of satoshi that is currently spendable. (May not be set for some coins.)
confirmedBalance The amount of satoshis you have within your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
admin An object containing the policies set on the wallet
pendingChainInitialization True if the wallet initialization transaction(s) is(are) still unconfirmed (see Ethereum)

Errors

Response Description
400 Bad Request Invalid wallet address
404 Not Found Unrecognized address or wallet not found

Wallet Operations

List Wallet Transfers

wallet.transfers()
.then(function(transfers) {
  // print transfers
  console.dir(transfers);
});
WALLET="585c51a5df8380e0e3082e46"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/transfer

Returns an object that looks like this:

{
  "coin": "tbtc",
  "transfers": [
    {
      "id": "591623989c043ab2079857ee53d812f0",
      "coin": "tbtc",
      "wallet": "59161139c86cffa0074b614d07dfc29b",
      "txid": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93",
      "height": 1122442,
      "date": "2017-05-12T21:05:28.130Z",
      "confirmations": 1,
      "value": 100000,
      "bitgoFee": 0,
      "usd": 1.79092,
      "usdRate": 1790.92,
      "state": "confirmed",
      "vSize": 224,
      "nSegwitInputs": 0,
      "tags": [
        "591623989c043ab2079857ee"
      ],
      "sequenceId": "",
      "history": [
        {
          "date": "2017-05-12T21:05:28.130Z",
          "action": "confirmed"
        },
        {
          "date": "2017-05-12T21:05:28.130Z",
          "action": "created"
        }
      ],
      "entries": [
        {
          "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
          "value": -369600
        },
        {
          "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
          "wallet": "59161139c86cffa0074b614d07dfc29b",
          "value": 100000
        },
        {
          "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
          "value": 259600
        }
      ],
      "outputs": [
        {
          "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:0",
          "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
          "value": 100000,
          "valueString": "100000",
          "wallet": "59161139c86cffa0074b614d07dfc29b",
          "chain": 0,
          "index": 0
        },
        {
          "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:1",
          "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
          "value": 259600,
          "valueString": "259600",
          "wallet": "59161139c86cffa0074b614d07dfc29b",
          "chain": 1,
          "index": 147
        }
      ],
      "inputs": [
        {
          "id": "778af3e4a2f0cfcebc28502ae5ee5d2edbec894eb07d967d6bb873720d33287a:1",
          "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
          "value": 369600,
          "valueString": "369600",
          "wallet": "59161139c86cffa0074b614d07dfc29b",
          "chain": 1,
          "index": 114
        }
      ],
      "confirmedTime": "2017-05-12T21:05:28.130Z",
      "createdTime": "2017-05-12T21:05:28.130Z"
    },
    
  ],
  "count": 5
}

Retrieves a list of transfers, which correspond to the deposits and withdrawals of digital currency on a wallet.

HTTP Request

GET /api/v2/:coin/wallet/:id/transfer

Query Parameters

Parameter Type Required Description
id String Yes ID of the wallet whose transfers to fetch.
prevId String No Continue iterating from this prevId (provided by nextBatchPrevId in the previous list)
allTokens Boolean No Gets transfers of all tokens associated with this wallet. Only valid for eth/teth.

Response

Array of transfers between wallets (see Get Wallet Transfer)

Field Description
coin The digital currency this wallet holds
transfers Array of transfers between wallets
nextBatchPrevId Can be used to iterate the next batch of results

Errors

Response Description
400 Bad Request Invalid wallet address

Get Wallet Transfer

let transferId = '591623989c043ab2079857ee53d812f0';
wallet.getTransfer({ id: transferId })
.then(function(transfer) {
  // print the transfer object
  console.dir(transfer);
});
WALLET="585c51a5df8380e0e3082e46"
TRANSFERID=591623989c043ab2079857ee53d812f0

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/transfer/$TRANSFERID

The JSON response will look similar to:

{
    "id": "591623989c043ab2079857ee53d812f0",
    "coin": "tbtc",
    "wallet": "59161139c86cffa0074b614d07dfc29b",
    "txid": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93",
    "height": 1122442,
    "date": "2017-05-12T21:05:28.130Z",
    "confirmations": 1,
    "value": 100000,
    "bitgoFee": 0,
    "usd": 1.79092,
    "usdRate": 1790.92,
    "state": "confirmed",
    "vSize": 224,
    "nSegwitInputs": 0,
    "tags": [
        "591623989c043ab2079857ee"
    ],
    "sequenceId": "",
    "history": [
        {
            "date": "2017-05-12T21:05:28.130Z",
            "action": "confirmed"
        },
        {
            "date": "2017-05-12T21:05:28.130Z",
            "action": "created"
        }
    ],
    "entries": [
        {
            "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
            "value": -369600
        },
        {
            "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
            "wallet": "59161139c86cffa0074b614d07dfc29b",
            "value": 100000
        },
        {
            "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
            "value": 259600
        }
    ],
    "outputs": [
      {
        "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:0",
        "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
        "value": 100000,
        "valueString": "100000",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 0,
        "index": 0
      },
      {
        "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:1",
        "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
        "value": 259600,
        "valueString": "259600",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 1,
        "index": 147
      }
    ],
    "inputs": [
      {
        "id": "778af3e4a2f0cfcebc28502ae5ee5d2edbec894eb07d967d6bb873720d33287a:1",
        "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
        "value": 369600,
        "valueString": "369600",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 1,
        "index": 114
      }
    ],
    "confirmedTime": "2017-05-12T21:05:28.130Z",
    "createdTime": "2017-05-12T21:05:28.130Z"
}

Wallet transfers represent digital currency sends and receives on your wallet.

This is the recommended method to track funding withdrawals and deposits.

HTTP Request

GET /api/v2/:coin/wallet/:walletId/transfer/:id

Query Parameters

Parameter Type Required Description
walletId String Yes ID of the wallet
id String Yes ID of the wallet transfer

Response

Returns a transfer object.

Field Description
id ID of the wallet transfer
coin Digital currency of the wallet
wallet Wallet ID of the wallet transfer
txid Transaction hash of the transfer
height Number of blocks mined before this transaction
date Date that this transaction occured
usd value of the total amount sent in USD
usdRate price of the cryptocurrency being sent in USD/base_unit
confirmations Number of block confirmations
state confirmed if corresponding transaction is in a block; otherwise, unconfirmed, pendingApproval, rejected or removed
vSize virtual size of the transaction (exists only if coin supports segwit)
nSegwitInputs number of inputs spending from segwit addresses (exists only if coin supports segwit)
entries Array of consolidated address to value objects
inputs Array of inputs used in the associated transaction (only returned from UTXO coins)
outputs Array of outputs used in the associated transaction (only returned from UTXO coins)
confirmedTime Time the transaction was confirmed
createdTime Time the transaction was created
history Object representing the history of state changes to the transfer
usd USD value of the transfer
value Digital currency value of the transfer
valueString Digital currency value of the transfer (string representation)

Get Wallet Transfer By Sequence ID

let sequenceId = 'hello123';
wallet.transferBySequenceId({ sequenceId: sequenceId })
.then(function(transfer) {
  // print the transfer object
  console.dir(transfer);
});
WALLET=59161139c86cffa0074b614d07dfc29b
SEQUENCEID=hello123

curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/transfer/sequenceId/$SEQUENCEID

Example response

{
    "id": "591623989c043ab2079857ee53d812f0",
    "coin": "tbtc",
    "wallet": "59161139c86cffa0074b614d07dfc29b",
    "txid": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93",
    "height": 1122442,
    "date": "2017-05-12T21:05:28.130Z",
    "confirmations": 1,
    "value": 100000,
    "bitgoFee": 0,
    "usd": 1.79092,
    "usdRate": 1790.92,
    "state": "confirmed",
    "tags": [
        "591623989c043ab2079857ee"
    ],
    "sequenceId": "hello123",
    "history": [
        {
            "date": "2017-05-12T21:05:28.130Z",
            "action": "confirmed"
        },
        {
            "date": "2017-05-12T21:05:28.130Z",
            "action": "created"
        }
    ],
    "entries": [
        {
            "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
            "value": -369600
        },
        {
            "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
            "wallet": "59161139c86cffa0074b614d07dfc29b",
            "value": 100000
        },
        {
            "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
            "value": 259600
        }
    ],
    "outputs": [
      {
        "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:0",
        "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
        "value": 100000,
        "valueString": "100000",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 0,
        "index": 0
      },
      {
        "id": "761774a49a1d9d820572f326dc4b99bfd26dcd6661574660995decc612718e0b:1",
        "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
        "value": 259600,
        "valueString": "259600",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 1,
        "index": 147
      }
    ],
    "inputs": [
      {
        "id": "778af3e4a2f0cfcebc28502ae5ee5d2edbec894eb07d967d6bb873720d33287a:1",
        "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
        "value": 369600,
        "valueString": "369600",
        "wallet": "59161139c86cffa0074b614d07dfc29b",
        "chain": 1,
        "index": 114
      }
    ],
    "confirmedTime": "2017-05-12T21:05:28.130Z",
    "createdTime": "2017-05-12T21:05:28.130Z"
}

Get the transaction on a wallet sequence ID that was passed in when sending a transaction (via Send Transaction or Send Transaction to Many). This is useful for tracking an unsigned/unconfirmed transaction via your own unique ID, as coin transaction IDs are not defined before co-signing.

A pending transaction that has not yet been co-signed by BitGo will still have a sequence id.

HTTP Request

GET /api/v2/:coin/wallet/:walletId/transfer/sequenceId/:sequenceId

URL Parameters

Parameter Type Required Description
walletId String Yes ID of the wallet
sequenceId String Yes The unique id previously sent with an outgoing transaction

Response

Returns a Transfer object.

Create Wallet Address

wallet.createAddress({ label: 'My address' })
.then(function(address) {
  // print new address
  console.dir(address);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/address

The new address response looks like this:

{
  "address": "2Mz7x1a5df8380e0e30yYc6e",
  "coin": "tbtc",
  "label": "My address",
  "wallet": "585c51a5df8380e0e3082e46",
  "coinSpecific": {
    "chain": 0,
    "index": 1,
    "redeemScript": "522101a5df8380e0e30453ae"
  }
}

This API call is used to create a new receive address for your wallet, which enhances your privacy. You may choose to call this API whenever a deposit is made. The BitGo API supports millions of addresses.

Please check the “Coin-Specific Implementation” with regards to fee address management for Ethereum.

HTTP Request

POST /api/v2/:coin/wallet/:id/address

Query Parameters

Parameter Type Required Description
id String Yes ID of the wallet to derive address for.

Body Parameters

Parameter Type Required Description
allowMigrated Boolean No Set to true to enable address creation for migrated BCH wallets.
chain Integer No Specifies the address format, defaults to 0, use 10 for SegWit (only on BTC and BTG)
gasPrice Integer No Custom gas price to be used for deployment of receive addresses (only for Ethereum)
lowPriority Boolean No Set to true to use low priority fee address (only for Ethereum). Use gasPrice parameter above to manually set fees. Note that low gasPrice transactions will take longer to get confirmed, but will be cheaper.
label String No Human-readable name for the address

Response

Newly created address object.

Field Description
address The wallet address (will not exist for Ethereum - see below)
coin The cryptocurrency of the wallet
chain The chain of the new address (see above)
coinSpecific currency-specific information about the new address
id the public ID of the address
index the index of the address (sequential for wallets)
label Human-readable name for the address
lastNonce the last used nonce for the address (only for Ethereum)

wallet | Wallet ID

Get Wallet Address

wallet.getAddress({address: '2NCzBK2Yf7PFAAfKsgc6cfTSG8FxtgMGG9C'})
.then(function(address) {
  // print address
  console.dir(address);
});
WALLET=5935dfef695bc5d30732ba88342405dd
ADDRESS=2NCzBK2Yf7PFAAfKsgc6cfTSG8FxtgMGG9C

curl -X GET \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/address/$ADDRESS

The address response looks like this:

{
  "address": "2NCzBK2Yf7PFAAfKsgc6cfTSG8FxtgMGG9C",
  "chain": 0,
  "index": 0,
  "coin": "tbtc",
  "label": "My address",
  "wallet": "5935dfef695bc5d30732ba88342405dd",
  "coinSpecific": {
    "redeemScript": "52210…953ae"
  }
}

This API call is used to get information about a single wallet address. The address object can be fetched by using either the id or the address itself.

HTTP Request

GET /api/v2/:coin/wallet/:walletId/address/:addressOrId

Query Parameters

Parameter Type Required Description
walletId String Yes ID of the wallet to which the address belongs.
addressOrId String Yes Valid address or address id of the wallet.

Response

Returns an address object.

Field Description
address The wallet address
chain The address chain
coin The cryptocurrency of the wallet
coinSpecific Data specific to the cryptocurrency of the wallet. See Coin-Specific Implementation.
index The address index
label Human-readable name for the address
lastNonce the last used nonce for the address (only for Ethereum)
wallet Wallet ID

Update Wallet Address

WALLET=5935dfef695bc5d30732ba88342405dd
ADDRESS=2NCzBK2Yf7PFAAfKsgc6cfTSG8FxtgMGG9C

curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\" }" \
https://test.bitgo.com/api/v2/tltc/wallet/$WALLET/address/$ADDRESS

The address response looks like this:

{
  "address": "2NCzBK2Yf7PFAAfKsgc6cfTSG8FxtgMGG9C",
  "chain": 0,
  "index": 0,
  "coin": "tbtc",
  "label": "My address",
  "wallet": "5935dfef695bc5d30732ba88342405dd",
  "coinSpecific": {
    "redeemScript": "52210…953ae"
  }
}

This API call is used to update fields on a wallet address.

HTTP Request

PUT /api/v2/:coin/wallet/:walletId/address/:addressOrId

Query Parameters

Parameter Type Required Description
walletId String Yes ID of the wallet to which the address belongs.
addressOrId String Yes Valid address or address id of the wallet.

Body Parameters

Parameter Type Required Description
label String No Human-readable name for the address

Response

Returns an address object.

Field Description
address The wallet address
chain The address chain
coin The cryptocurrency of the wallet
coinSpecific Data specific to the cryptocurrency of the wallet. See Coin-Specific Implementation.
index The address index
label Human-readable name for the address
lastNonce the last used nonce for the address (only for Ethereum)
wallet Wallet ID

Send Transaction

let params = {
  amount: 0.01 * 1e8,
  address: '2NFfxvXpAWjKng7enFougtvtxxCJ2hQEMo4',
  walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};
wallet.send(params)
.then(function(transaction) {
  // print transaction details
  console.dir(transaction);
});

WALLETID='59d2d3a4f68130b507c437e485763ab2'
DESTINATIONADDRESS='2N9JiEUYgRwKAw6FfnUca54VUeaSYSL9qqG'
COIN=tbtc
AMOUNT=1000000
WALLETPASSPHRASE='password'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"address\": \"$DESTINATIONADDRESS\", \"amount\": $AMOUNT, \"walletPassphrase\": \"$WALLETPASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/$COIN/wallet/$WALLETID/sendcoins

It returns an object that looks this:

{
  "txid": "a4b50c3f7fb5dd9273f5be69661b79eed61570421f76ec903ad914d39980549e",
  "status": "signed"
}

This API call allows you to create and send cryptocurrency to a destination address.

HTTP Request

POST /api/v2/:coin/wallet/:id/sendcoins

Body Parameters

Parameter Type Required Coins Description
address String Yes All Recipient address
amount Integer Yes All Amount to be sent to the recipient
walletPassphrase String Yes All The passphrase to be used to decrypt the user key on this wallet
prv String No All The private key in string form if the walletPassphrase is not available
numBlocks Integer No All UTXO-based Estimates the approximate fee per kilobyte necessary for a transaction confirmation within numBlocks blocks.
feeRate Integer No All UTXO-based Fee rate in satoshis/litoshis/atoms per kilobyte.
comment String No All Any additional comment to attach to the transaction
unspents Array No All UTXO-based The unspents to use in the transaction. Each unspent should be in the form prevTxId:nOutput.
minConfirms Integer No All UTXO-based Minimum number of confirmations unspents going into this transaction should have.
enforceMinConfirmsForChange Boolean No All UTXO-based Enforce minimum number of confirmations on change (internal) inputs.
targetWalletUnspents Integer No All UTXO-based The desired count of unspents in the wallet. If the wallet’s current unspent count is lower than the target, up to four additional change outputs will be added to the transaction. To reduce unspent count in your wallet see 'Consolidate Unspents’.
noSplitChange Boolean No All UTXO-based Set to true to disable automatic change splitting for purposes of unspent management.
minValue Integer No All UTXO-based Ignore unspents smaller than this amount of satoshis
maxValue Integer No All UTXO-based Ignore unspents larger than this amount of satoshis
gasPrice Integer No ETH Custom gas price to be used for sending the transaction
gasLimit Integer No ETH Custom gas limit for the transaction
sequenceId Integer No ETH The sequence ID of the transaction
segwit Boolean No BTC, LTC, BTG Allow SegWit unspents to be used, and create SegWit change.
lastLedgerSequence Integer No XRP Absolute max ledger the transaction should be accepted in, whereafter it will be rejected.
ledgerSequenceDelta String No XRP Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected.
changeAddress String No All UTXO-based Specifies the destination of the change output.

Response

Returns the newly created transaction description object.

Field Description
txid Blockchain transaction ID
status Status of transaction

Send Transaction to Many

let params = {
  recipients: [
    {
      amount: 0.01 * 1e8,
      address: '2NFfxvXpAWjKng7enFougtvtxxCJ2hQEMo4',
    }
  ],
  walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};
wallet.sendMany(params)
.then(function(transaction) {
  // print transaction details
  console.dir(transaction);
});
WALLETPASSPHRASE='watashinobitcoin'
COIN=tbtc
WALLETID='59d2d3a4f68130b507c437e485763ab2'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"recipients\": [{ \"address\": \"2N4Xz4itCdKKUREiySS7oBzoXUKnuxP4nRD\", \"amount\": 1500000}, /
{ \"address\": \"2NGJP7z9DZwyVjtY32YSoPqgU6cG2QXpjHu\", \"amount\": 2500000 }], /
\"walletPassphrase\": \"$WALLETPASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/$COIN/wallet/$WALLETID/sendmany

It returns an object that looks this:

{
  "txid": "a4b50c3f7fb5dd9273f5be69661b79eed61570421f76ec903ad914d39980549e",
  "status": "signed"
}

This API call allows you to create a transaction and send to multiple addresses. This may be useful if you schedule outgoing transactions in bulk, as you will be able to process multiple recipients and lower the aggregate amount of blockchain fees paid.

HTTP Request

POST /api/v2/:coin/wallet/:id/sendmany

Body Parameters

Parameter Type Required Coins Description
recipients Array Yes All Array of recipient objects and the amount to send to each e.g. [{address: ‘38BKDNZbPcLogvVbcx2ekJ9E6Vv94DqDqw’, amount: 1500}, …]
walletPassphrase String Yes All The passphrase to be used to decrypt the user key on this wallet
prv String No All The private key in string form if the walletPassphrase is not available
numBlocks Integer No All UTXO-based Estimates the approximate fee per kilobyte necessary for a transaction confirmation within numBlocks blocks.
feeRate Integer No All UTXO-based Fee rate in satoshis/litoshis/atoms per kilobyte.
comment String No All Any additional comment to attach to the transaction
unspents Array No All UTXO-based The unspents to use in the transaction. Each unspent should be in the form prevTxId:nOutput.
minConfirms Integer No All UTXO-based Minimum number of confirmations unspents going into this transaction should have.
enforceMinConfirmsForChange Boolean No All UTXO-based Enforce minimum number of confirmations on change (internal) inputs.
targetWalletUnspents Integer No All UTXO-based The desired count of unspents in the wallet. If the wallet’s current unspent count is lower than the target, up to four additional change outputs will be added to the transaction. To reduce unspent count in your wallet see 'Consolidate Unspents’.
noSplitChange Boolean No All UTXO-based Set to true to disable automatic change splitting for purposes of unspent management.
minValue Integer No All UTXO-based Ignore unspents smaller than this amount of satoshis
maxValue Integer No All UTXO-based Ignore unspents larger than this amount of satoshis
gasPrice Integer No ETH Custom gas price to be used for sending the transaction
gasLimit Integer No ETH Custom gas limit for the transaction
sequenceId Integer No ETH The sequence ID of the transaction
segwit Boolean No BTC, LTC, BTG Allow SegWit unspents to be used, and create SegWit change.
lastLedgerSequence Integer No XRP Absolute max ledger the transaction should be accepted in, whereafter it will be rejected.
ledgerSequenceDelta String No XRP Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected.
changeAddress String No All UTXO-based Specifies the destination of the change output.

Recipients

Each recipient object has the following key-value-pairs:

Key Type Value
address String Destination address
amount Integer Satoshis to send in transaction
String String representation of satoshis to send in transaction
gasPrice Integer No

Response

Returns the newly created transaction description object.

Field Description
txid Blockchain transaction ID
status Status of transaction

Wallet Operations — Advanced

List Wallet Addresses

wallet.addresses()
.then(function(addresses) {
  // print addresses
  console.dir(addresses);
});
WALLET=585c51a5df8380e0e3082e46

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/addresses

The response will look like this:

{
  "limit": 25,
  "coin": "tbtc",
  "addresses": [
    {
      "address": "2NFfxvXpAWjKng7enFougtvtxxCJ2hQEMo4",
      "coin": "tbtc",
      "label": "My address",
      "wallet": "585c71a5df8380e0e3001318",
      "coinSpecific": {
        "chain": 0,
        "index": 0,
        "redeemScript": "522101a5df8380e0e30c53ae"
      }
    },
    
  ],
  "count": 6,
  "pendingAddressCount": 0,
  "totalAddressCount": 6
}

This API call is used to retrieve a wallet’s addresses. This covers all receive addresses, including both external and change addresses.

HTTP Request

GET /api/v2/:coin/wallet/:id/addresses

Query Parameters

Parameter Type Required Description
id String Yes Wallet ID.
limit Number No The maximum number of addresses to be returned.
prevId String No Continue iterating (provided by nextBatchPrevId in the previous list)
sortOrder Number No Order the addresses by creation date. -1 is newest first, 1 is for oldest first.

Response

An array of address objects.

Field Description
limit How many addresses will be queried
coin The cryptocurrency of the wallet
addresses An array of addresses
count The number of addresses returned by this query
pendingAddressCount The total number of pending addresses for this wallet (useful only for Ethereum). This is only returned when prevId is not passed in.
totalAddressCount The total number of confirmed addresses for this wallet. This is only returned when prevId is not passed in.
nextBatchPrevId Can be used to iterate the next batch of results

List Wallet Transactions

wallet.transactions()
.then(function(transactions) {
  // print transactions
  console.dir(transactions);
});
WALLET="585c51a5df8380e0e3082e46"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/tx

The transaction list will look like this:

{
  "transactions": [
    {
      "id": "fe834f8484f36414cc83d01187a09e80cff670eb903332ef0540552cc7c1beef",
      "size": 405,
      "fee": 17418,
      "date": "2016-12-23T04:57:55.942Z",
      "hex": "010001a5df8380e0e3000000",
      "fromWallet": "585c71a5df8380e0e3001318",
      "blockHash": "00000000deb1fea813d2203258e8a0d78890c6ac0ca2df308775fc830ca7e835",
      "blockHeight": 1060644,
      "blockPosition": 9,
      "inputIds": [
        "7c95e04cf24cb2bc63ce27f9c6aad500ffcd9c4a1f76e015a2935e9074ae2e88:2"
      ],
      "comment": "test transaction",
      "inputs": [
        {
          "id": "7c95e04cf24cb2bc63ce27f9c6aad500ffcd9c4a1f76e015a2935e9074ae2e88:2",
          "address": "2NBEqoSXRJ2giw2bhu98UHn5ysM3tNUhPYT",
          "value": 45947744,
          "wallet": "585c71a5df8380e0e3001318",
          "fromWallet": "585c71a5df8380e0e3001318",
          "chain": 1,
          "index": 2
        },
        
      ],
      "outputs": [
        {
          "id": "fe834f8484f36414cc83d01187a09e80cff670eb903332ef0540552cc7c1beef:0",
          "address": "n2eMqTT929pb1RDNuqEnxdaLau1rxy3efi",
          "value": 1000000
        },
        
      ],
      "entries": [
        {
          "account": "2N6CYYGoBdpUiAXWeGJC11ypf9cKkBgoXZ7",
          "value": 1000000,
          "inputs": 0,
          "outputs": 1
        },
        
      ]
    },
    
  ],
  "coin": "tbtc"
}

This API call lists all blockchain transactions for a given wallet.

HTTP Request

GET /api/v2/:coin/wallet/:id/tx

Query Parameters

Parameter Type Required Description
id String Yes ID of the wallet whose transactions to fetch.
prevId String No Continue iterating (provided by nextBatchPrevId in the previous list result)
allTokens Boolean No Gets details of all token transactions associated with this wallet. Only valid for eth/teth.

Response

Returns an array of transaction objects (see get wallet transaction).

Field Description
transactions Array of transaction objects
nextBatchPrevId Can be used to iterate the next batch of results

Get Wallet Transaction

let txHash = "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93"
wallet.getTransaction({txHash: txHash})
.then(function(transaction){
//print the transaction
  console.dir(transaction);
});
WALLET="585c51a5df8380e0e3082e46"
TXID="fe834f8484f36414cc83d01187a09e80cff670eb903332ef0540552cc7c1beef"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/tx/$TXID

An Example JSON Response is below:

{
  "id": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93",
  "normalizedTxHash": "e0e4bada8332ed254c20c4c1d2c25e5f13386509e7ac21d005a169925d07889a",
  "date": "2017-09-06T23:48:50.928Z",
  "hex": "0100000001c94b453b9e997cd8538ecb99c20d981beb7c359c536c16d13865afe96bb77bef000000006b483045022100f7861a0b6ea18b3a368a97c8a85df49e798ec9926bbc912862663dd72b3e18bd022068305d68276ca567d635a53ea0ac6ff730def71316c91d952e4b4baed489c13d0121033905507e505d4777707bc8b70a38e3ff450ceed772932784b5ac719c62f3cd8bffffffff0210f60300000000001976a914bcca7743d9e6417e81c322177dfdaf756093bf1a88aca08601000000000017a9143a1001939de68218f4153f01c90d9818accc8d6a8700000000",
  "blockHash": "0000000000134c6c3840ad2fedb520081df15c5ac4efa43a8d42326500144399",
  "blockHeight": 1181203,
  "blockPosition": 2,
  "confirmations": 12431,
  "fee": 10000,
  "feeString": "10000",
  "size": 224,
  "inputIds": [
    "f09c34d3954e654e43edea3bff27051945e17efe7caa543674d16cd081b85704:1"
  ],
  "inputs": [
    {
      "id": "ef7bb76be9af6538d1166c539c357ceb1b980dc299cb8e53d87c999e3b454bc9:0",
      "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
      "value": 369600,
      "valueString": "369600"
    }
  ],
  "outputs": [
    {
      "id": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93:0",
      "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
      "value": 100000,
      "valueString": "100000",
      "wallet": "59161139c86cffa0074b614d07dfc29b",
      "chain": 0,
      "index": 36
    },
    {
      "id": "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93:1",
      "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
      "value": 259600,
      "valueString": "259600"
    }
  ],
  "entries": [
    {
      "address": "2MxYEMY8UKFPj8Ps5BXSHj3FLA2QfD9n7K1",
      "inputs": 0,
      "outputs": 1,
      "value": 100000,
      "valueString": "100000"
    },
    {
      "address": "mi4NNLqqPVwQZGc6ZX4S3FG1fL3AnVCaug",
      "inputs": 1,
      "outputs": 0,
      "value": -369600,
      "valueString": "-369600"
    },
    {
      "address": "mxjBshD14gvw1JkKmBLyEJbz5bigNE357y",
      "wallet": "59161139c86cffa0074b614d07dfc29b",
      "inputs": 0,
      "outputs": 1,
      "value": 259600,
      "valueString": "259600"
    }
  ]
}

This API call retrieves object information for a specific tranasaction hash by specifying the transaction ID.

HTTP Request

GET /api/v2/:coin/wallet/:id/tx/:txid

Query Parameters

Parameter Type Required Description
id String Yes ID of the wallet whose transactions to fetch.
txid String Yes Transaction hash to retrieve.

Response

Returns a transaction object

Field Description
id Transaction hash
normalizedTxHash Normalized transaction hash
date Date of the transaction
hex Transaction Hex
blockHash Block hash the transaction is apart of
blockHeight Height of the block
blockPosition Position of the block
confirmations Number of confirmations for this transaction
fee Transaction fee
feeString Transaction fee as a string
size Size of the transaction in bytes
inputIds Array of the input ids
inputs Array of source objects containing id, address, and value
outputs Array of destination objects containing address and value
entries Array of consolidated address to value objects
fromWallet id of the wallet that sent this transaction

List Wallet Unspents

wallet.unspents()
.then(function(unspents) {
  // print unspents
  console.dir(unspents);
});
WALLET=585c51a5df8380e0e3082e46

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/unspents

The response will look like this:

{
  "unspents": [
    {
      "id": "952ac7fd9c1a5df8380e0e305fac8b42db:0",
      "address": "2NEqutgZ741a5df8380e0e30gkrM9vAyn3",
      "value": 203125000,
      "blockHeight": 999999999,
      "date": "2017-02-23T06:59:21.538Z",
      "wallet": "58ae81a5df8380e0e307e876",
      "fromWallet": null,
      "chain": 0,
      "index": 0,
      "redeemScript": "522102f601b186b23d6c7b1fc3a3363a7e47b1a48e13e559601c9cf22c98b249c288bf210385dd4200926a87b1363667d50b8e46d17f811ee7bed3c5c29607545f231233d521036ed3744f71e371796b8dfea84dbeeb49a270339ec34eb9a92b87b6874674ecb357ae",
      "isSegwit": false
    }
  ],
  "coin": "tbtc"
}

This API call will retrieve the unspent transaction outputs (UTXOs) within a wallet.

This may be relevant if you are trying to do manual coin control when operating an unspent-based blockchain such as Bitcoin.

HTTP Request

GET /api/v2/:coin/wallet/:id/unspents

Query Parameters

Parameter Type Required Description
prevId String No Continue iterating wallets from this prevId as provided by nextBatchPrevId in the previous list
minValue Integer No Ignore unspents smaller than this amount of satoshis
maxValue Integer No Ignore unspents larger than this amount of satoshis
minHeight Integer No Ignore unspents confirmed at a lower block height than the given minHeight
minConfirms Integer No Ignores unspents that have fewer than the given confirmations

Response

An array of unspent objects.

Field Description
unspents Array of unspent objects
nextBatchPrevId Can be used to iterate the next batch of results
coin The digital currency of the unspents

Unspent Object

Field Description
id The outpoint of the unspent (txid:vout)
address The address that owns this unspent
value Value of the unspent in satoshis
blockHeight The height of the block that created this unspent
date The date the unspent was created
wallet The id of the wallet the unspent is in
fromWallet The id of the wallet the unspent came from (if it was sent from a BitGo wallet you’re a member on , null otherwise)
chain The address type and derivation path of the unspent (0 = normal unspent, 1 = change unspent, 10 = segwit unspent, 11 = segwit change unspent)
index The position of the address in this chain’s derivation path
redeemScript The script defining the criteria to be satisfied to spend this unspent
isSegwit A flag indicating whether this is a segwit unspent

Get Total Balances

bitgo.coin(coin).wallets().getTotalBalances()
.then(function (balances) {
  // print total balances across all wallets for this coin
  console.dir(balances);
});
curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
http://test.bitgo.com/api/v2/tbtc/wallet/balances

The response will look like this:

{
  "balance": 1234567890,
  "balanceString": "1234567890",
  "confirmedBalance": 1234567890,
  "confirmedBalanceString": "1234567890",
  "spendableBalance": 1234567890,
  "spendableBalanceString": "1234567890",
}

This API call will calculate the total balance across all wallets with the specified coin type.

The resulting total balance is broken down into three categories: balance, confirmed balance, and spendable balance. Each balance has a slightly different meaning, which is detailed in the Response table below.

HTTP Request

Get /api/v2/:coin/wallet/balances

Response

Field Description
balance The total sum of coins across all wallets containing the given coin type
balanceString A string representation of the balance
confirmedBalance The total sum of coins across all wallets containing the given coin type which have been confirmed by the network
confirmedBalanceString A string representation of the confirmed balance
spendableBalance The total sum of coins across all wallets containing the given coin which may be used as inputs for creating new transactions
spendableBalanceString A string representation of the spendable balance

Note: Total balances consider only wallets of a single coin type. It cannot be used to get the total balance of all coins in all wallets.

Get Maximum Spendable

wallet.maximumSpendable(params)
.then(function(amount) {
  // print maximum spendable amount
  console.dir(amount);
});
WALLET=585c51a5df8380e0e3082e46

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/maximumSpendable

The response will look like this:

{
  "maximumSpendable": 100000000,
  "coin": "tbtc"
}

This API call will retrieve the maximum amount that can be spent with a single transaction from the wallet.

The maximum spendable amount can differ from a wallet’s total balance. A transaction can only use up to 200 unspents. Wallets that have more than 200 unspents cannot spend the full balance in one transaction. Additionally, the value returned for the maximum spendable amount accounts for the current fee level by deducting the estimated fees. The amount will only be calculated based on the unspents that fit the parameters passed.

HTTP Request

GET /api/v2/:coin/wallet/:id/maximumSpendable

Query Parameters

Parameter Type Required Description
limit Integer No Max number of unspents to use (if less than 200)
minValue Integer No Ignore unspents smaller than this amount of satoshis
maxValue Integer No Ignore unspents larger than this amount of satoshis
minHeight Integer No Minimum block height of unspents to fetch
feeRate Integer No The desired fee rate for the transaction in satoshis/kB
minConfirms Integer No The required number of confirmations for each non-change unspent
enforceMinConfirmsForChange Boolean No Apply the required confirmations set in minConfirms for change outputs

Response

An object representing the coin and the maximum spendable amount.

Field Description
maximumSpendable The maximum amount that can be spent in a single transaction
coin The digital currency of the unspents

Consolidate Wallet Unspents

let params = {
    numUnspentsToMake: 2,
    minValue: 100000,
    maxValue: 47000000,
    minHeight: 1,
    minConfirms: 2,
    limit: 100,
    walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};
wallet.consolidateUnspents(params)
.then(function(transactionInfo) {
  // print transaction info
  console.dir(transactionInfo);
});
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"numUnspentsToMake\": 2, \"limit\": 100, \"minValue\": 100000, \"maxValue\": 47000000, \"minHeight\": 1, /
\"minConfirms\": 2, \"walletPassphrase\":  \"secretpassphrase1a5df8380e0e30\" }"
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/wallet/:id/consolidateunspents

The response will look like this:

{
  "txid": "5885a7e6c7802206f69655ed763d14f101cf46501aef38e275c67c72cfcedb75",
  "tx": "010000001945f506cad0d2b8be8e36ed5d4dbb7502cd3a2822d01f7afe411f9773c6fd381cad0 ...",
  "status": "signed"
}

This SDK call will consolidate the unspents that match the parameters, and consolidate them into the number specified by numUnspentsToMake.

HTTP Request

POST /api/v2/:coin/wallet/:id/consolidateunspents

Query Parameters

Parameter Type Required Description
id String Yes Wallet ID.

Body Parameters

Parameter Type Required Description
walletPassphrase String Yes Passphrase to decrypt the wallet’s private key.
numUnspentsToMake Integer No Number of outputs created by the consolidation transaction (Defaults to 1)
limit Integer No Number of unspents to select (Defaults to 25, Max is 200)
minValue Integer No Ignore unspents smaller than this amount of satoshis
maxValue Integer No Ignore unspents larger than this amount of satoshis
minHeight Integer No The minimum height of unspents on the block chain to use
feeRate Integer No The desired fee rate for the transaction in satoshis/kB
feeTxConfirmTarget Integer No Fee rate is automatically chosen by targeting a transaction confirmation in this number of blocks (Only available on BTC, feeRate takes precedence if also set)
maxFeePercentage Integer No Maximum percentage of an unspent’s value to be used for fees. Cannot be combined with minValue
minConfirms Integer No The required number of confirmations for each transaction input
enforceMinConfirmsForChange Boolean No Apply the required confirmations set in minConfirms for change outputs

Response

An object with the transaction info

Field Description
txid Id of the transaction
tx The serialized transaction
status If the transaction was signed

Fanout Wallet Unspents

let params = {
    maxNumInputsToUse: 20,
    numUnspentsToMake: 200,
    minValue: 100000,
    maxValue: 47000000,
    minHeight: 1,
    minConfirms: 2,
    walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};
wallet.fanoutUnspents(params)
.then(function(transactionInfo) {
  // print transaction info
  console.dir(transactionInfo);
});
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"maxNumInputsToUse\": 20, \"numUnspentsToMake\": 200, \"minValue\": 100000, \"maxValue\": 47000000, \"minHeight\": 1, /
\"minConfirms\": 2, \"walletPassphrase\":  \"secretpassphrase1a5df8380e0e30\" }"
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/wallet/:id/fanoutunspents

The response will look like this:

{
  "txid": "5885a7e6c7802206f69655ed763d14f101cf46501aef38e275c67c72cfcedb75",
  "tx": "010000001945f506cad0d2b8be8e36ed5d4dbb7502cd3a2822d01f7afe411f9773c6fd381cad0 ...",
  "status": "signed"
}

This SDK call will fanout the unspents currently in the wallet that match the parameters, and use them as inputs to create more unspents.

HTTP Request

POST /api/v2/:coin/wallet/:id/fanoutunspents

Query Parameters

Parameter Type Required Description
id String Yes Wallet ID.

Body Parameters

Parameter Type Required Description
walletPassphrase String Yes Passphrase to decrypt the wallet’s private key.
xprv String No The private key in string form if the walletPassphrase is not available
maxNumInputsToUse Integer No Number of unspents you want to use in the fanout transaction (Default 20, Max 80)
numUnspentsToMake Integer No Number of unspents you want to create in the transaction. They will all be almost the same size. (Default 200, Max 300)
minValue Integer No Ignore unspents smaller than this amount of satoshis
maxValue Integer No Ignore unspents larger than this amount of satoshis
minHeight Integer No The minimum height of unspents on the block chain to use
maxFeePercentage Integer No Maximum percentage of an unspent’s value to be used for fees. Cannot be combined with minValue
minConfirms Integer No The required number of confirmations for each transaction input
enforceMinConfirmsForChange Boolean No Apply the required confirmations set in minConfirms for change outputs
feeRate Integer No The desired fee rate for the transaction in satoshis/kB
feeTxConfirmTarget Integer No Fee rate is automatically chosen by targeting a transaction confirmation in this number of blocks (Only available on BTC, feeRate takes precedence if also set)

Response

An object with the transaction info

Field Description
txid Id of the transaction
tx The serialized transaction
status If the transaction was signed

Sweep

let params = {
    address: '2MwvR24yqym2CgHMp7zwvdeqBa4F8KTqunS',
    walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};
wallet.sweep(params)
.then(function(transactionInfo) {
  // print transaction info
  console.dir(transactionInfo);
});
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"address\":  \"2MwvR24yqym2CgHMp7zwvdeqBa4F8KTqunS\", \"walletPassphrase\":  \"secretpassphrase1a5df8380e0e30\" }"
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/wallet/:id/sweep

The response will look like this:

{
  "txid": "5885a7e6c7802206f69655ed763d14f101cf46501aef38e275c67c72cfcedb75",
  "tx": "010000001945f506cad0d2b8be8e36ed5d4dbb7502cd3a2822d01f7afe411f9773c6fd381cad0 ...",
  "status": "signed"
}

This SDK call attempts to move all of the funds of the wallet into the address provided.

HTTP Request

POST /api/v2/:coin/wallet/:id/sweep

Body Parameters

Parameter Type Required Coins Description
address String Yes All The address to send all the funds in the wallet to.
walletPassphrase String Yes All Passphrase to decrypt the wallet’s private key.
xprv String No All The private key in string form if the walletPassphrase is not available
otp String No All The current 2FA code
feeRate Integer No All UTXO-based Fee rate in satoshis/litoshis/atoms per kilobyte.
feeTxConfirmTarget Integer No All UTXO-based Estimates the approximate fee per kilobyte necessary for a transaction confirmation within numBlocks blocks.
gasPrice Integer No ETH Custom gas price to be used for sending the transaction
sequenceId Integer No All The sequence ID of the transaction
lastLedgerSequence Integer No XRP Absolute max ledger the transaction should be accepted in, whereafter it will be rejected.
ledgerSequenceDelta String No XRP Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected.

Response

An object with the transaction info

Field Description
txid Id of the transaction
tx The serialized transaction
status If the transaction was signed

Build Transaction

let params = {
  recipients: [
    {
      amount: 0.01 * 1e8,
      address: '2NFfxvXpAWjKng7enFougtvtxxCJ2hQEMo4',
    }
  ]
};
wallet.prebuildTransaction(params)
.then(function(transaction) {
  // print transaction details
  console.dir(transaction);
});

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"recipients\": [{ \"address\": \"2N4Xz4itCdKKUREiySS7oBzoXUKnuxP4nRD\", \"amount\": 1500000}, /
{ \"address\": \"2NGJP7z9DZwyVjtY32YSoPqgU6cG2QXpjHu\", \"amount\": 2500000 }] }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/wallet/:id/tx/build

It returns an object that looks this:

{
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000",
    "txInfo": {
        "nP2SHInputs": 1,
        "nSegwitInputs": 0,
        "nOutputs": 2,
        "unspents": [
            {
                "chain": 1,
                "index": 10,
                "redeemScript": "52210208906f13de98b88bc9f83886c39a1555ada816b12de6f029626af2ef9413708b2102bca01320026604530fc47068ce015b39b91bd72d8964b0c5023697645b1441ab210336d8e968990c8a5b2bad83a237c37957ce70586ed507b155941ea28ec953860153ae",
                "id": "7df5bb3c8ce6daa9e3bed51d2d926c231525e595032713ed8fde4166adb5b079:1",
                "address": "2MvevrYxML8NkRng4avXz7oMCgs5qxR7Mef",
                "value": 4508000
            }
        ],
        "changeAddresses": [
            "2MtLtTSsC98dF4zriFGvCfmce3A17Zz1McK"
        ]
    },
    "feeInfo": {
        "size": 373,
        "fee": 3730,
        "feeRate": 10000,
        "payGoFee": 0,
        "payGoFeeString": "0"
    }
}

Create a transaction with the specified parameters. This builds a transaction object, but does not sign or send it.

HTTP Request

POST /api/v2/:coin/wallet/:id/tx/build

Body Parameters

Parameter Type Required Coins Description
recipients Array Yes Objects describing the receive address and amount.
numBlocks Integer No All UTXO-based Estimates the approximate fee per kilobyte necessary for a transaction confirmation within numBlocks blocks.
feeRate Integer No All UTXO-based Fee rate in satoshis/litoshis/atoms per kilobyte.
minConfirms Integer No All UTXO-based Minimum number of confirmations unspents going into this transaction should have.
enforceMinConfirmsForChange Boolean No All UTXO-based Enforce minimum number of confirmations on change (internal) inputs.
unspents Array No All UTXO-based The unspents to use in the transaction. Each unspent should be in the form prevTxId:nOutput.
targetWalletUnspents Integer No All UTXO-based The desired count of unspents in the wallet. If the wallet’s current unspent count is lower than the target, up to four additional change outputs will be added to the transaction. To reduce unspent count in your wallet see 'Consolidate Unspents’.
noSplitChange Boolean No All UTXO-based Set to true to disable automatic change splitting for purposes of unspent management.
minValue Integer No All UTXO-based Ignore unspents smaller than this amount of satoshis
maxValue Integer No All UTXO-based Ignore unspents larger than this amount of satoshis
gasPrice Integer No ETH Custom gas price to be used for sending the transaction
lastLedgerSequence Integer No XRP Absolute max ledger the transaction should be accepted in, whereafter it will be rejected.
ledgerSequenceDelta String No XRP Relative ledger height (in relation to the current ledger) that the transaction should be accepted in, whereafter it will be rejected.
changeAddress String No All UTXO-based Specifies the destination of the change output.

Recipients

Each recipient object has the following key-value-pairs:

Key Type Required Value
address String Yes Destination address
amount Integer Yes Amount to send to recipient in base units (satoshis, drops, etc.)

Response

Returns the newly created transaction description object.

Field Description
txHex the unsigned, serialized transaction hex
txInfo metadata about the transaction and unspents used
feeInfo metadata about the fees the transaction will pay
sequenceId The sequence ID of the transaction (only for Ethereum)

Errors

Status Message Coins Resolution
400 insufficient funds All The transaction’s cost exceeds the spendable balance. Please make sure that the send amount leaves sufficient balance for the fee.
400 invalid address All One of the recipient addresses is not valid. Please check that the addresses have been entered correctly and adhere to a supported format.
400 every recipient must have an address All Check the format of the recipients in your request. Each recipient must be specified with a destination address to which the amount is sent.
400 sub-dust-threshold amount for
UTXO One of the recipient amounts is too small. Please pick amounts that are greater than the dust threshold.
400 invalid amount for:
- should be a numerical string
Account Send a string instead of a plain number for the amount.
400 cannot send less than base reserve (20000000 drops) to non-existent address XRP Send more XRP or send to a prefunded address.
400 must provide a destination tag to send to
XRP The address you are sending to requires a destination tag. This is a setting configured by the recipient for each address.
400 internal transactions are not supported in Ripple XRP You cannot send money from an account to the same account.
400 please provide a positive numerical fee rate in satoshis/kb UTXO If a fee rate is specified, it should be a positive number.

Sign Transaction

let params = {
  "txPrebuild": {
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000",
    "txInfo": {
      "nP2SHInputs": 1,
      "nSegwitInputs": 0,
      "nOutputs": 2,
      "unspents": [
        {
          "chain": 1,
          "index": 10,
          "redeemScript": "52210208906f13de98b88bc9f83886c39a1555ada816b12de6f029626af2ef9413708b2102bca01320026604530fc47068ce015b39b91bd72d8964b0c5023697645b1441ab210336d8e968990c8a5b2bad83a237c37957ce70586ed507b155941ea28ec953860153ae",
          "id": "7df5bb3c8ce6daa9e3bed51d2d926c231525e595032713ed8fde4166adb5b079:1",
          "address": "2MvevrYxML8NkRng4avXz7oMCgs5qxR7Mef",
          "value": 4508000
        }
      ],
      "changeAddresses": [
        "2MtLtTSsC98dF4zriFGvCfmce3A17Zz1McK"
      ]
    },
    "feeInfo": {
      "size": 373,
      "fee": 3730,
      "feeRate": 10000,
      "payGoFee": 0,
      "payGoFeeString": "0"
    }
  },
  "prv": "xprvmysecretprivatekey"
};
wallet.signTransaction(params)
.then(function(transaction) {
  // print half-signed transaction hex
  console.dir(transaction);
});

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{\"txPrebuild\":{\"txHex\":\"010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000\" \
 ,\"txInfo\":{\"nP2SHInputs\":1,\"nSegwitInputs\":0,\"nOutputs\":2,\"unspents\":[{\"chain\":1,\"index\":10,\"redeemScript\":\"52210208906f13de98b88bc9f83886c39a1555ada816b12de6f029626af2ef9413708b2102bca01320026604530fc47068ce015b39b91bd72d8964b0c5023697645b1441ab21 \
 0336d8e968990c8a5b2bad83a237c37957ce70586ed507b155941ea28ec953860153ae\",\"id\":\"7df5bb3c8ce6daa9e3bed51d2d926c231525e595032713ed8fde4166adb5b079:1\", \
 \"address\":\"2MvevrYxML8NkRng4avXz7oMCgs5qxR7Mef\",\"value\":4508000}],\"changeAddresses\":[\"2MtLtTSsC98dF4zriFGvCfmce3A17Zz1McK\"]}, \
 \"feeInfo\":{\"size\":373,\"fee\":3730,\"feeRate\":10000,\"payGoFee\":0,\"payGoFeeString\":\"0\"}},\"prv\":\"xprvmysecretprivatekey\"}"
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/wallet/:id/signtx

It returns an object that looks this:

{
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000"
}

Sign the given transaction with the specified keychain. All signing is done locally and can be performed offline. Signing can happen two ways: with a prv argument representing the private key, or with keychain and walletPassphrase arguments (for signing with an encrypted private key).

HTTP Request

POST /api/v2/:coin/wallet/:id/signtx

Body Parameters

Parameter Type Required Description
txPrebuild Object Yes The transaction description object, output from 'Build Transaction’
prv String No The user private key
coldDerivationSeed String No The seed used to derive the signing key
keychain Object No The user keychain with an encryptedPrv property
walletPassphrase Passphrase to decrypt the user keychain
key Object No alias for 'keychain’

Response

Field Description
txHex The half-signed, serialized transaction hex

Send Transaction

let params = {
  txHex: "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000",
  otp: '0000000'
};
wallet.submitTransaction(params)
.then(function(transaction) {
  // print transaction status
  console.dir(transaction);
});

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"txHex\": \"010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000\", \
\"otp\": \"0000000\" }"
http://$BITGO_EXPRESS_HOST:3080/api/v2/wallet/:id/tx/send

It returns an object that looks this:

{
    "txid": "415993bf16c856feb92ab15245a7d6b18757a276c2ac8f58fdbf6fad926857d6",
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000",
    "status": "signed"
}

Submit a half-signed transaction. The server will do one of the following:

HTTP Request

POST /api/v2/:coin/wallet/:id/tx/send

Body Parameters

Parameter Type Required Description
halfSigned Object Yes The half-signed info returned from 'Sign Transaction’
txHex String No The half-signed, serialized transaction hex (alternative to halfSigned)
otp String Yes The current 2FA code
comment String No Any additional comment to attach to the transaaction

Response

Field Description
txid The transaction’s unique identifier
txHex The serialized representation of the fully-signed transaction in hexadecimal
status The result of the send request

Freeze Wallet

WALLETID='585c51a5df8380e0e3082e46'
DURATION='4000'
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"duration\": \"$DURATION\" }" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/freeze
wallet.freeze({ otp: '0000000' })
.then(function(freeze) {
  console.dir(freeze);
});

Example Response

{
  "time" : "2016-04-01T03:51:39.779Z",
  "expires" : "2016-04-01T04:58:19.779Z"
}

Prevent all spend activity on a wallet. This call is designed to be used in cases of emergency, and prevent spends for a default of 1 hour. An unlock is required to freeze a wallet.

Once frozen, a wallet cannot be unfrozen except by contacting BitGo manually.

Parameters

Parameter Type Required Description
duration number No length of time in seconds to freeze spend activity. Defaults to 1 hour.
otp String Yes An OTP code for the account obtained using the second factor authentication device

Response

Field Description
time The date the freeze command was called
expires The date after which spend activity will be allowed

Errors

Response Description
400 Bad Request The request parameters were missing or incorrect.
401 Unauthorized The authentication parameters did not match, or unlock is required.

Keychains

All BitGo wallets are created using keychains. A keychain is a standard BIP32 extended HD key. Unlike traditional bitcoin keys, which represent a single ECDSA key pair, a keychain can represent many key pairs, all derived from a common private key. This allows the user to retain a single private key, but generate an infinite number of public keys. BitGo uses these extended keys to keep your bitcoin more private and secure.

To make wallet creation simple, BitGo maintains a list of Keychains for each user. Each keychain may be used in any number of BitGo Wallets.

There are two types of keychains:

All keychains are identified by their key id.

List Keychains

bitgo.coin('tbtc').keychains().list()
.then(function(keychain) {
  // print the keychains
  console.dir(keychains);
});
curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/key

The list is returned in the following format:

{
  "keys": [
    {
      "encryptedPrv": "{\"iv\":\"PXgD5cs61Ykr3a5jUpuwbQ==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"yETwNmH5ZnM=\",\"ct\":\"k4fgKz3Vsizc/wvaJZLGbFQUDfN7K7/Q/l1o/+ocrKL2FYMWXesleUedxiSe3i/JZHJzdJ0owrdinlsy1swPKrzwJEtkNaUDfBTpJDIDlFlxqH6RqMCeeR0x4rctShm5FMORvvXcn0dlfawbgVjriRwgaK0jjQY=\"}",
      "id": "585cc59eb2c04b960646d1bef7e59816",
      "pub": "xpub661MyMwAqRbcFukQiqR83Hgbhvgznic7U1L67FZZUpu5KgkAWr4xHsjE9mzud3PMUKJdhzD16XHgwjDZo5dbzbaQsVFLQWcNdRrWuYigKyB",
      "users": [
        "543c11ed356d00cb7600000b98794503"
      ]
    },
    
  ],
  "limit": 100,
  "nextBatchPrevId": "585cc59eb2c04b960646d1bef7e59816"
}

Retrieve a keychain based on its key id. To find out the key ids, use the List Keys API or the Get Wallet API.

HTTP Request

GET /api/v2/:coin/key

Query Parameters

Parameter Type Required Description
limit Integer No Max number of results in a single call. Defaults to 25.
prevId String No Continue iterating (provided by nextBatchPrevId in the previous list)

Response

An array of address objects.

Field Description
keys Array of Key Objects (see Get Keychain)
nextBatchPrevId Can be used to iterate the next batch of results

Errors

Response Description
400 Bad Request The request parameters were missing or incorrect.
401 Unauthorized The authentication parameters did not match.

Get Keychain

let keyId = '58c1f8a0781a5df8380e0e304b228c68';

bitgo.coin('tbtc').keychains().get({ id: keyId })
.then(function(keychain) {
  // print the keychain
  console.dir(keychain);
});
KEY="58c1f8a0781a5df8380e0e304b228c68"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/key/$KEY

The keychain is structured as follows:

{
  "id": "58c1f8a0781a5df8380e0e304b228c68",
  "pub": "xpub661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe",
  "users": [
    {
      "user": "58c1f8a0781a5df8380e0e304b228c63",
      "encryptedPrv": "{\"iv\":\"cRyAe…Udg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"gVo2ia/7sd4=\",\"ct\":\"FCkKz…TRNA=\"}"
    }
  ]
}

Retrieve a keychain based on its key id. To find key ids, use the List Keys API or the Get Wallet API.

HTTP Request

GET /api/v2/:coin/key/:id

Query Parameters

Parameter Type Required Description
id String Yes The keychain’s key id.

Response

Returns a keychain object.

Field Description
id Public key id
pub Public key
users Array of { users, encryptedPrv }; if you sent an encryptedPrv with the key, it will appear in the object

Errors

Response Description
400 Bad Request The request parameters were missing or incorrect.
401 Unauthorized The authentication parameters did not match.

Create Keychain

let key = bitgo.coin('tbtc').keychains().create();
curl -X POST http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/keychain/local

The key object is structured like this:

{
  "pub": "xpub661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe",
  "prv": "xprv9s21ZrQH143K3coRpaibgNhuXr1T8TbE1mMBxG2HLnmvbrGB3rtfHKgNxfuwmK5tA647C7DFSrS67xmERNg9L9RzcvJBJ6No1ipGnNmTkdu"
}

Local client-side function to create a new keychain.

Optionally, a single parameter, seed, may be provided which uses a deterministic seed to create your keychain. The seed should be an array of numbers at least 32 elements long. Calling this function with the same seed will generate the same BIP32 keychain.

Returns an object containing the xprv and xpub for the new chain. The created keychain is not known to the BitGo service. To use it with the BitGo service, use the ‘Store Keychain’ API call.

For security reasons, it is highly recommended that you encrypt and destroy the original xprv immediately to prevent theft.

Response

Returns a local keychain object.

Field Description
pub Public key
prv Private key

Create BitGo Keychain

bitgo.coin('tbtc').keychains().createBitGo()
.then(function(keychain) {
  // print the keychain
  console.dir(keychain);
});
curl -X POST \
-d "{ \"source\": \"bitgo\" }" \
https://test.bitgo.com/api/v2/:coin/key

Returns a special keychain object:

{
  "id": "58c1f8a0781a5df8380e0e304b228c11",
  "users": [],
  "pub": "661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe",
  "isBitGo": true
}

Creates a new keychain on BitGo’s servers and returns the public keychain to the caller.

HTTP Request

POST /api/v2/:coin/key

Argument Parameters

Parameter Type Required Description
source String Yes The origin of the keychain. Must be bitgo for a BitGo key.
enterprise String Yes (only for Eth) The enterprise id of the BitGo key
newFeeAddress Boolean No Create a new keychain instead of fetching enterprise key (only for Ethereum)

Response

A BitGo keychain object.

Field Description
id Keychain id
pub Public key
isBitGo Verifies if keychain is a BitGo keychain

Create Backup Keychain

bitgo.coin('tbtc').keychains().createBackup({ provider: 'cme' })
.then(function(keychain) {
  // print the keychain
  console.dir(keychain);
});
curl -X POST \
-d "{ \"source\": \"backup\", \"provider\": \"cme\" }" \
https://test.bitgo.com/api/v2/:coin/key

Returns a special keychain object:

{
  "id": "58c1f8a0781a5df8380e0e304b228c11",
  "users": [],
  "pub": "661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe"
}

Creates a new backup keychain on a third party specializing in key recovery services. This keychain will be stored on the third party service and usable for recovery purposes only.

HTTP Request

POST /api/v2/:coin/key

Argument Parameters

Parameter Type Required Description
source String Yes The origin of the keychain. Must be backup for a backup key.
provider String Yes The backup provider for the keychain, e. g. cme.

Response

A BitGo keychain object.

Field Description
id Keychain id
pub Public key

Add Keychain

let key = bitgo.coin('tbtc').keychains().create();
bitgo.coin('tbtc').keychains().add(key)
.then(function(keychain) {
  // print the keychain
  console.dir(keychain);
});
XPUB="xpub661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"pub\": \"$XPUB\" }" \
https://test.bitgo.com/api/v2/tbtc/key

Returns a keychain object

{
  "id": "58c1f8a0781a5df8380e0e304b228c11",
  "users": [
    "58c1f8a0781a5df8380e0e304b228c68"
  ],
  "pub": "xpub661MyMwAqRbcG6stvcFc3Wee5sqwXvK5NzGnkeRtu8JuUebKbQCuq7zroyJ4TSWd9VuenwwirViTwtrtdHRn9B7HeeBzqVdnrWRCerJhTRe"
}

This API call allows you to add a public keychain on BitGo’s server. Only the public key parameter is required. If using the 'Create Keychain’ API call, you do not need to include the source parameter. You must add a keychain to BitGo before a wallet can be created with a keychain.

HTTP Request

POST /api/v2/:coin/key

Body Parameters

Parameter Type Required Description
pub String Yes The keychain’s public key.
encryptedPrv String No The keychain’s encrypted private key.
source String No The origin of the keychain, e. g. bitgo or backup

Response

Returns a server-stored keychain object with an id.

Field Description
id Keychain id
user Array of users with access to the keychain
pub Public key

Wallet Policy

BitGo wallets feature advanced security features such as multi-user or approval of transactions and spending limits. To take advantage of this, a user/developer may add and modify policy rules on a wallet. Rules will trigger an associated action (set by the user). The policy engine will collect all triggered rule results, and perform any triggered actions in the order of deny or getApproval (from another user).

If a wallet carries a balance and there are more than two “admin” users associated with a Wallet, any policy change will require approval by another administrator before it will take effect (if there are no additional “admin” users, this will not be necessary). It is thus highly recommended to create wallets with at least 2 administrators by performing a wallet share. This way, policy can be effective even if a single user is compromised.

Additionally, to prevent working around policies by policy changes, policies are immutable starting 48 hours after their creation. In order to unlock a policy, you will need to contact support and verify your identity.

This documentation provides API coverage of basic BitGo policy involving a single wallet.

Further custom policy may be implemented using the webhook policy type, which causes BitGo to call out to a URL endpoint capable of evaluating any custom policy behavior involving external state.

Advanced policy involving multiple wallets may be implemented by contacting BitGo directly.

Get Wallet Policies

The list of policies in operation on a wallet is included when the wallet is fetched. See Get Wallet for further details.

Set Velocity Policy Rule

WALLETID='585a0860c5a04c696edd2c331ce2f346'

curl -X POST https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/policy/rule\
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
      "id": "my velocity limit",
      "type": "velocityLimit",
      "action": {
        "type": "getApproval"
      },
      "condition": {
        "amountString": "1e8",
        "timeWindow": 86400,
        "groupTags": [":tag"],
        "excludeTags": []
      }
    }' \

Example response

{
   "id":"585a0860c5a04c696edd2c331ce2f346",
   "users":[
      {
         "user":"56b0ed00f68ef6343608159bd861f6bf",
         "permissions":[
            "admin",
            "view",
            "spend"
         ]
      }
   ],
   "coin":"tbtc",
   "label":"My TBTC Wallet",
   
   "admin":{
      "policy":{
         "id":"597a1eb8a4db5fb37729887f0c3c042b",
         "label":"default",
         "version":1,
         "date":"2017-07-27T19:04:59.628Z",
         "rules":[
            {
               "id":"my velocity limit",
               "coin":"tbtc",
               "type":"velocityLimit",
               "action":{
                  "type":"getApproval"
               },
               "condition":{
                  "amountString":"1e8",
                  "timeWindow":86400,
                  "groupTags":[
                     ":tag"
                  ],
                  "excludeTags":[

                  ]
               }
            }
         ]
      }
   },
   
}

Add a rule to a wallet’s policy. A wallet policy’s rules control the conditions under which BitGo will use its single key to sign a transaction. An email notification will be sent to all wallet users when a policy is updated. This email is NOT sent for the first time policy is added.

HTTP Request

POST /api/v2/:coin/wallet/:id/policy/rule

Query Parameters

Parameter Type Required Description
id String Yes The id of the policy rule
type String Yes The type of the policy. See Policy types
condition String Yes The condition that triggers the policy. See Policy types
action String Yes The action to take when the policy is triggered. Should be either deny or getapproval

Response

Returns a wallet model object containing the new policy rule.

Field Description
id ID of the wallet (also the first receiving address)
label The wallet label, as shown in the UI.
coin The digital currency this wallet holds.
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
users Array of users and their permissions on this wallet.
approvalsRequired Number of approvers needed to confirm transactions or policy changes on the wallet.
balance The balance in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The balance that is currently spendable. (May not be set for some coins.)
confirmedBalance The balance in your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
admin An object containing the policies set on the wallet.

Update Velocity Policy Rule

WALLETID='585a0860c5a04c696edd2c331ce2f346'

curl -X PUT https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/policy/rule\
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
      "id": "my velocity limit",
      "type": "velocityLimit",
      "action": {
        "type": "getApproval"
      },
      "condition": {
        "amountString": "10e8",
        "timeWindow": 43200,
        "groupTags": [],
        "excludeTags": ["2NFj9CHyY8cLKH4UXsivpRa5xkdvAXqqai9"]
      }
    }' \

Example response

{
  "id":"585a0860c5a04c696edd2c331ce2f346",
  "users":[
    {
      "user":"56b0ed00f68ef6343608159bd861f6bf",
      "permissions":[
        "admin",
        "view",
        "spend"
      ]
    }
  ],
  "coin":"tbtc",
  "label":"My TBTC Wallet",
  
  "admin":{
    "policy":{
      "id":"597a1eb8a4db5fb37729887f0c3c042b",
      "version":2,
      "date":"2017-07-27T19:43:25.438Z",
      "rules":[
        {
          "id":"my velocity limit",
          "coin":"tbtc",
          "type":"velocityLimit",
          "action":{
            "type":"getApproval"
          },
          "condition":{
            "amountString":"10e8",
            "timeWindow":43200,
            "groupTags":[

            ],
            "excludeTags":[
              "2NFj9CHyY8cLKH4UXsivpRa5xkdvAXqqai9"
            ]
          }
        }
      ]
    }
  },
  
}

Update a rule on a wallet’s policy.

HTTP Request

PUT /api/v2/:coin/wallet/:id/policy/rule

Query Parameters

Parameter Type Required Description
id String Yes The id of the policy rule to be updated. (This value can’t be changed)
type String Yes The type of the policy. (This value can’t be changed)
condition String Yes The new condition that triggers the policy. See Policy types
action String Yes The new action to take when the policy is triggered. Should be either deny or getapproval

Response

Returns a wallet model object containing the updated policy.

Field Description
id ID of the wallet (also the first receiving address)
label The wallet label, as shown in the UI.
coin The digital currency this wallet holds.
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
users Array of users and their permissions on this wallet.
approvalsRequired Number of approvers needed to confirm transactions or policy changes on the wallet.
balance The balance in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The balance that is currently spendable. (May not be set for some coins.)
confirmedBalance The balance in your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
admin An object containing the policies set on the wallet.

Remove a Policy Rule

WALLETID='585a0860c5a04c696edd2c331ce2f346'

curl -X DELETE https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/policy/rule\
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{
      "id": "my velocity limit",
      "type": "velocityLimit",
      "action": {
        "type": "getApproval"
      },
      "condition": {
        "amountString": "10e8",
        "timeWindow": 43200,
        "groupTags": [],
        "excludeTags": ["2NFj9CHyY8cLKH4UXsivpRa5xkdvAXqqai9"]
      }
    }' \

Example response

{
  "id":"585a0860c5a04c696edd2c331ce2f346",
  "users":[
    {
      "user":"56b0ed00f68ef6343608159bd861f6bf",
      "permissions":[
        "admin",
        "view",
        "spend"
      ]
    }
  ],
  "coin":"tbtc",
  "label":"My TBTC Wallet",
  
  "admin":{
    "policy":{
      "id":"597a1eb8a4db5fb37729887f0c3c042b",
      "version":3,
      "date":"2017-07-27T20:03:29.694Z",
      "rules":[

      ]
    }
  },
  
}

Remove a policy rule with the specified id. This may require a secondary approval if there is more than 1 “admin” user on the wallet.

HTTP Request

DELETE /api/v2/:coin/wallet/:id/policy/rule

Query Parameters

Parameter Type Required Description
id String Yes The id of the policy rule to be removed.
type String Yes The type of the policy.
condition String Yes The condition that triggers the policy.
action String Yes The action to take when the policy is triggered.

Response

Returns a wallet model object containing the updated policy.

Field Description
id ID of the wallet (also the first receiving address)
label The wallet label, as shown in the UI.
coin The digital currency this wallet holds.
keys Array of key ids on the wallet, in the order of User, Backup and BitGo.
users Array of users and their permissions on this wallet.
approvalsRequired Number of approvers needed to confirm transactions or policy changes on the wallet.
balance The balance in your wallet after all confirmations. (May not be set for some coins.)
spendableBalance The balance that is currently spendable. (May not be set for some coins.)
confirmedBalance The balance in your wallet in the form of confirmed unspents. (May not be set for some coins.)
balanceString A string representation of the balance property. It is always set.
spendableBalanceString A string representation of the spendableBalance property. It is always set.
confirmedBalanceString A string representation of the confirmedBalance property. It is always set.
admin An object containing the policies set on the wallet.

Policy types

Velocity Limit

A velocity limit policy rule will trigger when the amount spent within the specified time window exceeds the specified amount.

Type value: velocityLimit

Condition values:

Field Description Possible Values
amountString The maximum allowed value of all transactions able to be sent during the time window String number of satoshis, wei, drops, etc.
timeWindow The interval of time in which to sum transaction spend amounts and compare to the limit Number of seconds.
groupTags List of tags specific operations, “:tag” is appropriate is most circumstances string Array.
excludeTags Tags which define the group of wallet ids which, if spent to, will exclude that spend from the limit calculation. Also supports :tag to include current tag context string Array.

Action value:

Field Description Possible Values
type The action to take when the policy is triggered. deny or getApproval

Address Whitelist

An address whitelist rule will be triggered whenever any destination address (non-change) of an outgoing transaction is not in the whitelist.

Type value: whitelist

Condition values:

Field Description Possible Values
add The address to add to the whitelist Valid address in the network of the coin.
remove The address to remove from the whitelist Valid address in the network of the coin.

Action value:

Field Description Possible Values
type The action to take when the policy is triggered. deny or getApproval

Address Blacklist

An address blacklist rule will be triggered whenever any destination address (non-change) of an outgoing transaction is in the blacklist.

Type value: blacklist

Condition values:

Field Description Possible Values
add The address to add to the blacklist Valid address in the network of the coin.
remove The address to remove from the blacklist Valid address in the network of the coin.

Action value:

Field Description Possible Values
type The action to take when the policy is triggered. deny or getApproval

Webhook

A webhook rule will be triggered whenever a transaction is sent from the wallet. A webhook rule will issue a callback to the HTTPS endpoint specified in the condition. The rule will trigger an action if the HTTPS endpoint returns a non-200 (status) response.

Type value: webhook

Condition values:

Field Description Possible Values
url The URL to issue the callback to. HTTPs endpoint

Action value:

Field Description Possible Values
type The action to take when the policy is triggered. deny

Wallet Sharing

A BitGo wallet may be shared between multiple users. All users on a wallet share the same private key (although each individual user may encrypt it separately).

Security on a shared wallet is enforced by BitGo, which requires that users log in and authenticate before co-signing. Wallet permission levels define what an individual user is able to do on a wallet.

Wallet Permissions

Permission Description
View View transactions on the wallet
Spend Initiate transactions on the wallet, which are subject to wallet policy
Admin Change policy and manage users and settings on the wallet

Share a wallet

bitgo.coin('tbtc').wallets().get({ "id": walletId })
.then(function(wallet) {
  wallet.shareWallet({
    email: receiverUser,
    walletPassphrase: senderPassword,
    permissions: 'view,spend',
    skipKeychain: false
  })
  .then(function(result) {
    console.dir(result);
  });
});
WALLETID='58b88…58010'
PASSPHRASE='walletpassphrase'
RECEIVEREMAIL='test@bitgo.com'
PERMISSIONS='view,spend'
curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"walletPassphrase\": \"$PASSPHRASE\", \"email\": \"$RECEIVEREMAIL\", \"permissions\": \"$PERMISSIONS\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/tbtc/wallet/$WALLETID/share

The above will print an object structured as follows:

{
  "id": "58b88…e52aa",
  "coin": "tbtc",
  "wallet": "58b889…58010",
  "walletLabel": "my btc wallet",
  "fromUser": "573e5…16af9",
  "toUser": "56b0e…1f6bf",
  "permissions": "view,spend",
  "state": "active",
  "keychain":
   { "pub": "xpub6…BQWwN",
     "encryptedPrv": "{\"iv\":\"E14kv…InINn}",
     "fromPubKey": "0352c…4373a",
     "toPubKey": "03c73…4920a",
     "path": "m/999999/88717106/124758618"
    }
}

Sharing a wallet involves giving another user permission to use the wallet through BitGo.

In order for the receiver to use the wallet, we also need to share the private key with them. Each user on BitGo creates a public-private keypair for this purpose during their signup process.

The BitGo SDK does the following client-side to create a new wallet share:

HTTP Request

POST /api/v2/:coin/wallet/:walletId/share

Body Parameters

Parameter Type Required Description
email String Yes Email of the user to share the wallet with
permissions String Yes Comma-separated list of permissions, e.g. view,spend,admin
walletPassphrase String No Passphrase on the wallet being shared
skipKeychain Boolean No Set to true if sharing a wallet with another user who will obtain the keychain out-of-band
disableEmail Boolean No Set to true to prevent a notification email sent to the user added

Response

Returns the newly created wallet share object.

Field Description
id ID of the walletshare
coin Cryptocurrency of shared wallet
wallet Wallet id
walletLabel Label of the wallet being shared
fromUser Id of the sharing user
toUser Id of the requested user

List Wallet Shares

bitgo.coin('tbtc').wallets().listShares({})
.then(function(shares) {
  console.dir(shares);
});
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
http://test.bitgo.com/api/v2/tbtc/walletshare

The above will print an object structured as follows:

  {
    "incoming": [
      {
        "id": "58b61…e645f",
        "coin": "tbtc",
        "wallet": "58b61…9f2ee",
        "walletLabel": "my btc wallet",
        "fromUser": "56b0e…1f6bf",
        "toUser": "573e5…16af9",
        "permissions": "view,spend",
        "state": "active"
      }
    ],
    "outgoing": [
      {
        "id": "58b88…e52aa",
        "coin": "tbtc",
        "wallet": "58b88…58010",
        "walletLabel": "my btc wallet",
        "fromUser": "573e5…16af9",
        "toUser": "56b0e…1f6bf",
        "permissions": "view,spend",
        "state": "active"
      }
    ]
  }

This API call is for checking incoming and outgoing wallet shares for the logged-in account.

HTTP Request

GET /api/v2/:coin/walletshare

Response

Returns an array of wallet share objects.

Field Description
incoming Array of incoming wallet shares
outgoing Array of outgoing wallet shares

Get Wallet Share

bitgo.coin('tbtc').wallets().getShare({ walletShareId: shareId })
.then(function(share) {
  console.dir(share);
});
SHAREID='54c59…26f47'

curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
http://test.bitgo.com/api/v2/tbtc/walletshare/$SHAREID

The above will print an object structured as follows:

  {
    "id": "58b61…e645f",
    "coin": "tbtc",
    "wallet": "58b61…9f2ee",
    "walletLabel": "my btc wallet",
    "fromUser": "56b0e…1f6bf",
    "toUser": "573e5…16af9",
    "permissions": "view,spend",
    "state": "active"
  }

Gets incoming and outgoing wallet shares for specific share ID.

HTTP Request

GET /api/v2/:coin/walletshare/:shareId

Response

Returns a wallet share object.

Field Description
id ID of the walletshare
coin Cryptocurrency of shared wallet
wallet Wallet id
walletLabel Label of the wallet being shared
fromUser Id of the sharing user
toUser Id of the requested user

Resend Wallet Share Invite

bitgo.coin('tbtc').wallets().resendShareInvite({ walletShareId: shareId })
.then(function(share) {
  console.dir(share);
});
SHAREID='54c59…26f47'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
http://test.bitgo.com/api/v2/tbtc/walletshare/$SHAREID/resendemail

The above will print an object structured as follows:

  {
    "resent": true
  }

Resends the wallet share invitation to the share recipient. The wallet share should not have been accepted yet.

HTTP Request

POST /api/v2/:coin/walletshare/:shareId/resendemail

Response

Returns a wallet share object.

Field Description
resent true if the invitation was successfully resent, false otherwise

Accept Wallet Share

bitgo.coin('tbtc').wallets().acceptShare({
  walletShareId: shareId,
  newWalletPassphrase: 'receiverpassphrase',
  userPassword: receiverpassword
})
.then(function(result){
  console.dir(result);
});
SHAREID='54c59…26f47'
NEWPASSPHRASE='receiverpassphrase'
PASSWORD='sharingkeypassword'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"userPassword\": \"$PASSPHRASE\", \"newWalletPassphrase\": \"$NEWPASSPHRASE\" }" \
http://$bitgo_express_host:3080/api/v2/tbtc/walletshare/$SHAREID/acceptshare

The above will print an object structured as follows:

{
  "state": "accepted",
  "changed": "true"
}

Client-side operation to accept a wallet share. Performs the following steps:

HTTP Request

POST /api/v2/:coin/walletshare/:shareid/acceptshare

Body Parameters

Parameter Type Required Description
walletShareId String Yes The incoming wallet share ID to accept
newWalletPassphrase String No The passphrase to set on the wallet, for use during future spends
userPassword String No The user’s password to decrypt the shared private key
overrideEncryptedPrv String No Set to an alternate encrypted prv if you wish to store an encrypted prv received out-of-band

Response

Returns an object containing the state of the updated wallet share, and a boolean value indicating if it changed.

Field Description
id The id of the walletShare, used to accept it
walletId The id of the wallet being shared
walletLabel Label of the wallet to present to the user
fromUser BitGo ID of the user sharing the wallet
toUser BitGo ID of the user receiving the wallet
permissions Comma-separated list of permissions that the wallet share will give to the receiving user
keychain The encrypted keychain for the receiver to decrypt (to obtain the private key)

Cancel Wallet Share

bitgo.coin('tbtc').wallets().cancelShare({
  walletShareId: shareId
})
.then(function(result){
  console.dir(result);
});
SHAREID='54c591a5df8380e0e3026f47'

curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/walletshare/$SHAREID

The above will print an object structured as follows:

{
  "state": "canceled",
  "changed": "true"
}

Can be used to cancel a pending outgoing wallet share, or reject an incoming share. The share should not have been accepted yet.

HTTP Request

DELETE /api/v2/:coin/walletshare/:shareId

Query Parameters

Parameter Type Required Description
walletShareId String Yes The wallet share ID to cancel

Response

Field Description
state New state of walletShare
changed True if successful

Remove Wallet User

bitgo.coin('tbtc').wallets().get({ "id": walletId })
.then(function(wallet) {
  wallet.removeUser({ "user": userId })
  .then(function(wallet) {
    console.dir(wallet);
  });
});
WALLETID='58b881a5df8380e0e3058010'
USERID='56b0e1a5df8380e0e301f6bf'

curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/wallet/$WALLETID/user/$USERID

The above will print an object structured as follows:

{
  "id": "58b881a5df8380e0e3058010",
  "users": [
    {
      "user": "55e81a5df8380e0e30e20c6",
      "permissions": [
        "admin",
        "view",
        "spend"
      ]
    }
  ],
  "coin": "tbtc",
  "label": "My btc wallet",
  "m": 2,
  "n": 3,
  "keys": [
    "585951a5df8380e0e304a553",
    "585951a5df8380e0e30d645c",
    "585951a5df8380e0e30b6147"
  ],
  "tags": [
    "585951a5df8380e0e30a198a"
  ],
  "disableTransactionNotifications": false,
  "freeze": {},
  "deleted": false,
  "approvalsRequired": 1,
  "coinSpecific": {},
  "confirmedBalance": 0,
  "balance": 0
}

After a user has accepted a wallet share, they become a party on a wallet and the wallet share is considered “complete”.

In order to revoke the share after they have accepted, you can remove the user from the wallet.

This may require approval by another wallet administrator if there is more than a single administrator on a wallet.

HTTP Request

DELETE /api/v2/:coin/wallet/:walletId/user/:userId

Query Parameters

Parameter Type Required Description
walletId String Yes The ID of the wallet
userId String Yes The user id of the user to remove (can be found on the wallet object)

Response

Returns the updated Wallet Model for this wallet, or a Pending Approval object (if approval is required).

Wallet Recovery

Non-BitGo Recovery

let params = {
    userKey: '{"iv":"lNx/cH1DqEoNtgvFYMTw8w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"v+fVEuCUSws=","ct":"XS+uV89ciRQ96mA9sAn/4RCYPZUYMMIT/Xv+77fgNuoQlDAw3vEvMuG7e6tAjmA0DNf9hUZu94ptLNM3qjRPJlPifHcmbFGljW3KeRq8gLEfS/BIeumbKLQ7x3bp/5r3oNy0YJb0e9HIlpid8VUJfgTlApMvxes="}',
    backupKey: '{"iv":"He7osIAdX7veJdBJqlcW9w==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"19/UrbHsp+A=","ct":"kgzFeG52wZoSwDChx/5dyh9YKXXaFM0bk103jjgriHVeuwII/S47M2X3ktO4Dx0qKZRsSGfjaaakAyG/I5fJVmzQRYy+q5Wy2PrFrsf3iojyUJ2XUrk4qAEAW1PNDOXme68sHXx2Hh7nQyhvDWelwENKjsCr4No="}',
    walletPassphrase: 'secretpassphrase1a5df8380e0e30',
    bitgoKey: 'xpub661MyMwAqRbcEaJxA1rKBo9fiXYEAbBktQRK8fLwvfW9VvBtNcToxHcSbumepQViAC8QgNFAmKrPtZuYL8W8BVJGnKVab2RJh6eiAW91kj4',
    recoveryDestination: '2N8HAWZfjtYsB5H7PKqsmobi53b6FXyvTiL',
    scan: 20
};

bitgo.coin('tbtc').recover(params).then(function(transactionInfo) {
    // print transaction info
    console.dir(transactionInfo);
})

The above will print an object structured as follows:

{
  "inputs": [
    {
      "chainPath": "/0/0/0/0",
      "redeemScript": "52210350f84fa6a225b24066e248226297890d07bdd0ca7ad2e1df74dbe6eea25ca06521020e3ebf14fdbadce9be456933481bcc8d00706dbdcfbd866217fec680d45fd85b21039bbff69aeadacd767d8d09c2c80111073f7d1559753fd9713c9d57b432ca2e7053ae"
    }
  ],
  "transactionHex": "01000000015bd50a21afb2df749e34563046932dbb9af804d9381c5aeb84e18b5785e2b98901000000fdfd00004830450221008cbab51f378d9c468ea4ef8716e1ac5403202a73b58163124082a4251936e06f02201e97838dc9017c7b14989ad8bcd5f50bf1a52593c7439c61cea478c629515a140147304402201a452f1bdd69994e29d87e82db2caef40fb97b366d70b5bc089369220f0c58a702200a3364528077fc4d6a30ad46fe2e29932a998c6fb7d163bd6fc8a03fd49a0ee7014c6952210350f84fa6a225b24066e248226297890d07bdd0ca7ad2e1df74dbe6eea25ca06521020e3ebf14fdbadce9be456933481bcc8d00706dbdcfbd866217fec680d45fd85b21039bbff69aeadacd767d8d09c2c80111073f7d1559753fd9713c9d57b432ca2e7053aeffffffff0180fc00000000000017a914a4e7d0c167a21118626fe2bd97535d7740b2080a8700000000",
  "tx": {
    "Version": "1",
    "LockTime": "0",
    "Vin": [
      {
        "TxId": "89b9e285578be184eb5a1c38d904f89abb2d93463056349e74dfb2af210ad55b",
        "Vout": "1",
        "ScriptSig": {
          "Asm": "0 30450221008cbab51f378d9c468ea4ef8716e1ac5403202a73b58163124082a4251936e06f02201e97838dc9017c7b14989ad8bcd5f50bf1a52593c7439c61cea478c629515a14[ALL] 304402201a452f1bdd69994e29d87e82db2caef40fb97b366d70b5bc089369220f0c58a702200a3364528077fc4d6a30ad46fe2e29932a998c6fb7d163bd6fc8a03fd49a0ee7[ALL] 52210350f84fa6a225b24066e248226297890d07bdd0ca7ad2e1df74dbe6eea25ca06521020e3ebf14fdbadce9be456933481bcc8d00706dbdcfbd866217fec680d45fd85b21039bbff69aeadacd767d8d09c2c80111073f7d1559753fd9713c9d57b432ca2e7053ae",
          "Hex": "004830450221008cbab51f378d9c468ea4ef8716e1ac5403202a73b58163124082a4251936e06f02201e97838dc9017c7b14989ad8bcd5f50bf1a52593c7439c61cea478c629515a140147304402201a452f1bdd69994e29d87e82db2caef40fb97b366d70b5bc089369220f0c58a702200a3364528077fc4d6a30ad46fe2e29932a998c6fb7d163bd6fc8a03fd49a0ee7014c6952210350f84fa6a225b24066e248226297890d07bdd0ca7ad2e1df74dbe6eea25ca06521020e3ebf14fdbadce9be456933481bcc8d00706dbdcfbd866217fec680d45fd85b21039bbff69aeadacd767d8d09c2c80111073f7d1559753fd9713c9d57b432ca2e7053ae"
        },
        "CoinBase": null,
        "TxInWitness": null,
        "Sequence": "4294967295"
      }
    ],
    "Vout": [
      {
        "Value": 0.0006464,
        "N": 0,
        "ScriptPubKey": {
          "Asm": "OP_HASH160 a4e7d0c167a21118626fe2bd97535d7740b2080a OP_EQUAL",
          "Hex": "a914a4e7d0c167a21118626fe2bd97535d7740b2080a87",
          "ReqSigs": 1,
          "Type": "scripthash",
          "Addresses": [
            "2N8HAWZfjtYsB5H7PKqsmobi53b6FXyvTiL"
          ]
        }
      }
    ],
    "TxId": "66434c4869eb6edc910fa8cffeefef7d6729e1b25d5aaffcc484bec08fc6b23b"
  }
}

Extract funds from a BitGo wallet with the user key and backup key. This process is independent from the BitGo service.

Response

Returns a recovery transaction signed with the provided user and backup keys. The transactionHex field may be broadcasted from a node or block explorer.

Wrong Chain Recovery

let params = {
  txid: '54bb88d0e8f03386f040816f921559df96a58bb0b94abe67fd10e66ec7cad36b',
  recoveryAddress: '2N9fcNQtWoL1u2jdtQY3grjvaszKy19WMQ9',
  wallet: '5b103fe117c0edd64fb6730fc68a6fbb',
  coin: bitgo.coin('tltc'),
  walletPassphrase: 'secretpassphrase1a5df8380e0e30'
};

bitgo.coin('tbtc').recoverFromWrongChain(params).then(function (transactionInfo) {
  // print transaction info
  console.dir(transactionInfo);
});

The above will print an object structured as follows:

{
  "version": 2,
  "sourceCoin": "tbtc",
  "recoveryCoin": "tltc",
  "walletId": "5b103fe117c0edd64fb6730fc68a6fbb",
  "recoveryAddress": "2N9fcNQtWoL1u2jdtQY3grjvaszKy19WMQ9",
  "recoveryAmount": 62800,
  "txHex": "01000000016bd3cac76ee610fd67be4ab9b08ba596df5915926f8140f08633f0e8d088bb5401000000b700483045022100af05f5f09e0a20f2a87b1f096ad8ec60918e5557ada1332a2a5c8083c59b205c0220187891dae92629dcc9960f71e5363340222abd326089d6b0d5957a794977b2cb0100004c69522102424fce45241768831dd7bddfd77f6954037c9ef879989861e1b5e0e08eea33082103cbde718033d757c282154d432b1f7bcfce53af9b951e090bcc9b4b4a513abf3321030665ff319c5be4998752635de966560bc7decd6cacd75636e8b1c52b20502f7053aeffffffff0150f500000000000017a914b41eadc4c3083249a19a86847a8c8a43c48deb428700000000",
  "txInfo": {
    "inputAmount": 90000,
    "outputAmount": 62800,
    "spendAmount": 62800,
    "inputs": [
      {
        "id": "54bb88d0e8f03386f040816f921559df96a58bb0b94abe67fd10e66ec7cad36b:1",
        "address": "2NC8FTApZkWBXJ1UU7q9TPyWTZM5h8nHHdP",
        "value": 90000,
        "valueString": "90000",
        "blockHeight": 1325883,
        "date": "2018-06-19T23:24:50.380Z",
        "redeemScript": "522102424fce45241768831dd7bddfd77f6954037c9ef879989861e1b5e0e08eea33082103cbde718033d757c282154d432b1f7bcfce53af9b951e090bcc9b4b4a513abf3321030665ff319c5be4998752635de966560bc7decd6cacd75636e8b1c52b20502f7053ae",
        "index": 0,
        "chain": 0,
        "wallet": "5b103fe117c0edd64fb6730fc68a6fbb",
        "fromWallet": "5b103fe117c0edd64fb6730fc68a6fbb"
      }
    ],
    "outputs": [
      {
        "address": "2N9fcNQtWoL1u2jdtQY3grjvaszKy19WMQ9",
        "value": 62800,
        "valueString": "62800",
        "wallet": "5b103fe117c0edd64fb6730fc68a6fbb",
        "change": false
      }
    ],
    "externalOutputs": [
      {
        "address": "2N9fcNQtWoL1u2jdtQY3grjvaszKy19WMQ9",
        "value": 62800,
        "valueString": "62800",
        "wallet": "5b103fe117c0edd64fb6730fc68a6fbb",
        "change": false
      }
    ],
    "changeOutputs": [],
    "minerFee": 27200,
    "payGoFee": 0,
    "unspents": [
      {
        "id": "54bb88d0e8f03386f040816f921559df96a58bb0b94abe67fd10e66ec7cad36b:1",
        "address": "2NC8FTApZkWBXJ1UU7q9TPyWTZM5h8nHHdP",
        "value": 90000,
        "valueString": "90000",
        "blockHeight": 1325883,
        "date": "2018-06-19T23:24:50.380Z",
        "redeemScript": "522102424fce45241768831dd7bddfd77f6954037c9ef879989861e1b5e0e08eea33082103cbde718033d757c282154d432b1f7bcfce53af9b951e090bcc9b4b4a513abf3321030665ff319c5be4998752635de966560bc7decd6cacd75636e8b1c52b20502f7053ae",
        "index": 0,
        "chain": 0,
        "wallet": "5b103fe117c0edd64fb6730fc68a6fbb",
        "fromWallet": "5b103fe117c0edd64fb6730fc68a6fbb"
      }
    ]
  }
}

Half-signs a transaction to recover funds sent to the wrong chain, such as BTC sent to an LTC address.

Response

Returns a recovery transaction object signed with the provided user key. The returned JSON object should be saved to a file and sent to support@bitgo.com to complete the recovery process.

Pending Approvals

Get Pending Approval

This API calls retrieves the object information for a pending approval by id.

curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/:coin/pendingapprovals/:pendingapprovalid

HTTP Request

GET /api/v2/:coin/pendingapprovals/:pendingapprovalid

Response

Returns a pending approval object.

List Pending Approvals

List pending approvals on a wallet or an enterprise by providing either a wallet id or an enterprise in the url. By default, the request returns all the pending approvals for a user.


let walletId = "590bb3598005caaf07b5bffbe35f3c11";

pendingapproval().list(walletId)
.then(function(list) {
  // Print approval list
  console.dir(list);
});
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/:coin/pendingapprovals?enterprise=$ENTID

HTTP Request

GET /api/v2/:coin/pendingapprovals

Parameter Type Required Description
walletID address(string) No Base address of the wallet
enterprise string No The public ID of the enterprise
allTokens Boolean No Gets details of all token pending approvals. Only valid for teth/eth

Response

Returns a list of pending approvals.

Update Pending Approval

curl -X PUT \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN_OTHERENTERPRISEUSER" \
-d '{ "state": "approved", "otp": "0000000", "walletPassphrase": "password" }' \
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/pendingapprovals/:pendingApprovalid

Example JSON response:

{
  "createDate": "2015-04-28T21:58:02.416Z",
  "creator": "54c2…0c79",
  "enterprise": "54a2…1e88",
  "id": "5540…10f7",
  "info": {
    "policyRuleRequest": {
      "action": "update",
      "policyChanged": "553e…84c7",
      "update": {
        "action": {
          "type": "getApproval"
        },
        "condition": {
          "amount": 300000000
        },
        "id": "com.bitgo.limit.velocity.day",
        "type": "velocityLimit"
      }
    },
    "type": "policyRuleRequest"
  },
  "resolvers": [
    {
      "date": "2015-04-28T22:02:32.395Z",
      "user": "5458…4fd2"
    }
  ],
  "state": "approved"
}

Update the state of a pending approval to either ‘approved’ or 'rejected. Pending approvals are designed to be managed through our web UI. Requests made using an authentication token are not allowed to approve requests. Instead of using pending approvals we recommend creating a webhook policy to do automated approval and denial of transactions.

HTTP Request

PUT /api/v2/:coin/pendingapprovals/:pendingApprovalId

Query Parameters

Parameter Type Required Description
pendingApprovalId String Yes Pending approval id.

Body Parameters

Parameter Type Required Description
state String Yes Approval
otp string Yes One Time Password

Response

Returns the updated Wallet Model object.

Webhook Notifications

Webhooks may be setup up to programmatically receive callbacks from BitGo. These may be attached to wallets (in the case of transfers), or to a user (for block notifications). Webhook notifications are triggered when the specified event occurs, such as an incoming transaction.

BitGo servers will make a POST http request to the URL defined with a JSON payload, and expect a HTTP 200 OK. If a successful response is not received, BitGo will attempt to retry the webhook with an increasing delay between each retry.

Since anyone on the Internet can send HTTP requests to the Webhook URL, the request body payload should not be trusted. Please verify any information sent in the webhook by fetching the transfer/block data from BitGo before processing the notification.

Developers should take care to ensure that their application succeeds even in the cases of transient network error, or if receive the same webhook twice due to an improper acknowledgement.

Request Schema

The Webhook URL will be called with the following JSON-encoded fields in the HTTP body.

Field Description
type Type of Webhook (Can be transfer, pendingapproval, address_confirmation, block or wallet_confirmation)
walletId ID of the wallet associated with the webhook event, if this is a wallet webhook
hash Transaction ID, if this is a transfer webhook
pendingApprovalId Pending approval ID, if this is a pending approval webhook
state The state of the pending approval (pending, approved, or rejected), if this is a pending approval webhook

Webhook Types

BitGo is currently actively working on webhooks. Please get in touch with us to request more webhook types.

Type Description
transfer Activates when a transaction is seen/confirmed on any receive address of a wallet
pendingapproval Activates when a pending approval on the user’s wallet is created, approved, or rejected
address_confirmation Activates when an address has been initialized on a wallet
block Activates when a new block is seen on the coin network
wallet_confirmation Activates when a wallet has been initialized

List Wallet Webhooks

var walletId = "58d99…39604";

bitgo.coin('tbtc').wallets().get({ id: walletId })
.then(function(wallet) {
  return wallet.listWebhooks();
})
.then(function(webhooks) {
  console.dir(webhooks);
});
WALLETID="58d99…39604"

curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/webhooks

The above will print an object structured as follows:

{
  "webhooks": [
    {
      "id": "58d99…3b0ae",
      "label": "Test Webhook",
      "created": "2017-03-22T22:48:51.719Z",
      "walletId": "58d99…39604",
      "coin": "tbtc",
      "type": "transfer",
      "url": "http://your.server.com/webhook",
      "version": 2
    },
    
  ]
}

List all webhooks set up on the wallet. Currently, the types of webhooks that can be attached to a wallet are transfer, pendingapproval and address_confirmation notifications.

HTTP Request

GET /api/v2/:coin/wallet/:walletId/webhooks

Parameter Type Required Description
allTokens Boolean No Gets details of all token webhooks for the wallet. Only valid for eth/teth.

Response

Returns an array of Webhook objects.

Field Description
id Webhook ID.
label Webhook label.
created Webhook creation time.
walletId Wallet ID.
coin Cryptocurrency type.
type Webhook type.
URL Webhook callback URL.

Errors

Response Description
401 Unauthorized Token lacks required scope wallet_manage

Add Wallet Webhook

var walletId = "58d99…39604";
var url = "http://your.server.com/webhook";

bitgo.coin('tbtc').wallets().get({ id: walletId })
.then(function(wallet) {
  return wallet.addWebhook({
    url: url,
    type: "transfer"
  });
})
.then(function(webhook) {
  // print the new webhook
  console.dir(webhook);
});
WALLETID="58d99…39604"
URL="http://your.server.com/webhook"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"url\": \"$URL\", \"type\": \"transfer\" }" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/webhooks

The above will print an object structured as follows:

{
  "id": "590cd…35835",
  "created": "2017-05-05T19:46:22.019Z",
  "walletId": "590bb…f3c11",
  "coin": "tbtc",
  "type": "transfer",
  "url": "http://your.server.com/webhook",
  "version": 2
}

Add a webhook that will result in an HTTP callback at the specified URL from BitGo when events are triggered. There is a limit of 25 Webhooks of each type per wallet.

Types of wallet webhooks available:

  1. Transfer webhooks will fire on any transfer on the wallet.
  2. Pending approval webhooks will fire when an event triggers policy on the wallet (e.g send transaction, user change, policy change, pending approval updated).
  3. Address confirmation webhooks will fire when an address has been initialized on the wallet.

HTTP Request

POST /api/v2/:coin/wallet/:walletId/webhooks

Body Parameters

Parameter Type Required Description
url String Yes URL to fire the webhook to.
type String Yes Type of event to listen to (can be transfer or pendingaapproval).
numConfirmations Integer No Number of confirmations before triggering the webhook. If 0 or unspecified, requests will be sent to the callback endpoint when the transfer is first seen and when it is confirmed.

Response

Returns a Webhook object.

Field Description
id Webhook ID.
created Webhook creation time.
walletId Wallet ID.
coin Cryptocurrency type.
type Webhook type.
url Webhook callback URL.

Errors

Response Description
400 Bad Request Webhook already exists
400 Bad Request Invalid url: http://YOUR_URL:PORT/transactions/notification

Remove Wallet Webhook

var walletId = "58d99…39604";
var url = "http://your.server.com/webhook";

bitgo.coin('tbtc').wallets().get({ id: walletId })
.then(function(wallet) {
  return wallet.removeWebhook({
    url: url,
    type: "transfer"
  });
})
.then(function(result) {
  console.dir(result);
});
WALLETID="58d99…39604"
URL="http://your.server.com/webhook"

curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"url\": \"$URL\", \"type\": \"transfer\" }" \
http://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/webhooks

The above will print an object structured as follows:

{
  "removed": 1
}

Removing a webhook will cause new events of the specified type to no longer trigger HTTP callbacks to your URLs.

HTTP Request

DELETE /api/v2/:coin/wallet/:walletId/webhooks

Body Parameters

Parameter Type Required Description
type String Yes Type of the webhook (e.g. transfer, pendingapproval).
url String Yes URL for callback requests to be made at.

Response

Returns an object containing and a boolean value indicating if the webhook was removed.

Field Description
Removed Binary response for request(0,1)

Simulate Wallet Webhook

  wallet.simulateWebhook({
    webhookId: '590cd…35835',
    transferId: '59b70…dbd44'
  })
  .then(function(result) {
    console.dir(result);
  });
WALLETID="58d99…39604"
WEBHOOKID='590cd…35835',
TRANSFERID='59b70…dbd44'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"transferId\": \"$TRANSFERID\" }" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLETID/webhooks/$WEBHOOKID/simulate

The above will print an object structured as follows:

{
  "webhookNotifications": [
    {
      "id": "590cd…129f6",
      "type": "transfer",
      "wallet": "58d99…39604",
      "url": "http://your.server.com/webhook",
      "hash": "c25e6…c36ed",
      "coin": "tbtc",
      "state": "new",
      "transfer": "59b70…dbd44",
      "webhook": "590cd…35835",
      "updatedAt": "2017-05-05T19:53:41.544Z",
      "version": 2
    }
  ]
}

This API allows you to simulate and test a webhook so you can view its response.

HTTP Request

POST /api/v2/:coin/wallet/:walletId/webhooks/:webhookId/simulate

Body Parameters

Parameter Type Required Description
webhookId String Yes Webhook ID.
transferId String No ID of the transfer to be used in the simulation.
pendingApprovalId String No ID of the pending approval to be used in the simulation.

Errors

Response Description
400 Bad Request Invalid webhook type
404 Not Found Webhook not found
404 Not Found Wallet not found

List User Webhooks

var baseCoin = bitgo.coin('tbtc');
var webhooks = baseCoin.webhooks();

webhooks.list()
.then(function(result) {
  console.dir(result);
});
curl -X GET \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/webhooks

The above will print an object structured as follows:

{
  "webhooks": [
    {
      "id": "5a53a…4cb46",
      "label": "Test User Webhook",
      "created": "2018-01-08T16:56:36.546Z",
      "coin": "tbtc",
      "type": "block",
      "url": "http://your.server.com/user_webhook",
      "numConfirmations": 1,
      "version": 2,
      "state": "active",
      "successiveFailedAttempts": 0
    },
    
  ]
}

List all webhooks set up on the user. Currently, the types of webhooks that can be attached to a user are block and wallet_confirmation notifications.

HTTP Request

GET /api/v2/:coin/webhooks

Response

Returns an array of Webhook objects.

Field Description
id Webhook ID.
label Webhook label.
created Webhook creation time.
coin Cryptocurrency type.
type Webhook type.
url Webhook callback URL.
version 2 for coins running on API v2.
state state of the webhook (can be active or suspended).
successiveFailedAttempts number of successive failed attempts.

Errors

Response Description
401 Unauthorized Access token lacks required scope for this action

Add User Webhook

var baseCoin = bitgo.coin('tbtc');
var webhooks = baseCoin.webhooks();

webhooks.add({
  url: "http://your.server.com/user_webhook",
  type: "block",
  label: "Test User Webhook",
  numConfirmations: 1
})
.then(function(result) {
  console.dir(result);
});
URL="http://your.server.com/user_webhook"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"url\": \"$URL\", \"type\": \"block\" , \"label\": \"Test User Webhook\" , \"numConfirmations\": 1 }" \
https://test.bitgo.com/api/v2/tbtc/webhooks

The above will print an object structured as follows:

{
  "id": "5a53a…4cb46",
  "label": "Test User Webhook",
  "created": "2018-01-08T16:56:36.546Z",
  "coin": "tbtc",
  "type": "block",
  "url": "http://your.server.com/user_webhook",
  "numConfirmations": 1,
  "version": 2,
  "state": "active",
  "successiveFailedAttempts": 0
}

Add a webhook that will result in an HTTP callback at the specified URL from BitGo when events are triggered.

There is one type of user webhook available:

  1. Block webhooks will fire when a new block is seen on the coin network.
  2. Wallet confirmation webhooks will fire when a wallet has been initialized.

HTTP Request

POST /api/v2/:coin/webhooks

Body Parameters

Parameter Type Required Description
url String Yes URL to fire the webhook to.
type String Yes Type of event to listen to (can be of type block).
label String No Label of the new webhook.
numConfirmations Integer No Number of confirmations before triggering the webhook.

Response

Returns a Webhook object.

Field Description
id Webhook ID.
label Webhook label.
created Webhook creation time.
coin Cryptocurrency type.
type Webhook type.
url Webhook callback URL.
version 2 for coins running on API v2.
state state of the webhook (can be active or suspended).
successiveFailedAttempts number of successive failed attempts.

Remove User Webhook

var baseCoin = bitgo.coin('tbtc');
var webhooks = baseCoin.webhooks();

webhooks.remove({
  url: "http://your.server.com/user_webhook",
  type: "block"
})
.then(function(result) {
  console.dir(result);
});
URL="http://your.server.com/user_webhook"

curl -X DELETE \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"url\": \"$URL\", \"type\": \"block\" }" \
https://test.bitgo.com/api/v2/tbtc/webhooks

The above will print an object structured as follows:

{
  "removed": 1
}

Removing a webhook will cause new events of the specified type to no longer trigger HTTP callbacks to your URLs.

HTTP Request

DELETE /api/v2/:coin/webhooks

Body Parameters

Parameter Type Required Description
type String Yes Type of the webhook (e.g. block).
url String Yes URL for callback requests to be made at.

Response

Returns an object containing and a boolean value indicating if the webhook was removed.

Field Description
Removed Binary response for request(0,1)

Simulate User Webhook

var baseCoin = bitgo.coin('tbtc');
var webhooks = baseCoin.webhooks();

webhooks.simulate({
  webhookId: '590cd…35835',
  blockId: '00000…507d6'
})
.then(function(result) {
  console.dir(result);
});
WEBHOOKID='590cd…35835',
BLOCKID='00000…507d6'

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"blockId\": \"$BLOCKID\" }" \
https://test.bitgo.com/api/v2/tbtc/webhooks/$WEBHOOKID/simulate

The above will print an object structured as follows:

{
  "webhookNotifications": [
    {
      "id": "590cd…129f6",
      "type": "block",
      "url": "http://your.server.com/user_webhook",
      "hash": "00000…507d6",
      "coin": "tbtc",
      "state": "new",
      "webhook": "590cd…35835",
      "updatedAt": "2017-05-05T19:53:41.544Z",
      "version": 2
    }
  ]
}

This API allows you to simulate and test a webhook so you can view its response.

HTTP Request

POST /api/v2/:coin/webhooks/:webhookId/simulate

Body Parameters

Parameter Type Required Description
webhookId String Yes Webhook ID.
blockId String No Hash of the block to be used in the simulation.

Errors

Response Description
400 Bad Request Invalid webhook type
404 Not Found Webhook not found

Coin-Specific Implementation

BitGo strives to provide a multitude of different digital currencies via a seamless common application interface. Our platform is designed for the simple funds transfer of such currencies. The API operates at a wallet level above the blockchain, and the SDK handles the different transactional implementations without getting in the user’s way.

At times, certain operations (such as wallet creation) are handled differently between Blockchains - in Bitcoin, a multisig address can be crafted with just the 3 keys, but in Ethereum, a multisig contract must be deployed.

This section explains the differences of how BitGo handle’s our wallet operations - it is for informational use; our the SDK handles the intricacies of each digital currency, creating a common interface across all coins.

For a summarized list of all supported digital currencies, see this section.

Bitcoin

Bitcoin can be accessed with the following coin types

Environment Coin Type Faucet
Bitcoin Production btc
Bitcoin Testnet tbtc https://testnet.manu.backend.hamburg/faucet

The Bitcoin wallets in Platform V2 should not be confused with the wallets created via V1 routes.

Wallet construction

bitgo.coin('tbtc').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/tbtc/wallet/generate

For Bitcoin, BitGo uses a 2-of-3 multisig P2SH scheme, with the keys in the order of User, Backup and Bitgo respectively.

Wallet creation can be done in a single line with the help of our SDK.

Generating addresses

bitgo.coin('tbtc').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tbtc/wallet/$WALLET/address

BitGo uses an HD wallet scheme supporting the BIP32 standard with the following paths:

Manually generated addresses (for deposits): /0/0/0/n

Change addresses: /0/0/1/n

Balances

Bitcoin’s unit subdivisibility goes up to 100,000,000 satoshis, so most amounts can be represented as multiples of the smallest subdivison unit without exceeding the range of Javascript numbers.

For that reason, both the integer and the string balance properties are available, which covers balance, confirmedBalance, and spendableBalance, as well as their string value counterparts, balanceString, confirmedBalanceString, and spendableBalanceString.

Bitcoin Cash

Bitcoin Cash can be accessed with the following coin types

Environment Coin Type Faucet
Bitcoin Cash Production bch
Bitcoin Cash Testnet tbch https://testnet.manu.backend.hamburg/bitcoin-cash-faucet

New wallets created within Bitcoin Cash are not able to receive normal Bitcoin.

Fork notes

Bitcoin Cash (BCH) forked from the Bitcoin mainnet on August 1st, 2017. Addresses with balances at that time have the same balance within Bitcoin Cash. After this date, blocks and transactions on the BCH fork no longer overlap with Bitcoin.

The Bitcoin Cash fork is replay-safe both ways, meaning that transactions made after August 1st, 2017 on one chain will not occur on the other.

Migrated Wallets

All BitGo customers using our Bitcoin wallets on August 1st, 2017 had their wallets and keys automatically migrated to the V2 BCH coin type.

Users can find migrated wallets by using the list wallets API. On the wallet object, there is a migratedFrom property that corresponds to the Bitcoin Wallet ID.

To protect against confusion (users sending BCH to BTC addresses or vice versa), migrated wallets may not create new addresses by default. Users should create a new wallet with new keys to ensure all new BCH addresses do not collide with BTC addresses.

New Wallet construction

bitgo.coin('bch').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/bch/wallet/generate

For Bitcoin, BitGo uses a 2-of-3 multisig P2SH scheme, with the keys in the order of User, Backup and Bitgo respectively.

Wallet creation can be done in a single line with the help of our SDK.

Generating addresses

bitgo.coin('bch').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/bch/wallet/$WALLET/address

BitGo uses an HD wallet scheme supporting the BIP32 standard with the following paths:

Manually generated addresses (for deposits): /0/0/0/n

Change addresses: /0/0/1/n

Bitcoin Gold

Bitcoin Gold can be accessed with the following coin types

Environment Coin Type
Bitcoin Gold Production btg

Fork notes

Bitcoin Gold (BTG) forked from the Bitcoin mainnet on October 24th, 2017. Addresses with balances at that time have the same balance within Bitcoin Gold. After this date, blocks and transactions on the BTG fork no longer overlap with Bitcoin.

Bitcoin Gold uses a different address format from Bitcoin which protects users from accidentally sending coins to the wrong chain. All Bitcoin Gold addresses start with either a G or an A. Since BitGo wallets use multisig addresses, all addresses for our wallets start with an A.

The Bitcoin Gold fork is replay-safe both ways, meaning that new transaction made on one chain will not occur on the other.

Migrated Wallets

All BitGo customers using our Bitcoin wallets on October 24th, 2017 had their wallets and keys automatically migrated to the V2 BTG coin type.

Users can find migrated wallets by using the list wallets API. On the wallet object, there is a migratedFrom property that corresponds to the Bitcoin Wallet ID.

Litecoin

Litecoin can be accessed with the following coin types

Environment Coin Type Faucet
Litecoin Production ltc
Litecoin Testnet tltc http://testnet.litecointools.com/

Wallet construction

bitgo.coin('tltc').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/tltc/wallet/generate

For Litecoin, BitGo uses the same 2-of-3 multisig P2SH scheme as for Bitcoin, with the keys in the order of User, Backup and Bitgo respectively.

Generating addresses

bitgo.coin('tltc').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/tltc/wallet/$WALLET/address

BitGo uses an HD wallet scheme supporting the BIP32 standard with the following paths:

Manually generated addresses (for deposits): /0/0/0/n

Change addresses: /0/0/1/n

Converting addresses

bitgo.coin('ltc').canonicalAddress('3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd', 2);
// MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE

bitgo.coin('ltc').canonicalAddress('3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd', 1);
bitgo.coin('ltc').canonicalAddress('MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE', 1);
// 3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd
curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"address\": \"3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd\", \"scriptHashVersion\": 2 }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/ltc/canonicaladdress
# MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE

It is worth noting that Litecoin used to support the same P2SH address format as Bitcoin, but then switched to other version identifiers. For this reason, there can be confusion between Litecoin addresses that start with a 3 and those that start with M. However, both addresses are the same, and BitGo always interprets incoming transactions using the new address format (i. e. starting with an M). For outgoing transactions, we have an address conversion tool that would take an address like this one 3GBygsGPvTdfKMbq4AKZZRu1sPMWPEsBfd and convert it to this: MNQ7zkgMsaV67rsjA3JuP59RC5wxRXpwgE.

In testnet, the new P2SH addresses start with Q, so the corresponding conversion could be between 2MsFGJvxH1kCoRp3XEYvKduAjY6eYz9PJHz and QLc2RwpX2rFtZzoZrexLibcAgV6Nsg74Jn.

In order to prevent ambiguity, BitGo only accepts the new address format for outgoing transactions.

Method

bitgo.coin('ltc').canonicalAddress(address, scriptHashVersion)

bitgo.coin('tltc').canonicalAddress(address, scriptHashVersion)

HTTP Request

POST /api/v2/:coin/canonicaladdress

Function Arguments

Parameter Type Required Description
address String Yes The address string to convert
scriptHashVersion Integer No 1 for old address format, 2 for new. Defaults to 2.

Balances

Just as with Bitcoin, Litecoin’s unit subdivisibility goes up to 100,000,000, so most amounts can be represented as multiples of the smallest subdivison unit without exceeding the range of Javascript numbers.

For that reason, both the integer and the string balance properties are available, which covers balance, confirmedBalance, and spendableBalance, as well as their string value counterparts, balanceString, confirmedBalanceString, and spendableBalanceString.

Royal Mint Gold

RMG can be accessed with the following coin types

Environment Coin Type Faucet
RMG Production rmg
RMG Testnet trmg https://philosophersstone.rmgchain.info/

Wallet construction

bitgo.coin('trmg').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/trmg/wallet/generate

Royal Mint Gold wallets are very much alike Bitcoin’s, except that the consensus protocol is designed to require 2 Account Service Provider IDs and a single public key hash.

Generating addresses

bitgo.coin('trmg').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/trmg/wallet/$WALLET/address

Royal Mint Gold addresses are generated using the BIP32 standard described earlier, but only the user key varies.

The BitGo and backup keys are referenced and enforced as Account Service Provider IDs on a consensus protocol level.

Balances

Royal Mint Gold subdivisibility goes up to 1,000,000 atoms per gram, so all amounts can be represented as multiples of the smallest subdivison unit without exceeding the range of Javascript numbers.

For that reason, both the integer and the string balance properties are available, which covers balance, confirmedBalance, and spendableBalance, as well as their string value counterparts, balanceString, confirmedBalanceString, and spendableBalanceString.

Ethereum

Ethereum can be accessed with the following coin types

Environment Coin Type Faucet Instructions
Ethereum Production eth
Ethereum Testnet teth https://github.com/kovan-testnet/faucet

Enterprise fee address

ENTERPRISEID=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/teth/enterprise/$ENTERPRISEID/feeAddressBalance 

Each enterprise has a fee address which will be used to pay for transaction fees on all Ethereum wallets in that enterprise. The fee address is displayed in the dashboard of the BitGo website, and you must fund it before creating a wallet, address, or sending a transaction. Unlike in Bitcoin (where the sending wallet also pays the transaction fees) BitGo’s Ethereum wallet contract requires a separate account to initiate the transaction and pay the fees. If the enterprise’s fee address runs out of funds, you will not be able to create new wallets, addresses, or send transactions until you fund the fee address. You will not be able to use one of your own Ethereum wallets to fund the fee address if the fee address is too low (because you will not be able to send transactions from your Ethereum wallet) so it is best to create and fund a non-BitGo Ethereum account so you can use it to fund your BitGo enterprise fee address. Any open source Ethereum wallet or Ethereum exchange can be used to create an account.

Please note that the fee address is a single-signature account and the private key is created and owned by BitGo, so you will not be able to send funds out of the fee address once you have sent them in.

There will be a ‘feeAddress’ field under the 'CoinSpecific’ key for Ethereum wallets. You will use this address to pay the fees for creating transactions and addresses.

Wallet construction

bitgo.coin('teth').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' enterprise: '5612c2beeecf83610b621b90964448cd' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/teth/wallet/generate

Ethereum wallets can only be created under an enterprise. Pass in the id of the enterprise to associate the wallet with. Your enterprise id can be seen by clicking on the “Manage Organization” link on the enterprise dropdown.

Unlike Bitcoin, when you create an Ethereum wallet, BitGo sends a transaction on the Ethereum network in order to deploy its multi-signature wallet contract. While this initialization transaction is unconfirmed, the wallet should not be used, nor should anyone attempt to send funds to the wallet. For this reason, while the wallet’s initialization transaction is still unconfirmed on the Ethereum network the wallet’s receive address will not be visible through the API. This is to protect users against accidentally sending to an Ethereum wallet which does not exist on the network and losing funds.

Generating addresses

bitgo.coin('teth').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/teth/wallet/$WALLET/address

Unlike Bitcoin, Ethereum address creation requires interactions with the Ethereum blockchain. In order to deploy a receive address contract, BitGo sends a transaction on the Ethereum network. Please make sure to fund the fee address mentioned above. Like the wallet creation process, an Ethereum address will not be immediately usable upon creation and so the caller of this function will have to wait for the initialization transaction to be confirmed before attempting to fetch, or send to, the address

Balances

Unlike Bitcoin, each ether is comprised of 1,000,000,000,000,000,000 (1018) wei, so not even a single ether can be stored numerically without exceeding the range of Javascript numbers.

For that reason, only the string balance properties are available, which are balanceString, confirmedBalanceString, and spendableBalanceString.

Transactions

BitGo’s Ethereum multisig contract currently only supports one sender and one recipient. That means that the sendMany call will only accept one recipient.

Ripple

Ripple can be accessed with the following coin types

Environment Coin Type Faucet
Ripple Production xrp
Ripple Altnet txrp https://skippingstone.multisig.club/

Wallet construction

bitgo.coin('txrp').wallets()
.generateWallet({ label: 'My Test Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My Test Wallet"
PASSPHRASE="secretpassphrase1a5df8380e0e30"

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"label\": \"$LABEL\", \"passphrase\": \"$PASSPHRASE\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/txrp/wallet/generate

The creation of Ripple wallets is like Ethereum’s, in that wallet creation requires interaction with the blockchain (or the Ripple Consensus Ledger, short: RCL) to complete. When you create a Ripple wallet, BitGo sends 4 initialization transactions on the Ripple network in order to create the wallet. While these initialization transactions are unconfirmed, the wallet should not be used, nor should anyone attempt to send funds to the wallet. For this reason, while the wallet’s initialization transactions are still unconfirmed on the Ripple network the wallet’s receive address be not be visible through the API. This is to protect users against accidentally sending to a Ripple wallet which does not exist on the network and losing funds.

As with most blockchain interactions, there is a fee associated with it, which is currently at 45XRP. Therefore, though the creation of Ripple wallets is unlimited in our testing environment, a mandatory payment agreement is associated with it in production. Each enterprise has a default limit of 5 ripple wallets, but this limit can be increased by contacting BitGo at support@bitgo.com.

Generating addresses

bitgo.coin('txrp').wallets().getWallet({ id: '585c51a5df8380e0e3082e46' })
.then(function(wallet) {
  return wallet.createAddress();
})
.then(function(newAddress) {
  // print new address details
  console.dir(newAddress);
});
WALLET=585c51a5df8380e0e3082e46

curl -X POST \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/txrp/wallet/$WALLET/address

A key difference between Ripple and Bitcoin is that Ripple has no concept of UTXOs, and operates on an account-based model instead. Additionally, Ripple transactions only support one input and one output. That means that the sendMany call is not supported.

The BIP32 standard therefore cannot be taken advantage of, and hence generated Ripple addresses differ only in their sequentially incrementing destination tag components.

Balances

Though just like RMG, a single XRP is subdivisible only up to 1,000,000 drops, due to the very high potential number of total XRP in the system, it is likely that many amounts cannot be represented numerically without exceeding the range of Javascript nunmbers.

For that reason, only the string balance properties are available, which are balanceString, confirmedBalanceString, and spendableBalanceString.

ERC20 Tokens

ERC20 tokens can be accessed with the following coin types.

Environment Coin Type Contract Details
Ethereum Kovan Testnet terc https://kovan.etherscan.io/address/0x3cbda27c7c2b4c74055c2548fdba8ed92da53645
Ethereum Mainnet bat https://etherscan.io/token/0x0d8775f648430679a709e98d2b0cb6250d2887ef
Ethereum Mainnet brd https://etherscan.io/token/0x558ec3152e2eb2174905cd19aea4e34a23de9ad6
Ethereum Mainnet cvc https://etherscan.io/token/0x41e5560054824ea6b0732e656e3ad64e20e94e45
Ethereum Mainnet fun https://etherscan.io/token/0x419d0d8bdd9af5e606ae2232ed285aff190e711b
Ethereum Mainnet gnt https://etherscan.io/token/0xa74476443119A942dE498590Fe1f2454d7D4aC0d
Ethereum Mainnet knc https://etherscan.io/token/0xdd974d5c2e2928dea5f71b9825b8b646686bd200
Ethereum Mainnet mkr https://etherscan.io/token/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2
Ethereum Mainnet nmr https://etherscan.io/token/0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671
Ethereum Mainnet omg https://etherscan.io/token/0xd26114cd6EE289AccF82350c8d8487fedB8A0C07
Ethereum Mainnet pay https://etherscan.io/token/0xB97048628DB6B661D4C2aA833e95Dbe1A905B280
Ethereum Mainnet qrl https://etherscan.io/token/0x697beac28b09e122c4332d163985e8a73121b97f
Ethereum Mainnet rep https://etherscan.io/token/0x1985365e9f78359a9b6ad760e32412f4a445e862
Ethereum Mainnet rdn https://etherscan.io/token/0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6
Ethereum Mainnet wax https://etherscan.io/token/0x39Bb259F66E1C59d5ABEF88375979b4D20D98022
Ethereum Mainnet zil https://etherscan.io/token/0x05f4a42e251f2d52b8ed15e9fedaacfcef1fad27
Ethereum Mainnet zrx https://etherscan.io/token/0xe41d2489571d322189246dafa5ebde1f4699f498

Wallet functionality

ERC20 tokens are stored in Ethereum wallets. As a result certain wallet functionality available to other coins is not available to supported tokens. It is not possible to create wallets, create/list/get receive addresses, or share wallets for ERC20 tokens. All these functions will have to be done with the coin set to eth or teth since that is the actual coin type being used. In order to retrieve all token details associated with an Ethereum wallet, such as balance, pending approvals, policies, and webhooks, set the “allTokens” parameter to true with the following calls:

  1. Get Wallet
  2. List Wallets
  3. List Pending Approvals
  4. List Wallet Webhooks
  5. List Transfers
  6. List Transactions

Keychains

ERC20 tokens do not have a direct association with keys or keychains. Instead, all tokens share the same keys/keychains which belong to the Ethereum wallet.

Balances

Each token has a different divisibility factor which is specified in the token contract. This value is usually 1,000,000,000,000,000,000 (1018) units, but can vary from token to token. Please check the client constants to see the number of decimal places the token supports.

Only the string balance properties are available, which are balanceString, confirmedBalanceString, and spendableBalanceString.

Transactions

BitGo’s Ethereum multisig contract currently only supports one sender and one recipient. That means that the sendMany call will only accept one recipient for tokens.

Utilities

This section describes utility services provided as part of the BitGo v1 API.

Decrypt

var encryptedString = '{"iv":"n4zHXVTi/Go/riCP8fNs/A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"zvLyve+4AJU=","ct":"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l"}';
var decryptedString = bitgo.decrypt({ password: "password", input: encryptedString });
// decryptedString = "this is a secret"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/decrypt

{ "decrypted" : "this is a secret" }

Client-side function to decrypt an encrypted blob from the BitGo API.

Encrypt

var encryptedString = bitgo.encrypt({ password: "password", input: "this is a secret" });
// encyrptedString = "{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='this is a secret'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/encrypt

{ "encrypted" : "{\"iv\":\"U4uRz85ytmlCeTe2P3iOmg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"/tRnUh9LUyI7L5e5LPqpvnPR7RD1CdUi\"}" }

Client-side function to encrypt a string. All data stored with BitGo is encrypted using this API.

Market Price Data

This API is still being developed. BitGo will update this section soon.

HTTP Request

GET /api/v2/tbtc/market/latest

Example Market Model response

Coming soon

Estimate Transaction Fees

bitgo.coin('tbch').feeEstimate({ numBlocks: 2 }, function callback(err, res) {
  console.dir(res);
});
COIN=tbch \
curl -k https://www.bitgo.com/api/v2/$COIN/tx/fee

Returns the recommended fee rate per kilobyte to confirm a transaction within a target number of blocks. This can be used as the feeRate to construct transactions.

HTTP Request

GET /api/v2/:coin/tx/fee

Example response

{ 
  "feePerKb": 15000,
  "numBlocks": 2
}

Parameters

Parameter Type Required Coins Description
numBlocks number No BTC The target number of blocks for the transaction to be confirmed. The accepted range is 1 - 1000 and the default value is 2.

Response

Field Description
feePerKb The estimated fee rate in satoshis per kilobyte for the requested target number of blocks (returns the default fee rate for all non BTC coins).
numBlocks The target number of blocks requested for the estimate

Sign Transaction

let params = {
  "txPrebuild": {
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000",
    "txInfo": {
      "nP2SHInputs": 1,
      "nSegwitInputs": 0,
      "nOutputs": 2,
      "unspents": [
        {
          "chain": 1,
          "index": 10,
          "redeemScript": "52210208906f13de98b88bc9f83886c39a1555ada816b12de6f029626af2ef9413708b2102bca01320026604530fc47068ce015b39b91bd72d8964b0c5023697645b1441ab210336d8e968990c8a5b2bad83a237c37957ce70586ed507b155941ea28ec953860153ae",
          "id": "7df5bb3c8ce6daa9e3bed51d2d926c231525e595032713ed8fde4166adb5b079:1",
          "address": "2MvevrYxML8NkRng4avXz7oMCgs5qxR7Mef",
          "value": 4508000
        }
      ],
      "changeAddresses": [
        "2MtLtTSsC98dF4zriFGvCfmce3A17Zz1McK"
      ]
    },
    "feeInfo": {
      "size": 373,
      "fee": 3730,
      "feeRate": 10000,
      "payGoFee": 0,
      "payGoFeeString": "0"
    }
  },
  "prv": "xprvmysecretprivatekey"
};
bitgo.coin('tbtc').signTransaction(params)
.then(function(transaction) {
  // print half-signed transaction hex
  console.dir(transaction);
});

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{\"txPrebuild\":{\"txHex\":\"010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000\" \
 ,\"txInfo\":{\"nP2SHInputs\":1,\"nSegwitInputs\":0,\"nOutputs\":2,\"unspents\":[{\"chain\":1,\"index\":10,\"redeemScript\":\"52210208906f13de98b88bc9f83886c39a1555ada816b12de6f029626af2ef9413708b2102bca01320026604530fc47068ce015b39b91bd72d8964b0c5023697645b1441ab21 \
 0336d8e968990c8a5b2bad83a237c37957ce70586ed507b155941ea28ec953860153ae\",\"id\":\"7df5bb3c8ce6daa9e3bed51d2d926c231525e595032713ed8fde4166adb5b079:1\", \
 \"address\":\"2MvevrYxML8NkRng4avXz7oMCgs5qxR7Mef\",\"value\":4508000}],\"changeAddresses\":[\"2MtLtTSsC98dF4zriFGvCfmce3A17Zz1McK\"]}, \
 \"feeInfo\":{\"size\":373,\"fee\":3730,\"feeRate\":10000,\"payGoFee\":0,\"payGoFeeString\":\"0\"}},\"prv\":\"xprvmysecretprivatekey\"}"
http://$BITGO_EXPRESS_HOST:3080/api/v2/:coin/signtx

It returns an object that looks this:

{
    "txHex": "010000000179b0b5ad6641de8fed13270395e52515236c922d1dd5bee3a9dae68c3cbbf57d0100000000ffffffff0240420f000000000017a914f600974688ccdf5e72ce3f2b187afabbf4f1d3ec878e7835000000000017a9140c0a513cb9d8e46113c57aa46ae42d1bad29063d8700000000"
}

All signing is done locally and can be performed offline. Signing must happen with the prv argument representing the private key.

HTTP Request

POST /api/v2/:coin/signtx

Body Parameters

Parameter Type Required Description
txPrebuild Object Yes The transaction description object, output from ‘Create Transaction’
prv String Yes The user private key

Response

Field Description
txHex The half-signed, serialized transaction hex

Examples

This section describes utility services provided as part of the BitGo v1 API.

Create Wallet / Addresses

var encryptedString = '{"iv":"n4zHXVTi/Go/riCP8fNs/A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"zvLyve+4AJU=","ct":"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l"}';
var decryptedString = bitgo.decrypt({ password: "password", input: encryptedString });
// decryptedString = "this is a secret"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/decrypt

{ "decrypted" : "this is a secret" }

Client-side function to decrypt an encrypted blob from the BitGo API.

Get Wallet / Balances

var encryptedString = '{"iv":"n4zHXVTi/Go/riCP8fNs/A==","v":1,"iter":10000,"ks":256,"ts":64,"mode":"ccm","adata":"","cipher":"aes","salt":"zvLyve+4AJU=","ct":"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l"}';
var decryptedString = bitgo.decrypt({ password: "password", input: encryptedString });
// decryptedString = "this is a secret"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/decrypt

{ "decrypted" : "this is a secret" }

Client-side function to decrypt an encrypted blob from the BitGo API.

List Wallet Transactions

var encryptedString = bitgo.encrypt({ password: "password", input: "this is a secret" });
// encyrptedString = "{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='this is a secret'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/encrypt

{ "encrypted" : "{\"iv\":\"U4uRz85ytmlCeTe2P3iOmg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"/tRnUh9LUyI7L5e5LPqpvnPR7RD1CdUi\"}" }

Client-side function to encrypt a string. All data stored with BitGo is encrypted using this API.

Send Wallet Transactions

var encryptedString = bitgo.encrypt({ password: "password", input: "this is a secret" });
// encyrptedString = "{\"iv\":\"n4zHXVTi/Go/riCP8fNs/A==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"gNMqheicMoD8ZmNzRwuQfWGAh+HA933l\"}"
Available only as a local method (BitGo Express)

PASSWORD='password'
INPUT='this is a secret'

curl -X POST \
-H "Content-Type: application/json" \
-d "{ \"password\": \"$PASSWORD\", \"input\": \"$INPUT\" }" \
http://$BITGO_EXPRESS_HOST:3080/api/v2/encrypt

{ "encrypted" : "{\"iv\":\"U4uRz85ytmlCeTe2P3iOmg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"zvLyve+4AJU=\",\"ct\":\"/tRnUh9LUyI7L5e5LPqpvnPR7RD1CdUi\"}" }

Client-side function to encrypt a string. All data stored with BitGo is encrypted using this API.