> ## Documentation Index
> Fetch the complete documentation index at: https://docs.deribit.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Coinbase Wallet API

> Wallet API behavior for Coinbase-custodied Deribit accounts: network selection, deposit addresses, address book and CTN counterparties, and withdrawals.

Accounts whose wallet is custodied by Coinbase use the same wallet methods as
every other account, but a single currency can exist on more than one blockchain
network. Because an address is only meaningful together with its network, these
methods take an extra `network` parameter, address book entries carry their own
identifier, and withdrawals can also be sent to a Coinbase Travel Network (CTN)
counterparty instead of an on-chain address.

## Discovering the available networks

Networks are identified by a **network resource name** such as
`networks/ethereum-mainnet`, and this string is the value you pass as `network`.
Do not construct it yourself — read it from
[`public/get_currencies`](/api-reference/market-data/public-get_currencies).
Every Coinbase wallet currency includes a `coinbase_networks` array with at least
one network.

### Example Response

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": [
    {
      "currency": "ETH",
      "currency_long": "Ethereum",
      "coinbase_networks": [
        {
          "resource_name": "networks/ethereum-mainnet",
          "display_name": "Ethereum"
        }
      ]
    }
  ]
}
```

Each entry has a `resource_name` to send to the API and a `display_name` to show
to a user. Coinbase wallet currencies always have networks — do not expect
`coinbase_networks` to be missing or empty for those currencies.

[`private/create_deposit_address`](/api-reference/wallet/private-create_deposit_address),
[`private/get_current_deposit_address`](/api-reference/wallet/private-get_current_deposit_address)
and `private/add_to_address_book` validate `network` against the currency's
`coinbase_networks` and reject one that is not configured for it. Elsewhere —
`private/withdraw`, the update and remove methods and
`private/set_address_requires_security_key` — `network` is only used to select an
existing address book entry, so an unknown value fails to match. The method
[`private/coinbase/estimate_withdrawal_fee`](/api-reference/wallet/private-estimate_withdrawal_fee)
is restricted to Coinbase wallet type accounts.

## Deposit addresses

[`private/create_deposit_address`](/api-reference/wallet/private-create_deposit_address)
requires both `currency` and `network`, so each currency and network combination
has its own deposit address. An optional `label` can be supplied, which defaults
to `"deposit address"`.

### Example Request

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/create_deposit_address",
  "params": {
    "currency": "ETH",
    "network": "networks/ethereum-mainnet",
    "label": "Treasury inflows"
  },
  "id": 1
}
```

### Response

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "id": "0190a1b2-7c3d-7e5f-8a9b-0c1d2e3f4a5b",
    "currency": "ETH",
    "address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
    "type": "deposit",
    "kind": "onchain",
    "label": "Treasury inflows",
    "creation_timestamp": 1719993033041,
    "updated_timestamp": 1719993033041,
    "status": "active",
    "waiting_timestamp": null,
    "requires_confirmation": false,
    "requires_confirmation_change": false,
    "requires_security_key": false,
    "info_required": true,
    "network": "networks/ethereum-mainnet",
    "network_display_name": "Ethereum",
    "tag": ""
  }
}
```

`tag` is only returned for networks which use a destination tag, for example
XRPL. Deposit addresses always report `info_required` as `true`; the flag concerns
withdrawal beneficiary data and has no meaning for a deposit address.

This method is get-or-create. If an address already exists for the currency and
network it is returned unchanged, which means a `label` sent on a later call is
ignored rather than applied. Use
[`private/get_current_deposit_address`](/api-reference/wallet/private-get_current_deposit_address)
to read the existing address without attempting to create one; it also requires
`network` and returns `null` when nothing has been created yet.

<Warning>
  A deposit address is only valid on the network it was created for. Sending funds
  to it over a different network may make them unrecoverable.
</Warning>

## Address book entries

Every entry has an `id` — a UUID7 assigned by Deribit and returned by
[`private/get_address_book`](/api-reference/wallet/private-get_address_book).
Because the same address can be whitelisted on several networks, an entry is
identified in one of two ways:

* By `id`. This is unambiguous and is the recommended approach.
* By `address`, adding `network` and `tag` where needed.

The `kind` field distinguishes the two sorts of destination:

| `kind`    | Destination                                                                                    |
| --------- | ---------------------------------------------------------------------------------------------- |
| `onchain` | A blockchain address on a specific network                                                     |
| `ctn`     | A Coinbase Travel Network counterparty, identified by a counterparty ID rather than an address |

Accepted `type` values differ per method:

| Method                             | Accepted `type`                     |
| ---------------------------------- | ----------------------------------- |
| `private/add_to_address_book`      | `withdrawal`, `transfer`            |
| `private/update_in_address_book`   | `withdrawal`, `transfer`            |
| `private/remove_from_address_book` | `withdrawal`, `transfer`            |
| `private/get_address_book`         | `withdrawal`, `transfer`, `deposit` |

`deposit_source` is not used. Deposit entries are created by
`private/create_deposit_address` rather than added by hand, which is why
`deposit` is readable but not writable.

The `status` field reports availability: `waiting` while your account's
withdrawal delay is still pending, `ready` once the entry can be used, and
`active` for deposit addresses. Fields that were never set — `tag` and `network`
on CTN entries, and any Travel Rule field you did not supply — are omitted from
address book responses rather than returned as `null`, so test for presence. The
exception is a deposit entry, which reports `tag` as an empty string; these are
returned by `type: "deposit"` as well as by the deposit address methods.

### Listing entries, including CTN counterparties

CTN counterparties work with any asset, so they are stored under `"all"` rather
than under a specific currency like ETH or BTC.

<Warning>
  `private/get_address_book` returns only entries for the `currency` you pass. A
  call with `currency: "ETH"` therefore omits CTN counterparties — list those with
  a second call using `currency: "all"`. Make both calls if you need every
  withdrawal destination.
</Warning>

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/get_address_book",
  "params": {
    "currency": "all",
    "type": "withdrawal"
  },
  "id": 2
}
```

