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

BitGo Express Proxy Support

BitGo Express can also make requests to BitGo via a proxy. This can be done by setting the BITGO_USE_PROXY environment variable to the URI where your proxy is listening.

For example, to instruct BitGo Express to use a SOCKS proxy which is listening at 192.0.2.1 on port 12000, you should start BitGo Express with the following command:

BITGO_USE_PROXY="socks://192.0.2.1:12000" ./bitgo-express --debug --port 3080 --env test --bind localhost

BitGo Express currently supports the following proxy protocols:

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
dash Dash UTXO-based Production Beta
eth Ethereum Account Production Enterprise access
ltc Litecoin UTXO-based Production General availability
rmg Royal Mint Gold UTXO-based Production Enterprise access
xlm XLM Account Production General availability
xrp XRP Account Production Enterprise access
zec Zcash UTXO-based Production General availability
ae Aeternity ERC20 token Account Production Enterprise access
aion AION ERC20 token Account Production Enterprise access
aoa Aurora ERC20 token Account Production Enterprise access
ana ANA ERC20 token Account Production Enterprise access
ant Aragon ERC20 token Account Production Enterprise access
appc AppCoins ERC20 token Account Production Enterprise access
ast AirSwap ERC20 token Account Production Enterprise access
bat Basic Attention Token ERC20 token Account Production Enterprise access
bbx BBX ERC20 token Account Production Enterprise access
bcap BCAP ERC20 token Account Production Enterprise access
bid Blockbid ERC20 token Account Production Enterprise access
bnt Bancor ERC20 token Account Production Enterprise access
box ContentBox ERC20 token Account Production Enterprise access
bnty Bounty0x ERC20 token Account Production Enterprise access
btt Blocktrade ERC20 token Account Production Enterprise access
brd Bread ERC20 token Account Production Enterprise access
cag Change ERC20 token Account Production Enterprise access
cbc CashBet Coin ERC20 token Account Production Enterprise access
cdt Blox ERC20 token Account Production Enterprise access
cel Celsius ERC20 token Account Production Enterprise access
chsb SwissBorg ERC20 token Account Production Enterprise access
cln Colu Local Network ERC20 token Account Production Enterprise access
cpay Cryptopay ERC20 token Account Production Enterprise access
cvc Civic ERC20 token Account Production Enterprise access
dai Dai ERC20 token Account Production Enterprise access
data Streamr DATACoin ERC20 token Account Production Enterprise access
dent Dent ERC20 token Account Production Enterprise access
dgx Digix ERC20 token Account Production Enterprise access
drv Drive ERC20 token Account Production Enterprise access
echt eChat ERC20 token Account Production Enterprise access
edr Endor Protocol ERC20 token Account Production Enterprise access
egl eGold ERC20 token Account Production Enterprise access
elf Aelf ERC20 token Account Production Enterprise access
enj Enjin Coin ERC20 token Account Production Enterprise access
fmf Formosa Financial ERC20 token Account Production Enterprise access
fun FunFair ERC20 token Account Production Enterprise access
gen DAOstack ERC20 token Account Production Enterprise access
gno Gnosis ERC20 token Account Production Enterprise access
gnt Golem ERC20 token Account Production Enterprise access
gto Gifto ERC20 token Account Production Enterprise access
gusd Gemini Dollar ERC20 token Account Production Enterprise access
hold Hold ERC20 token Account Production Enterprise access
hot Holo ERC20 token Account Production Enterprise access
hst Decision Token ERC20 token Account Production Enterprise access
hyb Hybrid Block ERC20 token Account Production Enterprise access
incx InternationalCryptoX ERC20 token Account Production Enterprise access
ind Indorse ERC20 token Account Production Enterprise access
kin Kin ERC20 token Account Production Enterprise access
knc Kyber Network ERC20 token Account Production Enterprise access
link Chainlink ERC20 token Account Production Enterprise access
lion CoinLion ERC20 token Account Production Enterprise access
lnc Linker Coin ERC20 token Account Production Enterprise access
loom Loom Network ERC20 token Account Production Enterprise access
lrc Loopring ERC20 token Account Production Enterprise access
mdx Mandala ERC20 token Account Production Enterprise access
medx Medibloc ERC20 token Account Production Enterprise access
met Metronome ERC20 token Account Production Enterprise access
meta Metadium ERC20 token Account Production Enterprise access
mfg SyncFab ERC20 token Account Production Enterprise access
mft Mainframe ERC20 token Account Production Enterprise access
mith Mithril ERC20 token Account Production Enterprise access
mkr Maker ERC20 token Account Production Enterprise access
mtcn Multiven ERC20 token Account Production Enterprise access
mtl Metal ERC20 token Account Production Enterprise access
mvl Mass Vehicle Ledger Token Account Production Enterprise access
nas Nebulas ERC20 token Account Production Enterprise access
nexo Nexo ERC20 token Account Production Enterprise access
neu Neumark ERC20 token Account Production Enterprise access
nmr Numeraire ERC20 token Account Production Enterprise access
npxs Pundi X ERC20 token Account Production Enterprise access
omg OmiseGo ERC20 token Account Production Enterprise access
opt OPTin Token ERC20 token Account Production Enterprise access
pax Paxos ERC20 token Account Production Enterprise access
pay TenX ERC20 token Account Production Enterprise access
plc PlusCoin ERC20 token Account Production Enterprise access
pma PumaPay ERC20 token Account Production Enterprise access
poly Polymath ERC20 token Account Production Enterprise access
powr Power Ledger ERC20 token Account Production Enterprise access
ppt Populous ERC20 token Account Production Enterprise access
pro Propy ERC20 token Account Production Enterprise access
qash QASH ERC20 token Account Production Enterprise access
qrl Quantum ERC20 token Account Production Enterprise access
qvt Qvolta ERC20 token Account Production Enterprise access
rby Ruby X ERC20 token Account Production Enterprise access
rdn Raiden Network Token ERC20 token Account Production Enterprise access
reb Regblo ERC20 token Account Production Enterprise access
rebl Rebellious ERC20 token Account Production Enterprise access
rep Augur ERC20 token Account Production Enterprise access
salt Salt ERC20 token Account Production Enterprise access
shk iShook ERC20 token Account Production Enterprise access
snov Snovio ERC20 token Account Production Enterprise access
snt Status Network Token ERC20 token Account Production Enterprise access
srnt Serenity ERC20 token Account Production Enterprise access
storj Storj ERC20 token Account Production Enterprise access
storm Storm ERC20 token Account Production Enterprise access
ten Tokenomy ERC20 token Account Production Enterprise access
tkx Tokenize ERC20 token Account Production Enterprise access
tnt Tierion ERC20 token Account Production Enterprise access
trst WeTrust ERC20 token Account Production Enterprise access
tusd TrueUSD ERC20 token Account Production Enterprise access
ukg UnikoinGold ERC20 token Account Production Enterprise access
upp Sentinel Protocol ERC20 token Account Production Enterprise access
uqc Uquid Coin Erc20 token Account Production Enterprise access
wax Worldwide Asset eXchange ERC20 token Account Production Enterprise access
wtc WaltonChain ERC20 token Account Production Enterprise access
xrl Rialto ERC20 token Account Production Enterprise access
zco Zebi Coin 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
tdash Dash Testnet UTXO-based Test Beta
teth Ethereum Kovan Testnet Account Test Enterprise access
terc Ethereum ERC20 Token Testnet Account Test Enterprise access
tltc Litecoin Testnet UTXO-based Test General availability
trmg Royal Mint Gold Testnet UTXO-based Test Enterprise access
txlm XLM Testnet Account Test General availability
txrp XRP Testnet Account Test Enterprise access
tzec Zcash Testnet UTXO-based Test Enterprise 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.

