Navbar

Introduction

Welcome to the Coinbase Custody API documentation. The REST API has endpoints to access information about your account. Currently, the Coinbase Custody API supports read and write functionality for a variety of resources.

REST API Endpoint URL

https://api.custody.coinbase.com

Resource Access

Please see the table below for the access level of indvidual resources

Resource Read Write
Addresses Full Not supported
Users Full Not supported
Wallets Full in beta
Transactions Full in beta
Address Book Full in beta

Authentication

Generating an API Key

Before you can sign any requests, you must request an API Key from the Settings page of your Coinbase Custody account. Activating an API Key is subject to consensus.

To get started, add a new API Key on the Settings page. You will be prompted to name it and record the Passphrase. These will not be shown again and cannot be recovered for you.

After consensus approval, the activated API Key will appear in the related table with an associated Access Key. The two key pieces of information for your API Key are:

You will use the Access Key and Passphrase to make authenticated requests to your account. Coinbase Custody stores the salted hash of your passphrase for verification, but cannot recover the passphrase if you forget it.

API Key Permissions

Coinbase Custody API Keys can be read only or read write (in-beta).

Requests

All requests and responses are application/json content type and follow typical HTTP response status codes for success and failure.

Creating a Request

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/currencies?limit=100 \
    --header 'CB-ACCESS-KEY: <access_key>' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase>' \
    --header 'Content-Type: application/json'

All requests to the REST API must contain the following headers:

All request bodies should have content type application/json and be valid JSON.

Errors

Unless otherwise stated, errors to bad requests will respond with HTTP 4xx or 5xx status codes. The body will also contain a message parameter indicating the cause. Your language’s HTTP library should be configured to provide message bodies for non-2xx requests so that you can read the message field from the body.

Common error codes

Error Code Meaning Description
400 Bad Request Invalid request format
401 Unauthorized Invalid API Key
403 Forbidden You do not have access to the requested resource
404 Not Found Requested resource could not be found
500 Internal Server Error Server-side error occurred

Success

A successful response is indicated by HTTP status code 200 and may contain an optional body. If the response has a body, it will be documented under the related endpoint resource below.

Rate Limiting

Access to the Custody API is rate limited to 20 requests per second. If your API key exceeds this limit the API will respond with error message containing 429 HTTP Status Code and a "Rate limit exceeded" error message. To recover from this please reduce the number of requests you make to under 20 per second.

Pagination

Coinbase Custody uses cursor pagination for all REST requests which return arrays. Cursor pagination allows for fetching results before and after the current page of results and is well suited for realtime data. All endpoints return the most recent items first by default. To retrieve more results, subsequent requests should specify which direction to paginate based on the data previously returned.

before and after cursors are available via response headers CB-BEFORE and CB-AFTER. Your requests should use these cursor values when making requests for pages after the initial request.

Parameters

Parameter Default Description
before Request page before (newer than) this pagination id.
after Request page after (older than) this pagination id.
limit 25 Number of results per request. Maximum 100. Default 25.

Example

GET /api/v1/currencies?before=btc&limit=10

Before and After cursors

The before cursor references the first item in a results page and the after cursor references the last item in a set of results.

To request a page of records before the current one, use the before query parameter. Your initial request can omit this parameter to get the default first page.

The response will contain a CB-BEFORE header which will return the cursor id to use in your next request for the page before the current one. The page before is a newer page and not one that happened before in chronological time.

The response will also contain a CB-AFTER header which will return the cursor id to use in your next request for the page after this one. The page after is an older page and not one that happened after this one in chronological time.

Addresses

GetAddresses

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/addresses \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/addresses

Gets a list of addresses

Get a list of all crypto addresses associated with the account. For most use cases, you should use the Wallets endpoint to see the current cold address and balance for all wallets. The response value can be filtered by query parameters.

Parameters

Name In Type Required Description
wallet_id query string false The wallet id to filter by
currency query string false The type of currency to filter
state query string false The state of the address to filter

Enumerated Values

Parameter Value
state cold
state restore_in_progress
state restored

Response

filtered addresses by wallet_id