### Adding an on-chain address

[`private/add_to_address_book`](/api-reference/wallet/private-add_to_address_book)
requires `type` and `label`, plus `currency`, `address` and `network`. Add `tag`
for networks that use a destination tag or memo.

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/add_to_address_book",
  "params": {
    "currency": "ETH",
    "type": "withdrawal",
    "address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
    "network": "networks/ethereum-mainnet",
    "label": "Main address",
    "name": "Alice Smith",
    "country": "NL"
  },
  "id": 3
}
```

### Adding a CTN counterparty

Supply `counterparty_id` instead of `address` and `network`, and omit `currency`
— the entry is stored under `"all"`.

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/add_to_address_book",
  "params": {
    "type": "withdrawal",
    "counterparty_id": "cp-8f3e2a1b9c4d",
    "label": "CTN Partner"
  },
  "id": 4
}
```

### Travel Rule data

Beneficiary information is supplied on **on-chain** entries when adding or
updating them. The legacy `beneficiary_*`, `agreed` and `personal` parameters are
not used, and `extra_currencies` is not supported.

`name` and `country` are the two fields that matter operationally: together they
satisfy the Travel Rule requirement, clear `info_required`, and are the values
forwarded with the withdrawal. The remaining fields are stored alongside them as
supplementary detail.

| Parameter               | Description                                                                                 |
| ----------------------- | ------------------------------------------------------------------------------------------- |
| `name`                  | Full name of the beneficiary, person or organization. Required to satisfy the Travel Rule   |
| `country`               | Beneficiary country code, ISO 3166-1 alpha-2. Required to satisfy the Travel Rule           |
| `address`               | Beneficiary address. On an on-chain entry this is the same value as the destination address |
| `financial_institution` | Institution holding the beneficiary account                                                 |
| `account`               | Account identifier at that institution                                                      |
| `account_location`      | Location of the beneficiary account                                                         |
| `entity_type`           | `organization` or `individual`                                                              |
| `wallet_type`           | `exchange` or `self_hosted`                                                                 |
| `is_self`               | `true` when the beneficiary is the account owner                                            |

Once any of this data is stored the entry returns `beneficiary_created` and
`beneficiary_updated` timestamps. A withdrawal that needs Travel Rule data and
does not have `name` and `country` is rejected — on the usual confirmation path
this happens when the withdrawal is confirmed rather than when it is created, so
`private/withdraw` can return `prepared` and the withdrawal then fail with
`travel_rule_data_required`. Supply both fields when whitelisting an address you
intend to withdraw to.

<Note>
  CTN entries do not store beneficiary data. Travel Rule fields sent with a
  `counterparty_id` are accepted but discarded, such entries always report
  `info_required` as `true`, and they never return the `beneficiary_*` timestamps.
  Counterparty identity is already established within the Travel Network, so CTN
  withdrawals are not blocked by this.
</Note>

### Updating and removing entries

[`private/update_in_address_book`](/api-reference/wallet/private-update_in_address_book)
takes `currency` and `type`, plus either `address` or `id`. `label` is optional
here, and the method returns the updated entry rather than `"ok"`.

