Create a wallet
Create a wallet — a ledger balance in a single currency for a customer.
This does not create a credential. Add funding rails later with POST /v1/wallets/:id/credentials when you need a persistent receive identity. You can still onramp into a wallet with zero credentials.
If customer_id is omitted, the wallet is created for the merchant.
The currency must support deposit (can_deposit = true).
country_code (optional, ISO 3166-1 alpha-2, e.g. NG) pins the wallet to a country
at creation. It is required only when the same currency code is supported in more than
one country; a single-country currency code (like KES in KE) resolves without it. CRYPTO
currencies (like USDC) always resolve to null — supplying country_code for a crypto
code has no effect. The pinned country is persisted on the wallet, echoed on every wallet
response as country_code, and used by downstream flows (quotes, deposit-addresses) instead
of the customer’s registered country — so a wallet can serve payers who transact from a
country other than the customer’s KYC country.
Balances start at zero, formatted to the currency’s precision. A customer may
hold multiple wallets in the same crypto currency, but only one wallet per fiat
currency; each create returns a new wallet with its own wal_… id. Use the
optional label to tell them apart.
Body
currency— required. 2-8 uppercase alphanumerics (e.g.USDC,NGN).country_code— optional. 2-letter uppercase ISO 3166-1 alpha-2 (e.g.NG).customer_id— Owner customer ID. If omitted, defaults to your account’s default customer — created automatically when you signed up.label— optional. Max 255 chars.metadata— optional. Free-formRecord<string, string>.
Errors
400 invalid_input(was404 not_foundbefore XB-1154) —currency 'X' is not supported. The code isn’t in the supported currency table at all.400 invalid_input—currency 'X' is not supported in country 'Y'. The code exists but the suppliedcountry_codedoesn’t match any row.400 invalid_input—currency 'X' is available in multiple countries (A, B); country_code is required. Supply the pin to disambiguate.
Example
POST /v1/wallets
{
"currency": "USDC"
}
POST /v1/wallets
{
"currency": "NGN",
"country_code": "NG"
}
Authorizations
API key issued during merchant onboarding.
Headers
Optional client-supplied key. Identical key + identical body within 24h replays the original response. Identical key + different body returns 409 idempotency_conflict. The hash is over raw bytes — clients retrying must send the byte-identical body; a re-serialised JSON payload will produce a different hash and a 409. Strongly recommended for retry-safe clients.
^[A-Za-z0-9_\-]{8,255}$Body
CreateWalletDto