BitGo UTXO Library

The BitGo UTXO Library (bitgo-utxo-lib) is an open source library for UTXO transaction building and does not require a BitGo account or the BitGo SDK to be used. The bitgo-utxo-lib allows any developer working with UTXO-based blockchains to easily build and sign their own transactions.

Learn more about the BitGo UTXO Library here.

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). 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
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 XRP 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. Creates the backup keychain locally on the machine.
  3. Uploads the encrypted user keychain and public backup keychain.
  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
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
custodialWalletId ID of the cold custodial wallet linked to this wallet (only for custodial hot wallets)
custodialWallet the full wallet object information for the cold custodial wallet (only for custodial hot wallets)
customerWalletId ID of the hot custodial wallet linked to this custodial cold wallet (only for custodial cold wallets)
billingEnterprise ID of the customer enterprise this wallet belongs to (only for custodial cold wallets)

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 No Change threshold for erc20 forwarder (e.g. { [tokenName]: threshold }) (only coin teth)
coinSpecific Object No Update coin-specific properties (e.g. { txlm: { stellarUsername: 'test' } }) (currently only supported for Stellar)

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",
      "normalizedTxHash": "e0e4bada8332ed254c20c4c1d2c25e5f13386509e7ac21d005a169925d07889a",
      "height": 1122442,
      "date": "2017-05-12T21:05:28.130Z",
      "confirmations": 1,
      "type": "receive",
      "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.
includeHex Boolean No Include transaction hex (defaults to false, size of hex can be large). Final field will be called hex. Account based coins do not have transaction hex.
searchLabel String No Searches over the transfers’ memo, value and address fields. Value must be passed as the base units (satoshis, wei, etc).
type String No Possible values: send or receive
searchLabel String No Text to search in addresses, comments or txids.

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,
    "type": "receive",
    "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 (may be approximate for ETH and other coins where amounts in base units can exceed 2^53 - 1)
valueString Digital currency value of the transfer (string representation)
instant True if the the transfer was sent using instant transaction method (like Dash InstantSend)

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,
    "type": "receive",
    "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. In Coin-Specific Implementation see a coin’s section for its default chain and see “UTXO-based Coins” for valid chain codes.
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
count Number No Number of new addresses to create (maximum 250). If count is more than one, an object with an “addresses” property will be returned. See example response below. (BitGoJS only)

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

Bulk Creation Response (BitGoJS only)

If the count parameter was specified, then an object containing an array of address objects will be returned.

Field Description
addresses An array of address objects, each with properties as shown in the table above

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. See “UTXO-based Coins” section of Coin-Specific Implementation for valid chain codes.
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. See “UTXO-based Coins” section of Coin-Specific Implementation for valid chain codes.
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:

