Create User Wallet
Asks for one more custody wallet for the user, on the chain named by chain_id. This is a create, not an upsert: a user may hold several wallets (one per chain, and more than one on the same chain), so an existing wallet is never replaced and never a reason to refuse.
The call is asynchronous. 202 means the request was accepted. The custody provider creates the wallet on the chain's default network; it then appears in List User Wallets with custody: true, and the platform sends its KYC token to the new wallet on every network of the chain. The request is not idempotent: sending it twice creates two wallets.
Required permission: user:update
Request
POST /v2/users/{user_id}/wallets
Parameters
| Name | Type | In | Description |
|---|---|---|---|
user_id | string | path | Required. User ID |
Headers
| Name | Description |
|---|---|
Authorization | Required. Bearer <access_token> |
Content-Type | Required. application/json |
Body
| Field | Type | Required | Description |
|---|---|---|---|
chain_id | string | Yes | Chain (24-character hex chains id) to create the wallet on. Must have a default network. Chains are listed by GET /v2/chains |
label | string | No | Name shown in the wallet list; how a user with several wallets on one chain tells them apart |
Example
curl --request POST \
--url '{{baseUrl}}/v2/users/6a87455ad5f439809d488ac3/wallets' \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--data '{
"chain_id": "6740e0a10000000000000101",
"label": "Main wallet"
}'
Response
Status Code: 202 Accepted, empty body. Poll List User Wallets until the wallet appears.
Errors
| Status | Code | Description |
|---|---|---|
| 400 | 10015 | Validation failed (chain_id missing or not 24 hex characters) — see details |
| 400 | 10016 | user_id is not a valid id |
| 400 | 10001 | User not found (domain 1) |
| 400 | 10015 | chain not found, or chain has no default network configured |
See Errors for the error format and common codes.