Wallet
End users
Overview

End Users

Who calls these endpoints?External API (s2s)
Base path
/api/v1/wallet
Identity
Ed25519 request signature — X-Key-Id, X-Date, X-Nonce, Digest (when there is a body), X-Signature. ±5 min clock window, single-use nonce, optional per-key IP allow-list.
Authorization
The key must carry the wallet product and the wallet permission the call requires; a call without it gets 403 WALLET_INSUFFICIENT_SCOPE. Permissions per endpoint: Key permissions.
Cross-surface
The endpoints in this section are on the s2s surface; the reads and freeze also exist in the panel. Unfreezing and closing are merchant-panel only: Panel — End Users.

An end user is the person or business that holds a wallet in your program. Every money-movement endpoint acts on behalf of an end user, so your integration starts by creating one.

Model

End user (endUser)                      — unique by phone within a program
 └─ Wallet                              — 10-digit walletNo; the first one is the default wallet
     └─ Account                         — one account per currency per wallet
ConceptDescription
End userA person (PERSONAL) or a business (BUSINESS). Belongs to one program. The phone number is not stored in plain text; only a one-way digest for lookups and a masked form are kept.
WalletGroups accounts. The default wallet (isDefault: true) is opened automatically when the end user is created; more wallets can be opened later.
AccountWhere the money sits. Each account has a single currency; a wallet cannot hold a second account in the same currency. The account number is fullWalletNo = walletNo + a 4-digit account code.

The default wallet opens with a single account: in the currency you send in the request, or in your program's main currency. The program's other currencies are not opened automatically; add them by opening an account when needed.

externalCustomerId — your identifier

When you create an end user you can send the customer id from your own system as externalCustomerId. This value:

  • Is unique within a program: two end users in the same program cannot carry the same externalCustomerId. In a different program the same value may identify a different person.
  • Is case-sensitive; only leading and trailing whitespace is trimmed.
  • Lets you reach the user without storing our id: GET end-users/by-external/{externalCustomerId}.

externalCustomerId is optional but recommended. If a network error hides the result of a request, this is how you find the user — see Creating Twice.

Statuses and lifecycle

ACTIVE ──freeze──▶ FROZEN ──unfreeze──▶ ACTIVE
   │                  │
   └──────close───────┴──────────────▶ CLOSED (final)
StatusMeaning
ACTIVEThe user can transact.
FROZENNo money movement can be started on the user's behalf; the balance is kept. Reversible. Details: Freeze.
CLOSEDThe user and all their wallets and accounts are closed. Closing requires every account balance to be zero. There is no way back from this status.
Actions2s APIMerchant panel
Create✅ POST end-users✅
Freeze✅ POST end-users/{id}/freeze✅
Unfreeze—✅
Close—✅

Required permissions

Every request is signed with Ed25519, GET requests included. After the signature is verified, your key must carry the permission the call requires; otherwise the request is rejected with 403 WALLET_INSUFFICIENT_SCOPE.

EndpointsPermission required on the key
Reads: list, detail, by-external, balances, limit statuswallet:enduser:read (or any wallet read permission such as wallet:program:read)
Create, freeze, open wallets and accounts, wallet lookup (POST wallets/lookup)wallet:enduser:manage or wallet:program:manage

A read permission does not grant write access. All permissions: Key permissions.

Endpoints

EndpointPage
POST /api/v1/wallet/end-usersCreate
Creating the same user againCreating Twice
GET /api/v1/wallet/end-usersList
GET /api/v1/wallet/end-users/{id} · GET /api/v1/wallet/end-users/by-external/{externalCustomerId}Detail & Lookup
POST /api/v1/wallet/end-users/{id}/freezeFreeze
GET /api/v1/wallet/end-users/{id}/balancesBalances
GET /api/v1/wallet/end-users/{id}/limitsLimit Status
POST /api/v1/wallet/end-users/{id}/wallets · POST /api/v1/wallet/wallets/{walletId}/accountsWallets & Accounts
POST /api/v1/wallet/wallets/lookupWallet Lookup

Reading and raising the KYC level is covered in KYC Levels; linking employees to an employer is covered in Corporate Accounts.

Every call made with an end-user id that belongs to another merchant, or does not exist at all, gets the same response: 404 WALLET_NOT_FOUND. The response does not reveal whether the record exists in another account.