{
  "transfer": {
    "id":"5bb62629ba487fef8c7869e167569d4f",
    "coin":"tltc",
    "wallet":"5bb624eeda32ceff8b3216f7e0faae23",
    "txid":"095eb941fda5e5f02de17c90091c615dceeb299a2e10b59640246e69112768b6",
    "height":999999999,
    "date":"2018-10-04T14:39:38.023Z",
    "type":"send",
    "value":-4488,
    "valueString":"-4488",
    "feeString":"4488",
    "payGoFee":0,
    "payGoFeeString":"0",
    "usd":-0.0026272752,
    "usdRate":58.54,
    "state":"signed",
    "instant":false,
    "tags":[  
      "5bb624eeda32ceff8b3216f7e0faae23"
    ],
    "history":[  
      {  
        "date":"2018-10-04T14:39:38.022Z",
        "action":"signed"
      },
      {  
        "date":"2018-10-04T14:39:37.605Z",
        "action":"created"
      }
    ],
    "vSize":374,
    "nSegwitInputs":0,
    "entries":[  
      {  
        "address":"QZDpAmqDdSiCQnP7duX7d7knXPgzKH6Ka8",
        "wallet":"5bb624eeda32ceff8b3216f7e0faae23",
        "value":-500000000,
        "valueString":"-500000000"
      },
      {  
        "address":"QVtq6SiPztA7UxnUx4sE3DL5MBUSqbDtZp",
        "wallet":"5bb624eeda32ceff8b3216f7e0faae23",
        "value":498995512,
        "valueString":"498995512",
        "isChange":true,
        "isPayGo":false
      },
      {  
        "address":"QcPWF6R6nkdE6ouCVbQhpp7zMx6rv9L7w9",
        "wallet":"5bb624eeda32ceff8b3216f7e0faae23",
        "value":1000000,
        "valueString":"1000000",
        "isChange":true,
        "isPayGo":false
      }
    ],
    "signedTime": "2018-10-04T14:39:38.022Z",
    "createdTime": "2018-10-04T14:39:37.605Z"
  },
  "txid": "095eb941fda5e5f02de17c90091c615dceeb299a2e10b59640246e69112768b6",
  "tx": "010000001945f506cad0d2b8be8e36ed5d4dbb7502cd3a2822d01f7afe411f9773c6fd381cad0 ...",
  "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/String Yes All Amount to be sent to the recipient. Should be an Integer for all coin types except Ethereum, ERC20 tokens, and XRP for which it should be a String.
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
maxFeeRate Integer No All UTXO-based Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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 String No All An optional unique identifier provided by the customer during tx creation for tracking purposes
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.
data String No Ethereum Hex data to send to recipient with transaction (can be used to make contract calls)
instant Boolean No All Set to true to use instant tranasaction method (like Dash InstantSend) if available

Response

Returns the newly created transaction description object.

Field Description
transfer The Transfer object
txid Blockchain transaction ID
tx Transaction hex
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}, …] The amount should be an Integer for all coin types except Ethereum, ERC20 tokens, and XRP for which it should be a String.
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
maxFeeRate Integer No All UTXO-based Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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 String No All An optional unique identifier provided by the customer during tx creation for tracking purposes
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 Required Value
address String Yes Destination address
amount Integer or String Yes Satoshis to send in transaction
gasPrice Integer No Custom gas price to be used for sending the transaction (only for Ethereum)
data String No Ethereum

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.
labelContains String No Text to search in the wallet label case insensitively.
segwit Boolean No DEPRECATED. Mutually exclusive with chains. Returns only p2shP2wsh addresses on true. Returns only p2sh addresses on false. Returns all addresses if undefined and chains is also undefined. Equivalent to passing 10 and 11 as the only value in chains on true, 0 and 1 on false.
chains Array No Replaces segwit. Mutually exclusive with segwit. Returns only addresses of the chains passed. Returns all addresses if undefined and segwit is also undefined. See “UTXO-based Coins” section of Coin-Specific Implementation for valid chain codes.

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

Get First Pending Transaction

wallet.getFirstPendingTransaction()
.then(function(transactionData) {
  // print the transaction metadata
  console.dir(transactionData);
})

enterprise.getFirstPendingTransaction()
.then(function(transactionData) {
  // print the transaction metadata
  console.dir(transactionData);
})
WALLET="585c51a5df8380e0e3082e46"

curl \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/teth/tx/pending/first

The response will look like this:

{
  "walletId": "585c51a5df8380e0e3082e46",
  "txid": "0x023d55519e14d6243e614273ca779d2e45c6bccea30cfb32cd859b8f93291c69",
  "tx": "f901ec81c38504a817c8008307a120949e342e458e910017e538ca5868318d06a7fac0d240b90a8439425215000000000000000000000000406243ba15759c5b73bf8ed97bb037037619c5df00000000000000000000000000000000000000000000000000038d7ea4c6800000000000000000000000000000000000000000000000000000000000000000c0000000000000000000000000000000000000000000000000000000005a7e5ad1000000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000414eec57fea039bdcf8d9346a36f77d799878aa3c9c97ec02d34678c8eca038e015c646ed7a8bb7501fe0c1422dc395f7434311daa1a21f9cbe912b46fe5606bf41c000000000000000000000000000000000000000000000000000000000000001ba09c427a0852c3cc06e5b7a67e51ba9d41c9efa66acf6cea28f814e3048a6e92efa03a1ba9ef435a21d473cf7cc4c2e55eb860481c36c1310e9076d02b4b88226f51",
  "coin": "teth",
  "gasPrice": 1000000000000000000
}

This API call will retrieve the oldest pending transaction that has not been confirmed yet by the blockchain. The oldest pending transaction can be found either for a wallet or an enterprise. For ETH or ERC20 tokens, it will also include the Gas Price attached to that transaction

This may be useful for getting the information necessary to raise the fee rate on transactions that are slow to confirm.

HTTP Request

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

Query Parameters

Parameter Type Required Description
walletId String No The ID of the wallet to fetch the transaction from
enterpriseId String No The ID of the enterprise to fetch the transaction from

Response

Returns metadata about the transaction

Field Description
walletId The ID of the wallet that sent the transaction
txid Transaction Hash
tx Transaction Hex
coin The coin or token for the transaction
gasPrice [if ETH / ERC20] the gasPrice (in Wei) attached to the transaction

Change Fee on Transaction