[`private/remove_from_address_book`](/api-reference/wallet/private-remove_from_address_book)
takes the same identifying parameters and returns `"ok"`.

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/update_in_address_book",
  "params": {
    "currency": "ETH",
    "type": "withdrawal",
    "id": "0190a1b2-7c3d-7e5f-8a9b-0c1d2e3f4a5b",
    "label": "Updated label"
  },
  "id": 5
}
```

### Resolving an entry by address

When you identify an entry by `address` rather than `id`, Deribit narrows the
candidates by `tag` first and then by `network`:

* If several entries share the address and all of them carry a tag, omitting
  `tag` is rejected — whether or not the tags differ.
* If some candidates have a tag and others do not, omitting `tag` selects the
  untagged ones.
* If more than one candidate still remains and `network` was not supplied, the
  call is rejected.

Because tag narrowing runs first, an address whitelisted on two networks can
still resolve without `network` when only one of the two entries is untagged.
Pass `id`, or `address` together with `network` and `tag`, whenever you need to
be certain which entry you are acting on.

### Requiring a security key per address

[`private/set_address_requires_security_key`](/api-reference/wallet/private-set_address_requires_security_key)
controls whether withdrawals to one entry need security key approval. It takes
`currency`, `type` and `value`, plus either `address` or `id`, and returns the
updated entry. It requires only the `wallet:read_write` scope — unlike the legacy
wallet type it does not additionally require `mainaccount`, so a subaccount can
call it for its own entries.

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/set_address_requires_security_key",
  "params": {
    "currency": "ETH",
    "type": "withdrawal",
    "id": "0190a1b2-7c3d-7e5f-8a9b-0c1d2e3f4a5b",
    "value": true
  },
  "id": 6
}
```

## Creating a withdrawal

[`private/withdraw`](/api-reference/wallet/private-withdraw) requires `currency`
and `amount`, plus either `address` or `id`. The destination must already exist
in the address book. When identifying it by `address`, pass `network` — and `tag`
where applicable — for an on-chain destination, or pass the counterparty ID as
`address` for a CTN destination.

The `priority` and `nonce` parameters are not used.

<Warning>
  Because `nonce` is ignored, Coinbase withdrawals have no request idempotency. A
  retried `private/withdraw` creates a second withdrawal rather than returning the
  first, so retry only after confirming the outcome with
  [`private/get_withdrawals`](/api-reference/wallet/private-get_withdrawals).
</Warning>

### Example Request

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/withdraw",
  "params": {
    "currency": "ETH",
    "id": "0190a1b2-7c3d-7e5f-8a9b-0c1d2e3f4a5b",
    "amount": 0.5
  },
  "id": 7
}
```

### Response

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 7,
  "result": {
    "id": "01912f4e-8b6a-7c1d-9e2f-3a4b5c6d7e8f",
    "currency": "ETH",
    "state": "prepared",
    "amount": 0.5,
    "address": "0x742d35Cc6634C0532925a3b844Bc454e4438f44e",
    "network": "networks/ethereum-mainnet",
    "network_display_name": "Ethereum",
    "created_timestamp": 1719993033041,
    "updated_timestamp": 1719993033041,
    "note": ""
  }
}
```

The `id` here is the withdrawal's own identifier and is unrelated to the address
book `id` used to select the destination.

### Withdrawal states

| `state`                 | Meaning                                                                                |
| ----------------------- | -------------------------------------------------------------------------------------- |
| `prepared`              | Created and awaiting email confirmation                                                |
| `awaiting_second_email` | Confirmed once, awaiting the second confirmation where a secondary email is configured |
| `unconfirmed`           | Submitted to the custodian, not yet settled                                            |
| `completed`             | Settled by the custodian                                                               |
| `cancelled`             | Cancelled before settlement                                                            |

A new withdrawal starts as `prepared` and requires email confirmation. Entries
whose `requires_confirmation` is `false` and whose delay has elapsed are
**trusted**, and withdrawals to them skip confirmation and are submitted
immediately, so they start at `unconfirmed`. Since `requires_confirmation`
defaults to `true`, expect the confirmation path unless you have explicitly
turned it off for that entry.

<Note>
  `transfer_idem` is the idempotency key shared with the custodian and appears only
  once the withdrawal has been submitted, so it is absent while a withdrawal is
  `prepared`. As with the rest of the response, unset fields are omitted;
  `transaction_id` appears only after the transaction has been broadcast.
</Note>

## Estimating the withdrawal fee

[`private/coinbase/estimate_withdrawal_fee`](/api-reference/wallet/private-estimate_withdrawal_fee)
returns the expected network fee for a currency and network. Note that this
method names the parameter `network_name`, not `network`.