{
  "data": [
    {
      "address": "fake_eth_cold_address",
      "state": "cold",
      "balance": 0,
      "blockchain_link": "https://etherscan.io/address/fake_eth_cold_address",
      "created_at": "2020-07-22T18:55:22.012Z",
      "updated_at": "2020-07-22T18:55:22.012Z",
      "currency": "ETH",
      "balance_whole_units": "0.0"
    },
    {
      "address": "fake_btc_cold_address",
      "state": "cold",
      "balance": 0,
      "blockchain_link": "https://live.blockcypher.com/btc/address/fake_btc_cold_address",
      "created_at": "2020-07-22T18:55:21.945Z",
      "updated_at": "2020-07-22T18:55:21.945Z",
      "currency": "BTC",
      "balance_whole_units": "0.0"
    }
  ],
  "pagination": {
    "before": "fake_eth_cold_address",
    "after": "fake_btc_cold_address"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of addresses
address string false The crypto address
currency string false The type of currency
amount_whole_units string false The balance of the address in whole network units
amount integer false The balance of the address in atomic network units
state string false The state of the address if it is cold or restored
blockchain_link string false Blockchain explorer link
created_at string false The time this address was created
updated_at string false The time this address was last updated

GetAddressById

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/addresses/{address} \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/addresses/{address}

Gets a single address

Get information about a single crypto address. Use this endpoint when you know the specific address you want to retrieve.

Parameters

Name In Type Required Description
address path string true The crypto address to retrieve

Response

found address

{
  "address": "fake_btc_cold_address",
  "state": "cold",
  "balance": 0,
  "blockchain_link": "https://live.blockcypher.com/btc/address/fake_btc_cold_address",
  "created_at": "2020-07-22T18:55:23.581Z",
  "updated_at": "2020-07-22T18:55:23.581Z",
  "currency": "BTC",
  "balance_whole_units": "0.0"
}

Currencies

GetCurrencies

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/currencies \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/currencies

Allows all API keys

Retrieve the list of available currencies for your organization. The response is filterable by query parameters.

Parameters

Name In Type Required Description
symbol query string false The currency symbol to filter
limit query string false The number of symbols to retrieve

Response

with READ_WRITE key

{
  "data": [
    {
      "name": "Bitcoin",
      "decimals": 8,
      "symbol": "BTC"
    },
    {
      "name": "Bitcoin Cash",
      "decimals": 8,
      "symbol": "BCH"
    }
  ],
  "pagination": {
    "before": "btc",
    "after": "bch"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of currencies
symbol string false The type of currency
name string false The name of the currency

GetCurrencyById

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/currencies/{symbol} \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/currencies/{symbol}

Gets a single currency by symbol

Retrieve information about single currency.

Parameters

Name In Type Required Description
symbol path string true The symbol of the currency to retrieve

Response

found currency

{
  "name": "Bitcoin",
  "decimals": 8,
  "symbol": "BTC"
}

Transactions

GetTransactions

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/transactions \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/transactions

Gets a list of transactions

Retrieve a list of the transactions from your organization. The response is filterable by query parameters.

Parameters

Name In Type Required Description
currency query string false The type of currency to filter
state query string false The state of transactions to filter
type query string false The type of transactions to filter
wallet_id query string false The wallet id to filter
start_time query string false The start time to filter
end_time query string false The end time to filter
human_id query string false The human id to filter

Response

filtered by human id

{
  "data": [
    {
      "id": "86f54dcc-63d9-4275-8955-8ef69b6b197e",
      "type": "withdrawal",
      "state": "done",
      "amount": -100,
      "destination": null,
      "created_at": "2020-07-22T17:45:39.723Z",
      "updated_at": "2020-07-22T18:55:40.015Z",
      "wallet_id": "22ce4248-b57c-4bc7-bacf-4494b0251196",
      "amount_whole_units": "-0.000001",
      "currency": "BTC",
      "fee": 10,
      "hashes": [
        "8ee454cd21a6599f70599fc3199089b1"
      ],
      "source": null
    }
  ],
  "pagination": {
    "before": "d506ed51-d215-4d2e-bf4b-b6a1c761af88",
    "after": "6bd440dc-2726-4ad8-8420-39f096397a7a"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of transactions
id string false The ID of the transaction
type string false The type of transaction for example deposit or withdrawal
amount_whole_units string false The amount to deposit or withdraw in whole network units
amount integer false The amount to deposit or withdraw in atomic network units
currency string false The type of currency
fee integer false The fee of the transaction
hashes array false Blockchain transaction hashes
created_at string false The time this transaction was created
updated_at string false The time this transaction was updated

CreateTransaction

Body parameter

{
  "destination": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
  "source": "93cd4918-82bf-4a04-b58e-c94e36d0d817",
  "whole_amount": "10.0"
}

HTTP Request

POST /api/v1/transactions

Creates a new withdrawal transaction (beta)

Request a new withdrawal transaction be created from one of your organization's wallets. This request is subject to in-app consensus from your organization's signatories before it can be fulfilled.

Parameters

Name In Type Required Description
body body object false The create transaction payload
source body string true The source wallet id for the transaction
currency body string false A fiat currency symbol such as USD. If provided Custody will automatically convert the amount value into crypto units
whole_amount body string true The amount of the transaction in whole units (e.g. "1.01")
destination body string true The destination address of the transaction
account_identifier body string false The account identifier of the transaction (for example destination tag or memo value)

Response

with READ_WRITE key

{
  "destination": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa",
  "activity_id": "4bc6d4aa-0988-428a-95f6-f6dad01c2d89",
  "currency": "BTC",
  "approval_url": "http://custody.coinbase.com/activity/4bc6d4aa-0988-428a-95f6-f6dad01c2d89",
  "whole_amount": "0.001",
  "fee": "0.0000817",
  "source": "14J9RE7ieGf2ysmtHCEwjEnVSrundEqvLP"
}

GetTransactionById

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/transactions/{id} \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/transactions/{id}

Gets a single transaction by id

Retrieve information about a single transaction from your organization.

Parameters

Name In Type Required Description
id path string true The transaction id to retrieve

Response

found transaction

{
  "id": "9ea39fe5-eea0-4b09-ac98-4fff3f72a6ed",
  "type": "deposit",
  "state": "imported",
  "amount": 2000,
  "destination": null,
  "created_at": "2020-07-20T18:55:54.614Z",
  "updated_at": "2020-07-22T18:55:54.646Z",
  "wallet_id": "40178291-bfa5-438f-a9b2-294a2e54c839",
  "amount_whole_units": "0.00002",
  "currency": "BTC",
  "fee": 0,
  "hashes": [
    "943055a33dc4f3cb4831840bc3bde5c4",
    "9cffff05db2e16f45acd4659506142df"
  ],
  "source": null
}

Users

GetUsers

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/users \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/users

Gets a list of users

Retrieve a list of the users that belong to your organization.

Response

users found

{
  "data": [
    {
      "id": "accdb67e-c63f-4d8c-9c2f-71e5f6ae2ad6",
      "name": "test1",
      "state": "active",
      "email": "[email protected]",
      "created_at": "2020-07-22T18:56:04.565Z",
      "updated_at": "2020-07-22T18:56:04.565Z",
      "role": "auditor"
    },
    {
      "id": "e013eafb-4954-4eef-a33f-51bc804ddc29",
      "name": "test2",
      "state": "active",
      "email": "[email protected]",
      "created_at": "2020-07-22T18:56:04.575Z",
      "updated_at": "2020-07-22T18:56:04.575Z",
      "role": "auditor"
    },
    {
      "id": "e7b77718-e72e-4b02-9fee-9ec2564be4e9",
      "name": "test3",
      "state": "active",
      "email": "[email protected]",
      "created_at": "2020-07-22T18:56:04.585Z",
      "updated_at": "2020-07-22T18:56:04.585Z",
      "role": "auditor"
    }
  ],
  "pagination": {
    "before": "accdb67e-c63f-4d8c-9c2f-71e5f6ae2ad6",
    "after": "e7b77718-e72e-4b02-9fee-9ec2564be4e9"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of users
id string false The ID of the user
name string false The name of the user
email string false The email of the user
state string false The state of the user for example active or disabled
role string false The users role in the organization
created_at string false The time the user was created
updated_at string false The time the user was last updated

GetUserById

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/users/{id} \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/users/{id}

Gets a single user by id

Retrieve information about a single user in your organization.

Parameters

Name In Type Required Description
id path string true The user id to retrieve

Response

user found

{
  "id": "6a8b6f98-08d2-4323-b84c-6b0a7b8c5462",
  "name": "test1",
  "state": "active",
  "email": "[email protected]",
  "created_at": "2020-07-22T18:56:04.975Z",
  "updated_at": "2020-07-22T18:56:04.975Z",
  "role": "auditor"
}

Wallets

GetWallets

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/wallets \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/wallets

Gets a list of wallets

Retrieve a list of your organization's wallets. The response value can be filtered by query parameters.

Parameters

Name In Type Required Description
currency query string false The currency to filter

Response

filtered wallets found by currency

{
  "data": [
    {
      "id": "9ca8d02d-563e-4b4f-b5c9-d9d28fb3ac0a",
      "name": "test",
      "created_at": "2020-07-22T18:56:07.570Z",
      "updated_at": "2020-07-22T18:56:07.570Z",
      "balance": "0",
      "balance_whole_units": "0.0",
      "withdrawable_balance": "0",
      "withdrawable_balance_whole_units": "0.0",
      "unvested_balance": "0",
      "unvested_balance_whole_units": "0.0",
      "cold_address": "fake_eth_cold_address",
      "currency": "ETH"
    },
    {
      "id": "90b582e4-2c3e-4ee0-ae15-13036e5de0fd",
      "name": "test",
      "created_at": "2020-07-22T18:56:07.550Z",
      "updated_at": "2020-07-22T18:56:07.550Z",
      "balance": "0",
      "balance_whole_units": "0.0",
      "withdrawable_balance": "0",
      "withdrawable_balance_whole_units": "0.0",
      "unvested_balance": "0",
      "unvested_balance_whole_units": "0.0",
      "cold_address": "fake_btc_cold_address",
      "currency": "BTC"
    }
  ],
  "pagination": {
    "before": "9ca8d02d-563e-4b4f-b5c9-d9d28fb3ac0a",
    "after": "90b582e4-2c3e-4ee0-ae15-13036e5de0fd"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of wallets
id string false The ID of the wallet
name string false The name of the wallet
balance_whole_units string false The current balance in whole network units
withdrawable_balance_whole_units string false The withdrawable balance in whole network units
balance string false The current balance in atomic network units
withdrawable_balance string false The current withdrawable balance in atomic network units
cold_address string false The cold crypto address
currency string false The type of currency
created_at string false The time the wallet was created
updated_at string false The time the wallet was last updated

CreateWallet

Body parameter

{
  "currency": "btc",
  "name": "My BTC Wallet"
}

HTTP Request

POST /api/v1/wallets

Creates a new wallet (beta)

Request a new wallet be created for your organization. This request is subject to in-app consensus from your organization's signatories before it can be fulfilled.

Parameters

Name In Type Required Description
body body object false The create wallet payload
currency body string true The currency of the new wallet
name body string true The name of the new wallet

Response

with READ_WRITE key

{
  "activity_id": "5f541f4b-92a1-4817-ab8a-c47a8a6a5e72",
  "currency": "BTC",
  "approval_url": "http://custody.coinbase.com/activity/5f541f4b-92a1-4817-ab8a-c47a8a6a5e72",
  "name": "My BTC Wallet"
}

GetWalletById

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/wallets/{id} \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/wallets/{id}

Gets a single wallet by id

Retrieve information about an individual wallet for your organization.

Parameters

Name In Type Required Description
id path string true The wallet id to retrieve

Response

wallet found

{
  "id": "366f4746-2d0a-40e4-a052-24109fe98e82",
  "name": "test",
  "created_at": "2020-07-22T18:56:12.107Z",
  "updated_at": "2020-07-22T18:56:12.107Z",
  "balance": "0",
  "balance_whole_units": "0.0",
  "withdrawable_balance": "0",
  "withdrawable_balance_whole_units": "0.0",
  "unvested_balance": "0",
  "unvested_balance_whole_units": "0.0",
  "cold_address": "fake_btc_cold_address",
  "currency": "BTC"
}

Address Book

GetAddressBook

curl --request GET \
    --url https://api.custody.coinbase.com/api/v1/address_book \
    --header 'CB-ACCESS-KEY: <api_key> ' \
    --header 'CB-ACCESS-PASSPHRASE: <passphrase> ' \
    --header 'Content-Type: application/json'

HTTP Request

GET /api/v1/address_book

Gets a list of address book addresses (beta)

Retrieve a list of addresses in your organization's address book. The response value can be filtered by query parameters.

Parameters

Name In Type Required Description
currency query string false The currency to filter
account_identifier query string false The account identifier to filter by
name query string false The name to filter by
address query string false The address to filter by

Response

filtered addresses found by currency

{
  "data": [
    {
      "id": "24592c96-933a-4b74-8bc5-c0559e9cb7fc",
      "address": "xlm_address_1",
      "name": "My Custom XLM Address",
      "created_at": "2020-07-22T18:56:16.465Z",
      "updated_at": "2020-07-22T18:56:16.465Z",
      "currency": "XLM",
      "account_identifier": "123"
    },
    {
      "id": "0b8c4494-6b81-480d-8345-ed9bb56fa495",
      "address": "btc_address_1",
      "name": "Coinbase Pro BTC",
      "created_at": "2020-07-22T18:56:16.449Z",
      "updated_at": "2020-07-22T18:56:16.449Z",
      "currency": "BTC"
    }
  ],
  "pagination": {
    "before": "24592c96-933a-4b74-8bc5-c0559e9cb7fc",
    "after": "0b8c4494-6b81-480d-8345-ed9bb56fa495"
  }
}

Response

Status Code 200

Name Type Required Description
data array false Array of addresses from the address book
id string false The ID of the allowed address
name string false The name of the allowed address
address string false The crypto address of the allowed address
currency string false The type of currency of the allowed address
account_identifier string false The account identifier associated with the allowed address (for example destination tag or memo value)
created_at string false The time the allowed address was created
updated_at string false The time the allowed address was last updated

CreateAddressBookEntry

Body parameter

{
  "curency": "BTC",
  "name": "Bitcoin Genesis Address",
  "address": "1A1zP1eP5QGefi2DMPTfTL5SLmv7DivfNa"
}

HTTP Request

POST /api/v1/address_book

Creates a new address book address (beta)

Request a new address be added to your organization's address book. This request is subject to in-app consensus from your organization's signatories before it can be fulfilled.

Parameters

Name In Type Required Description
body body object false The address payload
currency body string true The currency of the new allowed address
name body string true The name of the new allowed address
address body string true The crypto address of the new allowed address
account_identifier body string false The account identifier of the new allowed address

Response

with READ_WRITE key

{
  "activity_id": "20a78101-4723-41bc-b4f6-281a61d32888",
  "account_identifier": "2423354331",
  "currency": "XRP",
  "approval_url": "http://custody.coinbase.com/activity/20a78101-4723-41bc-b4f6-281a61d32888",
  "name": "Coinbase Pro XRP"
}

Objects

Additional information regarding the various states and types of objects received from the Custody API

Address

States

State Description
cold Address is secured in offline storage
warm DEPRECATED
restore_in_progress Address is in-progress of being brought online
restored Address has been brought online
foreign Address that is not directly back by cold storage such as a proxy voting contract
invalidated Address that is not usable

Transactions

Types

Type AffectsBalance Description
deposit true On-chain deposit of funds to an associated address
withdrawal true On-chain withdrawal of funds authorized by account consensus.
reward true Reward payment to an associated address for a staked asset
sweep_withdrawal true Internal automated withdrawal from a restored address to a cold address
sweep_deposit true Internal automated deposit to a cold address from a restored address
proxy_withdrawal true On-chain withdrawal of funds from proxy contract to cold address
proxy_deposit true On-chain deposit of funds into proxy contract from cold address
coinbase_deposit true Coinbase Custody network fee payment for an eligible withdrawal
key_registration false Registration of a crypto key for staking purposes
billing_withdrawal true Coinbase Custody automated invoice settlement payment
delegation false On-chain delegation of funds or votes to a destination address
undelegation false On-chain transaction to revoke a previous delegation of funds or votes
restake false On-chain transaction that stakes/bonds additional funds and or pending rewards
complete_unbonding false On-chain event at the end of the bonding period which signals that bonded funds are now liquid again
coinbase_refund true Coinbase Custody refund for the leftover amount for a CPFP(child pays for parent)transaction

States

State Terminal Description
created false Transaction has been created by an account member
requested false Transaction has been authorized by account consensus
approved false Transaction has been authorized by Coinbase Custody
gassing false Transaction is pending coinbase_deposit fee funding
planned false Transaction is planned for broadcast
restored false Transaction broadcast is pending secure address restore
done true Transaction has been broadcast and confirmed on-chain
imported true Transaction has been detected and credited
cancelled true Transaction has been cancelled
user_rejected true Transaction has been rejected by an account member
rejected true Transaction has been rejected by Coinbase Custody

Changelog

1.1.0 - July 2020

Added

Removed

1.0.0 — April 2020

Coinbase Custody v1.0 API has launched