End Users
- 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| Concept | Description |
|---|---|
| End user | A 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. |
| Wallet | Groups accounts. The default wallet (isDefault: true) is opened automatically when the end user is created; more wallets can be opened later. |
| Account | Where 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)| Status | Meaning |
|---|---|
ACTIVE | The user can transact. |
FROZEN | No money movement can be started on the user's behalf; the balance is kept. Reversible. Details: Freeze. |
CLOSED | The 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. |
| Action | s2s API | Merchant 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.
| Endpoints | Permission required on the key |
|---|---|
Reads: list, detail, by-external, balances, limit status | wallet: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
| Endpoint | Page |
|---|---|
POST /api/v1/wallet/end-users | Create |
| Creating the same user again | Creating Twice |
GET /api/v1/wallet/end-users | List |
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}/freeze | Freeze |
GET /api/v1/wallet/end-users/{id}/balances | Balances |
GET /api/v1/wallet/end-users/{id}/limits | Limit Status |
POST /api/v1/wallet/end-users/{id}/wallets · POST /api/v1/wallet/wallets/{walletId}/accounts | Wallets & Accounts |
POST /api/v1/wallet/wallets/lookup | Wallet 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.