Overview

You can generate or manually create multisignature and MPC wallets with BitGo. Once created, you can configure security policies for your wallets, dictating how transactions can occur.

Generate Wallets

Create a self-custody wallet and keys all in one step. When you generate a wallet, BitGo does the following: * Creates a user keychain locally on your machine and uploads an encrypted key, using the provided passphrase (skipped if you supply a userKey). * Creates a backup keychain locally on your machine and uploads the public key. * Creates a BitGo keychain on a BitGo hardware-security module (HSM) and a backup key if backupXpubProvider is set to true. * Creates a wallet on the blockchain with these 3 public keys.

Manually Create Wallets

Create a custody wallet or a self-custody, hot or cold, wallet. You must create your own keys prior to manually creating a self-custody wallet.

Prerequisites

Cookbooks

Need just the steps? Expand a cookbook below to get started:

Create Wallets (MPC)Open Cookbook Create Wallets (Multisignature)Open Cookbook

Create Wallet

Endpoints:

export BITGO_EXPRESS_HOST="<YOUR_LOCAL_HOST>"
export COIN="<ASSET_ID>"
export ACCESS_TOKEN="<YOUR_ACCESS_TOKEN>"
export ENTERPRISE="<YOUR_ENTERPRISE_ID>"
export PASSPHRASE="<YOUR_BITGO_LOGIN_PASSPHRASE>"
export LABEL="<YOUR_WALLET_NAME>"

curl -X POST \
  http://$BITGO_EXPRESS_HOST/api/v2/$COIN/wallet/generate \
  -H 'Content-Type: application/json' \
  -H "Authorization: Bearer $ACCESS_TOKEN" \
  -d '{
    "enterprise": "'"$ENTERPRISE"'",
    "passphrase": "'"$PASSPHRASE"'",
    "label": "'"$LABEL"'",
    "multisigType": "onchain",
    "type": "hot"
}'

Step Result

Note

This response contains critical key material. Save it in a secure place.