const txid = "cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93";
const fee = 1000000000000000000;

wallet.changeFee({txid: txid, fee: fee})
.then(function(newTxHash) {
  // print the txHash of the updated transaction
  console.dir(newTxHash);
})
WALLET="585c51a5df8380e0e3082e46"
TXID="cc21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93"
FEE=1000000000000000000

curl -X POST \
-H "Content-Type: application/json" \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d "{ \"txid\": \"$TXID\", \"fee\": \"$FEE\" }" \
https://test.bitgo.com/api/v2/teth/wallet/$WALLET/tx/changeFee

The response will look like this:

{
  "txid": "dd21875eb303e5efda9056585d68c79b10345585213a62c9c1a7bc331dfd5d93"
}

This API call will change the fee rate on the transaction specified by transaction ID in the request. Currently, this feature only applies to ETH and ERC20 tokens, requires the fee to be increased by a minimum amount of 10 Gwei, and at least one hour passed since the transaction was first sent.

This is useful to raise the fee rate on transactions that are slow to confirm. This will not work with transactions that are already in a block.

HTTP Request

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

Query Parameters

Parameter Type Required Description
walletId String Yes The ID of the wallet to fetch the transaction from
txid String Yes The transaction hash for the transaction to change
fee Integer Yes The new fee rate to give the selected transaction

Response

Returns the txid of the updated transaction

Field Description
txid The new transaction hash

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
segwit Boolean No DEPRECATED. Mutually exclusive with chains. Returns only p2shP2wsh unspents on true. Returns only p2sh unspents on false. Returns all unspents if undefined and chains is also undefined. Equivalent to passing 10 and 11 as the only value in chains on true, 0 and 1 on false.
chains Array No Replaces segwit. Mutually exclusive with segwit. Returns only unspents of the chains passed. Returns all unspents if undefined and segwit is also undefined. See “UTXO-based Coins” section of Coin-Specific Implementation for valid chain codes.

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
maxFeeRate Integer No Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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
maxFeeRate Integer No Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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.
maxFeeRate Integer No All UTXO-based Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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
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

Query Parameters

Parameter Type Required Coins Description
segwit Boolean No All UTXO-based DEPRECATED. Please use addressType body parameter instead. This is the equivalent of { addressType: "p2shP2wsh" }. Mutually exclusive with addressType.

Body Parameters

Parameter Type Required Coins Description
recipients Array Yes All 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
maxFeeRate Integer No All UTXO-based Custom upper limit for fee rate in satoshis/kB. Delimits dynamic fee rates derived from numBlocks and default fee rates.
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.
memo Object No XLM Optional memo for a transaction (e.g. { value: '1', type: 'id' }) See Stellar specs
addressType String No All UTXO-based The type of address to create for change. One of p2sh, p2shP2wsh, and p2wsh. Case-sensitive. Mutually exclusive with segwit query parameter.

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.)
data String No [Ethereum Only] Hex data to send to recipient with transaction (can be used to make contract calls)

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

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 numeric 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 XRP 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 Coins Description
txPrebuild Object Yes All The transaction description object, output from 'Build Transaction’
prv String No All The user private key
coldDerivationSeed String No All The seed used to derive the signing key
keychain Object No All The user keychain with an encryptedPrv property
walletPassphrase String No All Passphrase to decrypt the user keychain
key Object No All alias for 'keychain’
recipients Array Yes ETH Array of objects describing the recipients. See buildTransaction for more detail

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 transaction

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

All Transactions

An all transactions rule will be triggered on any outgoing transaction.

Type value: allTx

Condition values:

None

Action value:

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

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: coinAddressWhitelist

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: coinAddressBlacklist

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)
wallet ID of the wallet associated with the webhook event, if this is a wallet webhook
hash Transaction ID, if this is a transfer webhook
transfer Transfer ID, a BitGo generated id of the transfer. This can be used to lookup more details about the transaction.
coin The coin of the transaction e.g “btc” or “eth”. Can also be a token name.
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
coin On transfer webhook, this is the transfer coin

Webhook HTTP response example

{
  "hash":"daca53bc7f649....bbaa29d64012a1393cbff2",
  "transfer":"5b58cd14....25ea6b99",
  "coin":"tbtc",
  "type":"transfer",
  "state":"confirmed",
  "wallet":"5ade....f45f740"
}

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",
  "allToken": false,
  "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 10 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.
allToken Boolean No Alltoken flag can only apply to ETH or ERC20 tokens webhook. This is a generic type of webhook. If allToken flag set to true, webhooks will fire on all ETH or ERC20 transactions. By default, allToken param is set to false. See the ERC20 section for more details.

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.
allToken AllToken webhook

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.

UTXO-based Coins

Generating addresses

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

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

Change addresses: /0/0/chainCode/n

Where chainCode represents the type of address according to the table below:

Chain Code Address Type Deposit or Change
0 Pay to Script Hash (P2SH) Deposit
1 Pay to Script Hash (P2SH) Change
10 Wrapped Segwit (P2SH-P2WSH) Deposit
11 Wrapped Segwit (P2SH-P2WSH) Change
20 Bech32/Native Segwit/Pay to Witness Script Hash (P2WSH) Deposit
21 Bech32/Native Segwit/Pay to Witness Script Hash (P2WSH) Change

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

See “Generating addresses” section of “UTXO-based” coins above. Bitcoin defaults to chain 10.

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

See “Generating addresses” section of “UTXO-based” coins above. Note that Bitcoin Cash does not support segwit. Bitcoin Cash defaults to chain 0.

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.

Generating addresses

See “Generating addresses” section of “UTXO-based” coins above. Bitcoin Gold defaults to chain 10.