### Example Request

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/coinbase/estimate_withdrawal_fee",
  "params": {
    "currency": "BTC",
    "network_name": "networks/bitcoin-mainnet"
  },
  "id": 8
}
```

### Response

```json theme={null}
{
  "jsonrpc": "2.0",
  "id": 8,
  "result": {
    "estimated_fee": "0.0005",
    "estimated_fee_before_subsidy": "0.001",
    "expires_at": "2026-04-06T12:00:00Z"
  }
}
```

`estimated_fee` is returned as a **string** to preserve precision, and
`estimated_fee_before_subsidy` is the amount before any fee subsidy is applied —
it falls back to `estimated_fee` when the custodian does not report it, so the two
being equal does not by itself mean no subsidy applied. `expires_at` is a
timestamp after which the estimate should no longer be relied on, and is `null`
when the custodian does not supply one. The estimate is indicative: the fee
charged at settlement may differ. Parse these values defensively — they are
passed through from the custodian.

## Subaccount withdrawals

Subaccounts cannot withdraw unless the main account has allowed it. The main
account controls this with
[`private/set_coinbase_subaccount_withdrawals_allowed`](/api-reference/wallet/private-set_coinbase_subaccount_withdrawals_allowed),
which takes a single `enabled` boolean and echoes it back. Calling it from a
subaccount is rejected. While disabled, `private/withdraw` from a subaccount
fails with a permission error.

```json theme={null}
{
  "jsonrpc": "2.0",
  "method": "private/set_coinbase_subaccount_withdrawals_allowed",
  "params": {
    "enabled": true
  },
  "id": 9
}
```

## Differences from the legacy wallet type

| Area                    | Legacy wallet type                         | Coinbase wallet type                                                          |
| ----------------------- | ------------------------------------------ | ----------------------------------------------------------------------------- |
| Network                 | Implied by the currency                    | Explicit `network`, discovered from `coinbase_networks`                       |
| Entry identity          | `currency` and `address`                   | `id`, or `address` with `network` and `tag`                                   |
| Destinations            | On-chain addresses                         | On-chain addresses and CTN counterparties                                     |
| Address book `type`     | `withdrawal`, `transfer`, `deposit_source` | `withdrawal`, `transfer`, plus `deposit` when reading                         |
| Travel Rule fields      | `beneficiary_*`, `agreed`, `personal`      | `name` and `country`, plus supplementary fields                               |
| Withdrawal fee          | Chosen with `priority`                     | Set by the custodian; estimate via `private/coinbase/estimate_withdrawal_fee` |
| Withdrawal idempotency  | `nonce` deduplicates retries               | None                                                                          |
| Withdrawal result       | Legacy withdrawal object                   | Coinbase withdrawal object with `state` and `transfer_idem`                   |
| Currency scope          | Wallet currencies                          | Any portfolio currency, or `"all"` for CTN entries                            |
| Address book management | Main account only, except `deposit_source` | Subaccounts can manage their own entries                                      |

## Notes and best practices

* **Always read network names from the API.** Treat `resource_name` as an opaque string and never hardcode or derive it, so that newly supported networks work without a client change.
* **Prefer `id` over `address`.** Identifying an entry by `id` avoids the tag and network ambiguity described above, and avoids sending the address on every call.
* **Query `currency: "all"` as well.** CTN counterparties are invisible to a per-currency `private/get_address_book` call.
* **Supply `name` and `country` when whitelisting.** Without them an on-chain entry stays at `info_required: true` and withdrawals that need Travel Rule data are rejected.
* **Do not blindly retry withdrawals.** There is no `nonce`, so a retry creates a second withdrawal.
* **Test for presence, not for `null`.** Unset fields are omitted from address book and withdrawal responses.
* **Re-check the fee near submission.** Fee estimates expire, and the amount charged at settlement can differ from the estimate.
* **Enable subaccount withdrawals deliberately.** The setting is off by default and can only be changed by the main account.
* **Match the tag to the network.** Networks that use a destination tag or memo need `tag` both when whitelisting the address and when withdrawing to it by address.


## Related topics

- [private/set_coinbase_subaccount_withdrawals_allowed](/api-reference/wallet/private-set_coinbase_subaccount_withdrawals_allowed.md)
- [private/coinbase/estimate_withdrawal_fee](/api-reference/wallet/private-estimate_withdrawal_fee.md)
- [private/get_current_deposit_address](/api-reference/wallet/private-get_current_deposit_address.md)
- [private/remove_from_address_book](/api-reference/wallet/private-remove_from_address_book.md)
- [private/update_in_address_book](/api-reference/wallet/private-update_in_address_book.md)