{
  "wallet": {
    "id": "6849948ac0623f81f74f63dbd8351d4f",
    "users": [
      {
        "user": "62ab90e06dfda30007974f0a52a12995",
        "permissions": ["admin", "spend", "view"]
      }
    ],
    "coin": "tbtc4",
    "label": "TBTC4 Self-Custody Wallet",
    "m": 2,
    "n": 3,
    "keys": [
      "68499487e6c77351bd3bbf04281fa8bb",
      "68499487cd07fc57de18f6481baa1903",
      "6849948902be620840a384c148d19979"
    ],
    "keySignatures": {
      "backupPub": "204119cfa9a1d0a00bd0e30b2c43d535dff36af557d1846385df7d47dc1a0092cc1eefbdc41b9f619f6d89d3597656c5e3f6b1ccc4b1f4331861c6b0993296eab9",
      "bitgoPub": "20784ad236269cd93ba6b922831cc102fdfba193e6be5e88ba6234de1e5232b4ba65db1a0e47f1fd8d038bd23878632e4c376b475b36e4a0d9516797c12630963b"
    },
    "enterprise": "62c5ae8174ac860007aff138a2d74df7",
    "organization": "62c5ae8174ac860007aff1555ffb960d",
    "bitgoOrg": "BitGo Trust",
    "tags": [
      "6849948ac0623f81f74f63dbd8351d4f",
      "62c5ae8174ac860007aff138a2d74df7"
    ],
    "disableTransactionNotifications": false,
    "freeze": {},
    "deleted": false,
    "approvalsRequired": 1,
    "isCold": false,
    "coinSpecific": {},
    "admin": {},
    "clientFlags": [],
    "walletFlags": [],
    "allowBackupKeySigning": false,
    "recoverable": false,
    "startDate": "2025-06-11T14:36:58.000Z",
    "type": "hot",
    "buildDefaults": {},
    "customChangeKeySignatures": {},
    "hasLargeNumberOfAddresses": false,
    "multisigType": "onchain",
    "hasReceiveTransferPolicy": false,
    "creator": "62ab90e06dfda30007974f0a52a12995",
    "config": {},
    "balance": 0,
    "balanceString": "0",
    "rbfBalance": 0,
    "rbfBalanceString": "0",
    "confirmedBalance": 0,
    "confirmedBalanceString": "0",
    "spendableBalance": 0,
    "spendableBalanceString": "0",
    "unspentCount": 0,
    "receiveAddress": {
      "id": "6849948ac0623f81f74f63ead377af97",
      "address": "tb1pz65k93su0vdccm9tewv5c00nxjytmxxqwxjn6lcn4pu7d9fa5jtqvg0glr",
      "chain": 40,
      "index": 0,
      "coin": "tbtc4",
      "wallet": "6849948ac0623f81f74f63dbd8351d4f",
      "coinSpecific": { "_requestId": "54b5f74006db93a38ab7-0000" }
    },
    "pendingApprovals": []
  },
  "userKeychain": {
    "id": "68499487e6c77351bd3bbf04281fa8bb",
    "pub": "xpub661MyMwAqRbcEst4tb4F36AfvoFtAy7U9viB7zapRqNnXhPknsPwNqhxpD1CqMGSGhq3hDMKQR1Br8gGxYygoR6SGic3XdJoTEzM5v9wyFy",
    "ethAddress": "0x944b592f950d24dd12dc405527e355d3d3922856",
    "source": "user",
    "type": "independent",
    "encryptedPrv": "{\"iv\":\"9sYzOP14H+eAN16iN40RLA==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"P5CWbEjWcu0=\",\"ct\":\"yTNEuBHcOjrZAeqSeGSgxu1Anls6zuC7W6AcwNuL4dwGbc3A6OSs68fpzN2ZpFj4EP1BazjiuT0iwZXIaEY/aYsGLNF/DMkTa16sngzx16Az20sBroYdvcfqXoroTZR63N6hoeepQst19nTuPYp/By/NYR/nhxo=\"}",
    "prv": "xprv9s21ZrQH143K2PobnZXEfxDwNmRPmWPcnhnaKcBCsVqoeu4cFL5gq3PUxv8jZXassaVMAxdrZAi91kyY2RVRkoNW2x5JKSBnozsB4Nc4m5H"
  },
  "backupKeychain": {
    "id": "68499487cd07fc57de18f6481baa1903",
    "pub": "xpub661MyMwAqRbcEfnfBkVRk9BB1SrYaFR884ndYpmNXnci6U2wrAQCsFiD21c49Aq7EvtK6QFzDzMwmFKVqi1bTL7kmuCEJ78bFn9Rq6NyLDV",
    "ethAddress": "0x1907355a7022491140d0e7e3447303c94c2be0f1",
    "source": "backup",
    "type": "independent",
    "encryptedPrv": "{\"iv\":\"EHdXHSWtgxzMhys9XAK9kg==\",\"v\":1,\"iter\":10000,\"ks\":256,\"ts\":64,\"mode\":\"ccm\",\"adata\":\"\",\"cipher\":\"aes\",\"salt\":\"oAQFS3LUV38=\",\"ct\":\"za2qiPkBjSkxD6XJBYvCyLfFtZMjZG00eUOKMfuzKNODp5/zDnRSPhMj28nMxayWowf8XLyyN7lMxJXBYxohuZ95ii5XWK6sw4SxKrD6+cejiMawWFIFTCNc0WhrcnTsYpyMYL1U5Ncpcd2/5sPUNOBWaK5XAdA=\"}",
    "prv": "xprv9s21ZrQH143K2BiC5ixRP1ESTR24AnhGkqs2kSMkyT5jDfhoJd5xKTPjAkMwgvkHDmvBTMq6ck679XNTtdd1fz1DmxifzPi8HkkP7GjKyfj"
  },
  "bitgoKeychain": {
    "id": "6849948902be620840a384c148d19979",
    "pub": "xpub661MyMwAqRbcGCXsEAmctkLstGa92f5ugiD3hvCL3Wyt8BqHYGCVsL2x6PgNgJeq8Aabtz92sMzq4Ezac459QkDmxowKqoL35gNJXEJDdeo",
    "ethAddress": "0x92f48893ab51470c2253a97aea8071da70bbd461",
    "source": "bitgo",
    "type": "independent",
    "isBitGo": true,
    "isTrust": false,
    "hsmType": "institutional"
  },
  "responseType": "WalletWithKeychains",
  "warning": "Be sure to backup the backup keychain -- it is not stored anywhere else!"
}

Note

Some networks, such as Ethereum, don't immediately return a new multisignature address, since creating a new address requires a blockchain transaction. The blockchain must confirm this transaction before you can use the address. The parameter pendingChainInitialization identifies if an address is awaiting confirmation.

You can save the wallet ID in the response, then wait for the blockchain to confirm the address before using it.

Next

See Also