Dash

Dash can be accessed with the following coin types

Environment Coin Type Faucet
Dash Production dash
Dash Testnet tdash http://test.faucet.masternode.io/

Wallet construction

bitgo.coin('tdash').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/tdash/wallet/generate

For Dash, 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('tdash').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/tdash/wallet/$WALLET/address

See “Generating addresses” section of “UTXO-based” coins above. Note that Dash does not support segwit. Dash defaults to chain 0.

Balances

Just as with Bitcoin, Dash’s unit subdivisibility goes up to 100,000,000 units called Duff, 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.

Dash InstantSend

Dash InstantSend is a Dash specific extension allowing instant on-chain payments. It works by committing to a transaction by a majority of Dash Masternodes. This way committed transaction can’t be double-spent by the sender and the receiver can potentially consider transaction to be settled without waiting for any on-chain confirmations. For more information on InstantSend please refer to Official Dash InstantSend documention

Dash InstantSend receiving and sending support is exposed through instant flag on Transfer objects and sending APIs.

Dash InstantSend transaction require higher than normal fees. Such fees will be automatically calculated and enforced by transaction building / sending APIs, when instant flag is set to true.

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

See “Generating addresses” section of “UTXO-based” coins above. Litecoin defaults to chain 0.

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.

Stellar

Stellar can be accessed with the following coin types

Environment Coin Type Faucet
Stellar Production xlm
Stellar Testnet txlm https://www.stellar.org/laboratory/#account-creator?network=test

Wallet construction

bitgo.coin('txlm').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/txlm/wallet/generate

The creation of Stellar wallets is similar to XRP and Ethereum’s, in that wallet creation requires interaction with the network to complete. For a Stellar wallet to be initialized, a funding transaction needs to be sent to the wallet’s address. When BitGo detects the funding transaction, another transaction is sent automatically to set up the signers and the home domain of the account.

