WaaS API Reference
Base URL: https://payments-api-dev-966260606560.europe-west2.run.app
Auth: X-API-Key header for all WaaS endpoints
Customer Wallet Management
Create Customer HD Wallet
POST /api/v1/wallet/customers
Creates a BIP39 HD wallet for a customer. The mnemonic is encrypted at rest and returned only on creation.
POST /api/v1/wallet/customers
X-API-Key: live_sk_...
Content-Type: application/json
{
"customer_id": "user_12345",
"word_count": 12
}| Field | Type | Required | Description |
|---|---|---|---|
customer_id | string | ✅ | Your internal customer identifier (email, UUID, or any string) |
word_count | integer | — | 12 or 24 BIP39 words (default: 12) |
Response 200 OK
{
"customer_id": "user_12345",
"wallet_id": 42,
"mnemonic": ["word1", "word2", "...", "word12"],
"created_at": "2026-06-25T14:00:00Z"
}⚠️ Store the mnemonic immediately. It is shown once only and cannot be retrieved without the
wallet:reveal_seedAPI permission.
Error 402 Payment Required
{ "error": "subscription expired — please renew your plan to continue" }Error 403 Forbidden
{
"error": "Wallet address limit reached for your current plan. Please upgrade to add more customer wallets.",
"code": "WALLET_LIMIT_EXCEEDED"
}List All Customer Wallets
GET /api/v1/wallet/customers
GET /api/v1/wallet/customers?page=1&limit=20&search=user_
X-API-Key: live_sk_...| Parameter | Type | Default | Description |
|---|---|---|---|
page | integer | 1 | Page number |
limit | integer | 20 | Results per page |
search | string | — | Filter by customer_id |
Response 200 OK
{
"customers": [ { "customer_id": "user_12345", "wallet_id": 42, "created_at": "..." } ],
"total": 87,
"page": 1,
"limit": 20
}Address Derivation
Derive a Blockchain Address
POST /api/v1/wallet/{customerID}/derive
Derives a new blockchain address for a customer wallet at the specified BIP-44 derivation index.
Set enable_monitoring: true to automatically subscribe this address to the deposit monitor — incoming transactions will fire wallet.deposit.detected and wallet.deposit.confirmed webhooks.
POST /api/v1/wallet/user_12345/derive
X-API-Key: live_sk_...
Content-Type: application/json
{
"network": "ETH",
"index": 0,
"is_testnet": false,
"enable_monitoring": true
}| Field | Type | Required | Description |
|---|---|---|---|
network | string | ✅ | BTC, BCH, LTC, BSC, ETH, POL, TRX, SOL, XRP |
index | integer | — | BIP-44 address index (default: 0) |
is_testnet | boolean | — | Use testnet address space (default: false) |
enable_monitoring | boolean | — | Subscribe to deposit webhooks (default: false) |
Response 200 OK
{
"customer_id": "user_12345",
"network": "ETH",
"address": "0x1a2b3c4d5e6f7890abcdef1234567890abcdef12",
"index": 0,
"derivation_path": "m/44'/60'/0'/0/0",
"is_testnet": false,
"monitored": true
}Error 402 — Subscription expired
Error 404 — Wallet not found for this customer_id
Error 400 — Invalid network
Deposit Lifecycle (when enable_monitoring: true)
| Status | safe_to_credit | Webhook | Action |
|---|---|---|---|
detected | false | wallet.deposit.detected | Show "pending" to customer — do not credit |
confirmed | true | wallet.deposit.confirmed | Credit customer account |
Always check
safe_to_credit: truebefore crediting. Never credit onwallet.deposit.detected.
Confirmation Method by Network
| Network | Method | Typical Settlement Time |
|---|---|---|
| ETH | Block depth | ~3 minutes |
| BSC | Block depth | ~30 seconds |
| POL | Block depth | ~60 seconds |
| BTC | Block depth (Esplora) | ~30 minutes |
| LTC | Time-based settlement | ~10 minutes |
| BCH | Time-based settlement | ~30 minutes |
| TRX | Time-based settlement | ~60 seconds |
| SOL | Time-based settlement | ~15 seconds |
| XRP | Time-based settlement | ~30 seconds |
List Addresses for a Customer
GET /api/v1/wallet/{customerID}/addresses
GET /api/v1/wallet/user_12345/addresses?refresh=true
X-API-Key: live_sk_...| Parameter | Type | Description |
|---|---|---|
refresh | boolean | Trigger live on-chain balance refresh for all addresses (default false) |
Response 200 OK
{
"customer_id": "user_12345",
"addresses": [
{
"id": 101,
"address": "0x1a2b...",
"network": "ETH",
"address_index": 0,
"derivation_path": "m/44'/60'/0'/0/0",
"monitored": true,
"total_received": "500.00",
"balances": [
{ "currency": "ETH", "amount": "0.0012" },
{ "currency": "USDT", "amount": "500.00" }
]
}
],
"total": 3
}List All Addresses (All Customers)
GET /api/v1/wallet/addresses
Returns all derived addresses across every customer wallet.
GET /api/v1/wallet/addresses?network=ETH¤cy=USDT&page=1&limit=20
X-API-Key: live_sk_...| Parameter | Type | Description |
|---|---|---|
network | string | Filter by network code |
currency | string | Filter by currency |
search | string | Search by address or customer ID |
page | integer | Page number (default 1) |
limit | integer | Results per page (default 20) |
Transfers & Sending
Send Crypto from Customer Wallet
POST /api/v1/wallet/{customerID}/transfer
Broadcasts a blockchain transaction from the customer's derived address.
POST /api/v1/wallet/user_12345/transfer
X-API-Key: live_sk_...
Content-Type: application/json
{
"network": "ETH",
"currency": "USDT",
"to_address": "0xRecipientAddress...",
"amount": "100000000",
"index": 0
}| Field | Type | Required | Description |
|---|---|---|---|
network | string | ✅ | BTC, BCH, LTC, BSC, ETH, POL, TRX, SOL, XRP |
currency | string | ✅ | Token or native currency (e.g. "USDT", "ETH", "BTC") |
to_address | string | ✅ | Recipient blockchain address |
amount | string | ✅ | Amount as a string — send "2.5" (human-readable, auto-converted) or "2500000000000000000" (pre-converted base units) |
index | integer | — | Address derivation index (default 0) |
Amount format: Pass either a human-readable decimal ("2.5") or a pre-converted integer in the network's smallest unit ("2500000000000000000"). The API converts decimal input automatically.
Decimal places by network and currency:
| Network | Currency | Decimals | 1 unit in base units |
|---|---|---|---|
| ETH | ETH | 18 | "1000000000000000000" |
| ETH | USDT, USDC | 6 | "1000000" |
| BSC | BNB | 18 | "1000000000000000000" |
| BSC | USDT, USDC | 18 | "1000000000000000000" |
| POL | POL | 18 | "1000000000000000000" |
| POL | USDT, USDC | 6 | "1000000" |
| TRX | TRX, USDT | 6 | "1000000" |
| SOL | SOL | 9 | "1000000000" |
| SOL | USDC | 6 | "1000000" |
| BTC, LTC, BCH | native | 8 | "100000000" |
| XRP | XRP | 6 | "1000000" |
Response 200 OK
{
"tx_hash": "0xabc123def456...",
"network": "ETH",
"currency": "USDT",
"amount": "100000000",
"to_address": "0xRecipient...",
"status": "submitted"
}Error 500 — Broadcast failed: insufficient funds, no UTXOs, unfunded account, incorrect amount format
Requires
wallet:transferAPI key permission.
Estimate Gas Fee
POST /api/v1/wallet/estimate-gas
Estimates the gas cost for an EVM transfer. No authentication required.
Only supports EVM networks: BSC, ETH, POL.
POST /api/v1/wallet/estimate-gas
Content-Type: application/json
{
"network": "ETH",
"currency": "USDT",
"from_address": "0xSenderAddress...",
"to_address": "0xRecipientAddress...",
"amount": "100000000"
}Response 200 OK
{
"gas_limit": "65000",
"gas_price": "20000000000",
"estimated_fee": "0.0013",
"estimated_fee_usd": "3.50"
}Fee Collection Configuration
WaaS allows you to collect a percentage fee from your customers on every deposit or transfer, sent directly on-chain to your own addresses.
Get Current Fee Configuration
GET /api/v1/wallet/fees
GET /api/v1/wallet/fees
X-API-Key: live_sk_...Response 200 OK
{
"fee_percent": "0.01",
"is_enabled": true,
"fee_addresses": {
"ETH": "0xYourEthAddress...",
"BSC": "0xYourBscAddress...",
"POL": "0xYourPolAddress...",
"TRX": "TYourTronAddress...",
"SOL": "YourSolanaAddress...",
"BTC": "bc1YourBtcAddress...",
"XRP": "rYourXrpAddress..."
}
}Set Fee Configuration
POST /api/v1/wallet/fees
Enable fee collection and set your percentage and receiving addresses in a single call.
POST /api/v1/wallet/fees
X-API-Key: live_sk_...
Content-Type: application/json
{
"fee_percent": "0.01",
"is_enabled": true,
"fee_addresses": {
"POL": "0xYourPolAddress...",
"ETH": "0xYourEthAddress..."
}
}| Field | Type | Required | Description |
|---|---|---|---|
fee_percent | string | ✅ | Fee as a decimal — "0.01" = 1%, "0.005" = 0.5%. Maximum "0.5" (50%) |
is_enabled | boolean | ✅ | true to activate fee collection |
fee_addresses | object | — | Map of network → your receiving address. Omitted networks will not have fees collected |
Response 200 OK
{
"fee_percent": "0.01",
"is_enabled": true,
"fee_addresses": { "POL": "0x...", "ETH": "0x..." }
}Fee collection only applies to networks where you have configured a receiving address. If no address is set for a network, fees are skipped on that network even if
is_enabled: true.
Update Settlement Addresses Only
PUT /api/v1/wallet/fees/addresses
Update the per-network receiving addresses without changing your fee percentage or enabled status.
PUT /api/v1/wallet/fees/addresses
X-API-Key: live_sk_...
Content-Type: application/json
{
"addresses": {
"SOL": "YourNewSolanaAddress...",
"TRX": ""
}
}Pass "" (empty string) for a network to remove its fee address and stop collecting on that network.
View Earnings
GET /api/v1/wallet/earnings
Returns a summary of fees collected across all networks, plus recent fee records.
GET /api/v1/wallet/earnings
X-API-Key: live_sk_...Response 200 OK
{
"total_fees_by_currency": [
{ "currency": "USDT", "network": "ETH", "total_amount": "150.50", "count": 42 },
{ "currency": "POL", "network": "POL", "total_amount": "8.20", "count": 12 }
],
"recent_fees": [...],
"total_transfers": 54
}Transaction History
Get Customer Transaction History
GET /api/v1/wallet/{customerID}/transactions
GET /api/v1/wallet/user_12345/transactions?network=ETH¤cy=USDT&status=confirmed&page=1&limit=20
X-API-Key: live_sk_...| Parameter | Type | Description |
|---|---|---|
network | string | Filter by network |
currency | string | Filter by currency |
status | string | Filter by status |
page | integer | Page number (default 1) |
limit | integer | Results per page (default 20) |
Seed & Key Management
Retrieve Customer Seed Phrase
GET /api/v1/wallet/{customerID}/seed
Returns the BIP39 mnemonic for a customer's wallet.
⚠️ Requires
wallet:reveal_seedAPI key permission. Handle with extreme care — anyone with the mnemonic controls all funds in the wallet.
GET /api/v1/wallet/user_12345/seed
X-API-Key: live_sk_...Response 200 OK
{
"customer_id": "user_12345",
"mnemonic": ["word1", "word2", "...", "word12"],
"word_count": 12
}Error 404 — Wallet not found
Export Private Key for Address
POST /api/v1/wallet/{customerID}/export-key
Returns the raw private key for a specific derived address.
⚠️ Requires
wallet:export_keyAPI key permission. Use only when the customer explicitly requests it (e.g., wallet export to external app). Never log or transmit private keys.
POST /api/v1/wallet/user_12345/export-key
X-API-Key: live_sk_...
Content-Type: application/json
{
"network": "ETH",
"index": 0
}Response 200 OK
{
"address": "0x1a2b3c...",
"private_key": "0xabcdef1234...",
"network": "ETH"
}