A capability represents a specific action a customer is authorized to take — holding a balance, sending a transfer, or placing a trade. Each capability must be explicitly requested, and Coinbase determines whether it can be granted based on the identity information you submit and the outcome of the customer’s KYC and compliance review. Before initiating an operation on behalf of a customer, check that the relevant capability is active.
Capability set
| Capability | What it enables |
|---|
custodyCrypto | Hold cryptocurrency in a Coinbase custodial account |
custodyFiat | Hold fiat currency in a Coinbase custodial account |
custodyStablecoin | Hold stablecoin in a Coinbase custodial account |
transferCrypto | Transfer cryptocurrency to another party |
transferFiat | Transfer fiat currency to another party |
transferStablecoin | Transfer stablecoin to another party |
tradeCrypto | Trade cryptocurrency |
tradeStablecoin | Trade stablecoin |
Each capability depends on a set of requirements. Most capabilities are satisfied by core identity verification (name, date of birth, SSN, address, email, phone number); higher-assurance capabilities such as tradeCrypto additionally require due-diligence fields (citizenship, employment status, occupation, expected volume). See which capabilities require which requirements for the full mapping.
Capability statuses
Each capability is represented as { "requested": boolean, "status": ... }. The status is one of:
| Status | Meaning | What to do |
|---|
unrequested | The capability has not been requested | Request it on a create or update call |
pending | Requested, but one or more requirements are outstanding or verification is still in progress | Resolve outstanding requirements; a recoverable decline also returns here |
active | The customer is authorized for this action | Proceed with the operation |
inactive | Permanently blocked by a compliance decision | No customer action is possible — do not proceed |
A pending status covers both “requirements still outstanding” and “submitted, verification in progress.” Verification is asynchronous, so a capability can stay pending briefly after all requirements are submitted. Use webhooks rather than tight polling to learn when it transitions.
Requesting a capability
Request capabilities in the capabilities map on create or update. Each entry is { "requested": true }:
PUT /v2/customers/{customerId}
{
"capabilities": {
"custodyFiat": { "requested": true }
}
}
The response returns the capability with its current status and lists any outstanding requirements under the customer’s requirements map.
Checking a capability
Capabilities are returned on the customer object. The response includes every capability, both requested and unrequested:
GET /v2/customers/{customerId}
{
"customerId": "customer_af2937b0-9846-4fe7-bfe9-ccc22d935114",
"capabilities": {
"custodyCrypto": { "requested": true, "status": "active" },
"custodyFiat": { "requested": false, "status": "unrequested" },
"custodyStablecoin": { "requested": false, "status": "unrequested" },
"tradeCrypto": { "requested": true, "status": "pending" },
"tradeStablecoin": { "requested": false, "status": "unrequested" },
"transferCrypto": { "requested": true, "status": "active" },
"transferFiat": { "requested": false, "status": "unrequested" },
"transferStablecoin": { "requested": false, "status": "unrequested" }
}
}
Gating operations on a capability
Always confirm a capability is active before initiating the corresponding operation. If it is not active, surface the outstanding requirements to your user and resolve them rather than attempting the operation:
const customer = await getCustomer(customerId);
const capability = customer.capabilities[requiredCapability];
if (capability?.status !== "active") {
// Not yet authorized. Inspect customer.requirements for what is outstanding,
// and resolve it. Do NOT expose compliance-specific reasons to end-users.
throw new Error("Customer is not authorized for this action yet");
}
// Capability is active — proceed with the transfer, trade, or custody operation.
Webhooks
The recommended production pattern is to subscribe to webhooks rather than poll, so your integration reacts as Coinbase processes verification and compliance decisions.
Subscribe to customers.capability.changed to receive capability status transitions. See Customer webhooks for subscription setup, signature verification, and the full event reference. The POST body contains only event-specific fields — eventId, eventType, and delivery timing metadata arrive in HTTP headers instead (Event payloads). A single event can report several capabilities changing at once:
{
"customerId": "customer_bcbd796d-b210-44a2-bb0d-6fea017c1fa0",
"capabilities": [
{ "code": "custodyFiat", "status": "active" },
{ "code": "transferFiat", "status": "active" }
]
}
Other customer events include customers.customer.deleted, customers.kyc_refresh.flagged, and customers.kyc_refresh.completed (see Customer webhooks and Requirements).
Testing capability outcomes in sandbox
In sandbox and test environments you can force deterministic verification outcomes — and the resulting capability statuses (active, pending, inactive) — using magic SSN values. See Testing in sandbox on the Requirements page.
Resolving a pending capability
If a capability is pending, inspect the customer’s requirements map to see what is outstanding. See the Requirements page for the full resolution reference.