Quickstart
Your first five API calls, in curl, Go, Python, PHP, JavaScript and Java.
Five API calls: create a user, fund their wallet, check the balance, send money, read the history. Ten minutes end to end with a sandbox key.
Before you start
export WALLETD_API="https://api.walletd.example"
export WALLETD_API_KEY="sk_sandbox_..."Sandbox keys move no real money. Card top-ups run against the processor's test mode, so you can complete the whole flow with a test card. See Testing.
1. Create a wallet user
A wallet user is your user, mirrored. external_id is your identifier and the
only field WalletD needs; it is unique per tenant, so creating the same one
twice is a 409.
curl -sS -X POST "$WALLETD_API/v1/users" \
-H "Authorization: Bearer $WALLETD_API_KEY" \
-H "Content-Type: application/json" \
-d '{"external_id": "user-42", "kind": "consumer", "display_name": "Ada Lovelace", "handle": "ada"}'{
"id": "019fee0b-b5d9-7dd6-945f-337ab9dd09bc",
"external_id": "user-42",
"kind": "consumer",
"display_name": "Ada Lovelace",
"handle": "ada",
"status": "active",
"created_at": "2026-08-11T05:12:44.219Z"
}Keep the returned id. Everything else in the API refers to users by it.
2. Put money in
A top-up creates an intent at a payment gateway.
It does not credit the wallet. The balance rises only when the processor confirms the money arrived. Top-ups covers the full flow, including how your app completes the card payment; here is the first half.
curl -sS -X POST "$WALLETD_API/v1/topups" \
-H "Authorization: Bearer $WALLETD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: topup-user-42-first" \
-d '{"user_id": "019fee0b-b5d9-7dd6-945f-337ab9dd09bc", "amount": 5000, "gateway": "stripe"}'{
"id": "019fee0c-1a2b-7c3d-8e4f-5a6b7c8d9e0f",
"user_id": "019fee0b-b5d9-7dd6-945f-337ab9dd09bc",
"amount": 5000,
"gateway": "stripe",
"status": "created",
"next_action": { "kind": "client_secret", "client_secret": "pi_3U3..._secret_..." },
"created_at": "2026-08-11T05:13:02.881Z"
}amount is 5000 minor units, which is $50.00. Hand
next_action.client_secret to your checkout UI; when the card clears, WalletD
credits the wallet.
3. Read the balance
curl -sS "$WALLETD_API/v1/users/$USER_ID/balances" \
-H "Authorization: Bearer $WALLETD_API_KEY"[
{ "purpose": "cash", "commodity": "USD", "balance": 5000, "available": 5000, "held": 0 },
{ "purpose": "points", "commodity": "POINTS", "balance": 0, "available": 0, "held": 0 }
]A user has one balance per purpose, not one number. available is what they
can spend right now; held is money reserved by an uncaptured authorization.
Show available. See The money model.
4. Send money
curl -sS -X POST "$WALLETD_API/v1/transfers" \
-H "Authorization: Bearer $WALLETD_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: transfer-order-8891" \
-d '{"from_user": "'$SENDER'", "to_user": "'$RECIPIENT'", "amount": 1500, "note": "lunch"}'The Idempotency-Key is required. It comes from your order, so retrying after
a timeout sends once. See Idempotency.
5. Read the history
curl -sS "$WALLETD_API/v1/users/$USER_ID/transactions?limit=20" \
-H "Authorization: Bearer $WALLETD_API_KEY"Newest first, cursor-paged. Every money movement a user was part of appears here with its type, amount, and reference, which is what a support screen needs.
What you just built
You provisioned a wallet, funded it through a real processor, moved money between two wallets, and read the trail. Everything else in this guide is a variation on those four moves.
Next
- Top-ups to finish the money-in flow properly, including webhooks.
- Webhooks so your backend learns about money without polling.
- Payments and refunds to charge for something.
- The money model if
availableversusheldwas surprising.