Stellar accounts must maintain a minimum balance of lumens. This reserve is calculated using the base reserve, which currently is 0.5 XLM. The calculation is: (2 + # of co-signers) × base reserve = 2.5 XLM. The base fee and base reserve values are provided by the latest ledger. The minimum funding amount required is obtained by adding the account reserve plus initialization fees (i.e. 2.5 XLM + 0.00005 XLM = 2.50005 XLM).

Required reserve

curl -X GET \
-H "Authorization: Bearer $ACCESS_TOKEN" \
https://test.bitgo.com/api/v2/txlm/requiredReserve

Fetch information about reserve requirements for an account.

HTTP Request

GET /api/v2/:coin/requiredReserve

Response

Field Description
baseFee base fee used in transaction fees.
baseReserve base reserve used in minimum account balances.
reserve minimum account balance, calculated using base reserve.
minimumFunding minimum funding balance, calculated using reserve and base fee.
height the height of the block that provides the base values.

Generating addresses

bitgo.coin('txlm').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/txlm/wallet/$WALLET/address

The BIP32 standard cannot be taken advantage of, and hence generated XLM addresses differ only in their sequentially incrementing memo id components. The memo type used by BitGo is MEMO_ID: a 64-bit unsigned numeric string. Whenever a new address is created, the incremented memoId and the rootAddress are returned in the address’ coinSpecific property.

Balances

Although Stellar supports transacting multiple types of assets, at this moment BitGo only supports the native asset type, called Lumen (XLM).

The smallest amount unit for Stellar is called “stroop”. One stroop equals 0.0000001 XLM.

Transactions

Stellar uses an account-based model, similar to XRP. Additionally, due to the use of memo, Stellar transactions only support one input and one output.

Currently, the base fee is 100 stroops (0.00001 XLM). The minimum fee for a transaction is calculated as (# of operations × base fee).

Federation

BitGo supports the Stellar federation protocol that matches Stellar addresses to Stellar accounts. Additionally, the BitGo federation server provides the next memo id for the wallet. Stellar accounts can be looked up by their Stellar address, or their Account ID.

Users can create email-like usernames for their Stellar wallets. A Stellar address is conformed by the Stellar username and the account’s home domain (e.g. test*bitgo.com). Stellar usernames are unique, and only accept lower-case letters, numbers and the characters: -_.+@. The home domain is automatically set to bitgo.com. A Stellar username can only be set once the wallet has been initialized, and it cannot be changed. See Update Wallet.

XRP (formerly known as Ripple)

XRP can be accessed with the following coin types

Environment Coin Type Faucet
XRP Production xrp
XRP 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 XRP wallets is like Ethereum’s, in that wallet creation requires interaction with the blockchain (or the XRP Ledger) to complete. When you create an XRP wallet, BitGo sends 4 initialization transactions on the XRP 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 XRP network the wallet’s receive address be not be visible through the API. This is to protect users against accidentally sending to an XRP 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 XRP 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 XRP 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 XRP and Bitcoin is that XRP has no concept of UTXOs, and operates on an account-based model instead. Additionally, XRP 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 XRP addresses differ only in their sequentially incrementing destination tag components.

Balances

Though just like RMG, a single XRP is divisible 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 numbers.

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

Zcash

BitGo supports transparent transactions with the latest Zcash network upgrade, Sapling. This means only Sapling compatible transactions will be generated and read by BitGo.

Zcash can be accessed with the following coin types:

Environment Coin Type Faucet
Zcash Production zec
Zcash Testnet tzec https://faucet.testnet.z.cash/

Notes on shielded transactions

Only transparent addresses are supported by BitGo wallets which limits the type of transactions allowed. A Zcash BitGo wallet can receive funds from a transparent or a shielded address but can only send funds to a transparent address.

Wallet construction

bitgo.coin('tzec').wallets()
.generateWallet({ label: 'My Test TZec Wallet', passphrase: 'secretpassphrase1a5df8380e0e30' })
.then(function(wallet) {
  // print the new wallet
  console.dir(wallet);
});
LABEL="My TZec 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/tzec/wallet/generate

Generating addresses

bitgo.coin('tzec').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/tzec/wallet/$WALLET/address

See “Generating addresses” section of “UTXO-based” coins above. Note that Zcash does not support segwit. Zcash defaults to chain 0.

Balances

Just as with Bitcoin, Zcash’s unit subdivisibility goes up to 100,000,000 zatoshis with a capped supply of 21,000,000 ZECs, 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.

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 ae https://etherscan.io/token/0x5ca9a71b1d01849c0a95490cc00559717fcf0d1d
Ethereum Mainnet aion https://etherscan.io/token/0x4CEdA7906a5Ed2179785Cd3A40A69ee8bc99C466
Ethereum Mainnet ana https://etherscan.io/token/0xfafd51641ab09dff163cd04d2eb6b7865eb83f53
Ethereum Mainnet aoa https://etherscan.io/token/0x9ab165d795019b6d8b3e971dda91071421305e5a
Ethereum Mainnet ant https://etherscan.io/token/0x960b236A07cf122663c4303350609A66A7B288C0
Ethereum Mainnet appc https://etherscan.io/token/0x1a7a8bd9106f2b8d977e08582dc7d24c723ab0db
Ethereum Mainnet ast https://etherscan.io/token/0x27054b13b1b798b345b591a4d22e6562d47ea75a
Ethereum Mainnet bat https://etherscan.io/token/0x0d8775f648430679a709e98d2b0cb6250d2887ef
Ethereum Mainnet bbx https://etherscan.io/token/0x71529cea068e3785efd4f18aaf59a6cb82b7e5cb
Ethereum Mainnet bcap https://etherscan.io/token/0x1f41e42d0a9e3c0dd3ba15b527342783b43200a9
Ethereum Mainnet bid https://etherscan.io/token/0xf1f64f6b8e17dd68c1db10b0eed3d2541a6c09ab
Ethereum Mainnet bnt https://etherscan.io/token/0x1f573d6fb3f13d689ff844b4ce37794d79a7ff1c
Ethereum Mainnet bnty https://etherscan.io/token/0xd2d6158683aee4cc838067727209a0aaf4359de3
Ethereum Mainnet box https://etherscan.io/token/0x63f584FA56E60e4D0fE8802b27C7e6E3b33E007f
Ethereum Mainnet btt https://etherscan.io/token/0xFA456Cf55250A839088b27EE32A424d7DAcB54Ff
Ethereum Mainnet brd https://etherscan.io/token/0x558ec3152e2eb2174905cd19aea4e34a23de9ad6
Ethereum Mainnet cag https://etherscan.io/token/0x7d4b8cce0591c9044a22ee543533b72e976e36c3
Ethereum Mainnet cbc https://etherscan.io/token/0x26DB5439F651CAF491A87d48799dA81F191bDB6b
Ethereum Mainnet cdt https://etherscan.io/token/0x177d39ac676ed1c67a2b268ad7f1e58826e5b0af
Ethereum Mainnet cel https://etherscan.io/token/0xaaaebe6fe48e54f431b0c390cfaf0b017d09d42d
Ethereum Mainnet chsb https://etherscan.io/token/0xba9d4199fab4f26efe3551d490e3821486f135ba
Ethereum Mainnet cln https://etherscan.io/token/0x4162178b78d6985480a308b2190ee5517460406d
Ethereum Mainnet cpay https://etherscan.io/token/0x0Ebb614204E47c09B6C3FeB9AAeCad8EE060E23E
Ethereum Mainnet cvc https://etherscan.io/token/0x41e5560054824ea6b0732e656e3ad64e20e94e45
Ethereum Mainnet dai https://etherscan.io/token/0x89d24a6b4ccb1b6faa2625fe562bdd9a23260359
Ethereum Mainnet data https://etherscan.io/token/0x0cf0ee63788a0849fe5297f3407f701e122cc023
Ethereum Mainnet dent https://etherscan.io/token/0x3597bfd533a99c9aa083587b074434e61eb0a258
Ethereum Mainnet dgx https://etherscan.io/token/0x4f3afec4e5a3f2a6a1a411def7d7dfe50ee057bf
Ethereum Mainnet drv https://etherscan.io/token/0x0b9d89a71bdabd231d4d497b7b7b879740d739c4
Ethereum Mainnet echt https://etherscan.io/token/0x1aadead0d2e0b6d888ae1d73b11db65a8447634a
Ethereum Mainnet edr https://etherscan.io/token/0xc528c28fec0a90c083328bc45f587ee215760a0f
Ethereum Mainnet egl https://etherscan.io/token/0x8f00458479ea850f584ed82881421f9d9eac6cb1
Ethereum Mainnet elf https://etherscan.io/token/0xbf2179859fc6D5BEE9Bf9158632Dc51678a4100e
Ethereum Mainnet enj https://etherscan.io/token/0xf629cbd94d3791c9250152bd8dfbdf380e2a3b9c
Ethereum Mainnet fmf https://etherscan.io/token/0xb4d0fdfc8497aef97d3c2892ae682ee06064a2bc
Ethereum Mainnet fun https://etherscan.io/token/0x419d0d8bdd9af5e606ae2232ed285aff190e711b
Ethereum Mainnet hold https://etherscan.io/token/0xD6e1401a079922469e9b965Cb090ea6fF64C6839
Ethereum Mainnet gen https://etherscan.io/token/0x543ff227f64aa17ea132bf9886cab5db55dcaddf
Ethereum Mainnet gno https://etherscan.io/token/0x6810e776880c02933d47db1b9fc05908e5386b96
Ethereum Mainnet gnt https://etherscan.io/token/0xa74476443119A942dE498590Fe1f2454d7D4aC0d
Ethereum Mainnet gto https://etherscan.io/token/0xc5bbae50781be1669306b9e001eff57a2957b09d
Ethereum Mainnet gusd https://etherscan.io/token/0x056fd409e1d7a124bd7017459dfea2f387b6d5cd
Ethereum Mainnet hot https://etherscan.io/token/0x6c6ee5e31d828de241282b9606c8e98ea48526e2
Ethereum Mainnet hst https://etherscan.io/token/0x554c20b7c486beee439277b4540a434566dc4c02
Ethereum Mainnet hyb https://etherscan.io/token/0x6059f55751603ead7dc6d280ad83a7b33d837c90
Ethereum Mainnet incx https://etherscan.io/token/0xa984a92731c088f1ea4d53b71a2565a399f7d8d5
Ethereum Mainnet ind https://etherscan.io/token/0xf8e386eda857484f5a12e4b5daa9984e06e73705
Ethereum Mainnet kin https://etherscan.io/token/0x818fc6c2ec5986bc6e2cbf00939d90556ab12ce5
Ethereum Mainnet knc https://etherscan.io/token/0xdd974d5c2e2928dea5f71b9825b8b646686bd200
Ethereum Mainnet lion https://etherscan.io/token/0x2167fb82309cf76513e83b25123f8b0559d6b48f
Ethereum Mainnet link https://etherscan.io/token/0x514910771af9ca656af840dff83e8264ecf986ca
Ethereum Mainnet lnc https://etherscan.io/token/0x6BEB418Fc6E1958204aC8baddCf109B8E9694966
Ethereum Mainnet loom https://etherscan.io/token/0xa4e8c3ec456107ea67d3075bf9e3df3a75823db0
Ethereum Mainnet lrc https://etherscan.io/token/0xef68e7c694f40c8202821edf525de3782458639f
Ethereum Mainnet mdx https://etherscan.io/token/0x9d03393d297e42c135625d450c814892505f1a84
Ethereum Mainnet medx https://etherscan.io/token/0xfd1e80508f243e64ce234ea88a5fd2827c71d4b7
Ethereum Mainnet met https://etherscan.io/token/0xa3d58c4e56fedcae3a7c43a725aee9a71f0ece4e
Ethereum Mainnet meta https://etherscan.io/token/0xde2f7766c8bf14ca67193128535e5c7454f8387c
Ethereum Mainnet mfg https://etherscan.io/token/0x6710c63432a2de02954fc0f851db07146a6c0312
Ethereum Mainnet mft https://etherscan.io/token/0xdf2c7238198ad8b389666574f2d8bc411a4b7428
Ethereum Mainnet mith https://etherscan.io/token/0x3893b9422cd5d70a81edeffe3d5a1c6a978310bb
Ethereum Mainnet mkr https://etherscan.io/token/0x9f8f72aa9304c8b593d555f12ef6589cc3a579a2
Ethereum Mainnet mtcn https://etherscan.io/token/0xf6117cc92d7247f605f11d4c942f0feda3399cb5
Ethereum Mainnet mtl https://etherscan.io/token/0xF433089366899D83a9f26A773D59ec7eCF30355e
Ethereum Mainnet mvl https://etherscan.io/token/0xa849eaae994fb86afa73382e9bd88c2b6b18dc71
Ethereum Mainnet nas https://etherscan.io/token/0x5d65D971895Edc438f465c17DB6992698a52318D
Ethereum Mainnet nexo https://etherscan.io/token/0xb62132e35a6c13ee1ee0f84dc5d40bad8d815206
Ethereum Mainnet neu https://etherscan.io/token/0xa823e6722006afe99e91c30ff5295052fe6b8e32
Ethereum Mainnet nmr https://etherscan.io/token/0x1776e1F26f98b1A5dF9cD347953a26dd3Cb46671
Ethereum Mainnet npxs https://etherscan.io/token/0xa15c7ebe1f07caf6bff097d8a589fb8ac49ae5b3
Ethereum Mainnet omg https://etherscan.io/token/0xd26114cd6EE289AccF82350c8d8487fedB8A0C07
Ethereum Mainnet opt https://etherscan.io/token/0xde8893346ce8052a02606b62d13b142648e062dd
Ethereum Mainnet pay https://etherscan.io/token/0xB97048628DB6B661D4C2aA833e95Dbe1A905B280
Ethereum Mainnet pax https://etherscan.io/token/0x8e870d67f660d95d5be530380d0ec0bd388289e1
Ethereum Mainnet plc https://etherscan.io/token/0xdf99c7f9e0eadd71057a801055da810985df38bd
Ethereum Mainnet pma https://etherscan.io/token/0x846c66cf71c43f80403b51fe3906b3599d63336f
Ethereum Mainnet poly https://etherscan.io/token/0x9992ec3cf6a55b00978cddf2b27bc6882d88d1ec
Ethereum Mainnet powr https://etherscan.io/token/0x595832f8fc6bf59c85c527fec3740a1b7a361269
Ethereum Mainnet ppt https://etherscan.io/token/0xd4fa1460f537bb9085d22c7bccb5dd450ef28e3a
Ethereum Mainnet pro https://etherscan.io/token/0x9041fe5b3fdea0f5e4afdc17e75180738d877a01
Ethereum Mainnet qash https://etherscan.io/token/0x618e75ac90b12c6049ba3b27f5d5f8651b0037f6
Ethereum Mainnet qrl https://etherscan.io/token/0x697beac28b09e122c4332d163985e8a73121b97f
Ethereum Mainnet qvt https://etherscan.io/token/0x1183f92a5624d68e85ffb9170f16bf0443b4c242
Ethereum Mainnet rdn https://etherscan.io/token/0x255aa6df07540cb5d3d297f0d0d4d84cb52bc8e6
Ethereum Mainnet reb https://etherscan.io/token/0x61383ac89988b498df5363050ff07fe5c52ecdda
Ethereum Mainnet rebl https://etherscan.io/token/0x5f53f7a8075614b699baad0bc2c899f4bad8fbbf
Ethereum Mainnet rep https://etherscan.io/token/0x1985365e9f78359a9b6ad760e32412f4a445e862
Ethereum Mainnet rby https://etherscan.io/token/0xf7705dee19a63e0bc1a240f723c5c0f570c78572
Ethereum Mainnet salt https://etherscan.io/token/0x4156D3342D5c385a87D264F90653733592000581
Ethereum Mainnet shk https://etherscan.io/token/0xebe4a49df7885d015329c919bf43e6460a858f1e
Ethereum Mainnet snov https://etherscan.io/token/0xbdc5bac39dbe132b1e030e898ae3830017d7d969
Ethereum Mainnet snt https://etherscan.io/token/0x744d70fdbe2ba4cf95131626614a1763df805b9e
Ethereum Mainnet srnt https://etherscan.io/token/0xbc7942054f77b82e8a71ace170e4b00ebae67eb6
Ethereum Mainnet storj https://etherscan.io/token/0xb64ef51c888972c908cfacf59b47c1afbc0ab8ac
Ethereum Mainnet storm https://etherscan.io/token/0xd0a4b8946cb52f0661273bfbc6fd0e0c75fc6433
Ethereum Mainnet ten https://etherscan.io/token/0xdd16ec0f66e54d453e6756713e533355989040e4
Ethereum Mainnet tnt https://etherscan.io/token/0x08f5a9235b08173b7569f83645d2c7fb55e8ccd8
Ethereum Mainnet trst https://etherscan.io/token/0xcb94be6f13a1182e4a4b6140cb7bf2025d28e41b
Ethereum Mainnet tkx https://etherscan.io/token/0x667102bd3413bfeaa3dffb48fa8288819e480a88
Ethereum Mainnet tusd https://etherscan.io/token/0x8dd5fbce2f6a956c3022ba3663759011dd51e73e
Ethereum Mainnet ukg https://etherscan.io/token/0x24692791bc444c5cd0b81e3cbcaba4b04acd1f3b
Ethereum Mainnet upp https://etherscan.io/token/0xc86d054809623432210c107af2e3f619dcfbf652
Ethereum Mainnet uqc https://etherscan.io/token/0xd01db73e047855efb414e6202098c4be4cd2423b
Ethereum Mainnet usdc https://etherscan.io/token/0xa0b86991c6218b36c1d19d4a2e9eb0ce3606eb48
Ethereum Mainnet wax https://etherscan.io/token/0x39Bb259F66E1C59d5ABEF88375979b4D20D98022
Ethereum Mainnet wtc https://etherscan.io/token/0xb7cb1c96db6b22b0d3d9536e0108d062bd488f74
Ethereum Mainnet xrl https://etherscan.io/token/0xb24754be79281553dc1adc160ddf5cd9b74361a4
Ethereum Mainnet zco https://etherscan.io/token/0x2008e3057bd734e10ad13c9eae45ff132abc1722
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
  7. Add Wallet Webhook

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.

ERC20 Tokens Webhooks

By setting the “allTokens” parameter to true, a generic webhook is created which will trigger on all ERC20 token and ETH transactions. It will send an http request to your webhook url and specify whether it is Ethereum or token using the field “coin”. Here’s an example response for a test token called “terc”.

{“hash”:“0x3e00ae17961d3d42ae722085904ba84e63a32b005ff46afff28b7c9c76f63291”, “transfer”:“5b612d25c9067f2a1db11a15f165989e”, “coin”:“terc”, “type”:“transfer”, “state”:“confirmed”, “wallet”:“5a13adcab70f2c284fdd9682db5e6d64”}

To get additional details about this transfer, you will then need to get the transfer details using the token name and transfer id. For the above transfer you’d need to call the following URL /terc/wallet/5a13adcab70f2c284fdd9682db5e6d64/transfer/5b612d25c9067f2a1db11a15f165989e to check the amount transferred and other details.

Note: A transaction that sends both Ethereum and an ERC20 token (or multiple token types) will cause one webhook notification for each. A transaction that sends a token not supported by BitGo (those listed above) will not cause a webhook notification.

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.

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 estimated fee for a transaction. For UTXO-based coins the fee is per-kilobyte, and you may include a parameter to specify the target number of blocks until confirmation. For account-based coins, the response is the estimated fee for a single transaction. Numbers are denominated in the smallest divisible units of the given coin.

HTTP Request

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

Example response (UTXO coin)

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

Example response (Account coin)

{ 
  "feeEstimate": "200"
}

Parameters

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

Response

Field Coins Description
feePerKb UTXO The estimated fee rate per kilobyte for the requested target number of blocks. Numbers are in the coin’s smallest divisible unit.
numBlocks UTXO The target number of blocks requested for the estimate.
feeEstimate Account The estimated fee for a single transaction. Number is in the coin’s smallest divisible unit and represented as a String

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.