API reference
Transactions
Read deposits and other movements in your app to keep your own ledger in sync.
Sync by transaction, not by balance
Copying a final balance can miss deposits
- T1 — you read the balance: 100 USDT
- T2 — the customer deposits 50 USDT
- T3 — you store “balance = 100”
- → the 50 USDT deposit is lost
Syncing by transaction (recommended)
- T1 — you read deposits [tx1, tx2] and store the cursor
- T2 — the customer deposits 50 USDT → tx3
- T3 — you read after the cursor: [tx3]
- → every deposit is processed once, in order
Idempotent
Every transaction has a unique id. Record it and the same deposit is never processed twice.
Sequential
Resume from the last id you processed with after_id. Nothing is skipped.
Transaction types
DEPOSITtypeA deposit to one of your customers' addresses. Credited to your pool and to the customer's balance.WITHDRAWALtypeAn on-chain payout from your pool. Its status follows block confirmation.PARTNER_APP_TRANSFERtypeAn internal transfer from your pool to a wallet on our network. tx_hash starts with internal: and there is no on-chain record.
When you credit balances in your own system, apply DEPOSIT rows only. Payouts and internal transfers are movements you started yourself through the API — use those rows for auditing, not for crediting.
List transactions
Returns your app's transactions, newest first. Combine status=SUCCESS with after_id to process deposits incrementally.
GET
/api/partner/{app_id}/transactions/List transactions.
Path parameters
app_idstringrequiredYour app ID (UUID), shown on the app's Developer tab.
Query parameters
statusstringPENDING, SUCCESS or FAILED. Use SUCCESS for syncing.user_idstringOnly this customer's transactions (your user_id).after_idintegerOnly transactions with an id greater than this value — use it as a cursor.orderingstringcreated_at (oldest first) or -created_at (newest first, the default).Default:
-created_atpageintegerPage number. Default 1.page_sizeintegerResults per page. Default 50, maximum 100.
Request example
curl "https://api.moallet.com/api/partner/{app_id}/transactions/?status=SUCCESS&ordering=created_at&after_id={last_id}" \
-H "Authorization: ApiKey {client_id}:{client_secret}"200 OK
{
"success": true,
"data": {
"count": 156,
"next": null,
"previous": null,
"results": [
{
"id": 12345,
"type": "DEPOSIT",
"user_id": "customer-1001",
"to_user_id": "",
"asset": {
"symbol": "USDT",
"network": "Solana Mainnet"
},
"amount": "500.000000000000000000",
"fee": "0",
"tx_hash": "5KtGHnFsLbJxZpQ3mN7vR2wY8dUcAeXhMoPqTiSuVfBk3sRw9nA4bDcEfGhJkLmNpQrStUvWxYz2aB3cD4eF5gH",
"from_address": "5DmYQC3fLxHUpmYbYuRkHFQ2yH4H3kP3VpYWgPMbpnGk",
"to_address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
"status": "SUCCESS",
"created_at": "2026-10-20T14:30:00Z"
},
{
"id": 12346,
"type": "PARTNER_APP_TRANSFER",
"user_id": "",
"to_user_id": "customer-1002",
"asset": {
"symbol": "USDT",
"network": "Solana Mainnet"
},
"amount": "25.000000000000000000",
"fee": "1.000000000000000000",
"tx_hash": "internal:c0ffee00-1234-4abc-9def-000000000000",
"from_address": "POOL",
"to_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
"status": "SUCCESS",
"created_at": "2026-10-20T15:00:00Z"
}
]
},
"error": null
}One customer's transactions
Add user_id to get a single customer's history.
Request example
curl "https://api.moallet.com/api/partner/{app_id}/transactions/?user_id=customer-1001&status=SUCCESS" \
-H "Authorization: ApiKey {client_id}:{client_secret}"Deposits per customer
Totals and deposit lists per customer for a date range — useful for daily or monthly reconciliation.
GET
/api/partner/{app_id}/user-deposits/Deposits grouped by customer.
Query parameters
start_datestringrequiredStart of the range: YYYY-MM-DD or ISO 8601.end_datestringrequiredEnd of the range (inclusive): YYYY-MM-DD or ISO 8601.statusstringPENDING, SUCCESS or FAILED. Default SUCCESS.Default:
SUCCESSpageintegerPage number. Default 1.page_sizeintegerResults per page. Default 50, maximum 100.
Request example
curl "https://api.moallet.com/api/partner/{app_id}/user-deposits/?start_date=2026-10-01&end_date=2026-10-31" \
-H "Authorization: ApiKey {client_id}:{client_secret}"200 OK
{
"success": true,
"data": {
"start_date": "2026-10-01",
"end_date": "2026-10-31",
"total_users": 1,
"page": 1,
"page_size": 50,
"total_pages": 1,
"users": [
{
"user_id": "customer-1001",
"total_deposited": "750.000000000000000000",
"deposit_count": 2,
"deposits": [
{
"id": 12345,
"amount": "500.000000000000000000",
"asset": {
"symbol": "USDT",
"network": "Solana Mainnet"
},
"tx_hash": "5KtGHnFsLbJxZpQ3mN7vR2wY8dUcAeXhMoPqTiSuVfBk3sRw9nA4bDcEfGhJkLmNpQrStUvWxYz2aB3cD4eF5gH",
"from_address": "5DmYQC3fLxHUpmYbYuRkHFQ2yH4H3kP3VpYWgPMbpnGk",
"to_address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
"created_at": "2026-10-20T14:30:00Z"
}
]
}
]
},
"error": null
}Status values
PENDINGstatusSeen on-chain, waiting for confirmations.SUCCESSstatusConfirmed and credited. These are the rows to sync.FAILEDstatusFailed or reverted. Never credited.
Response fields
Transaction object
idintegerUnique transaction id — use it to de-duplicate.typestringDEPOSIT, WITHDRAWAL or PARTNER_APP_TRANSFER.user_idstringThe customer the transaction belongs to (your user_id).to_user_idstringThe receiving customer for transfers, if any.assetobjectAsset: symbol and network.amountstringAmount as a decimal string (up to 18 decimals).feestring | nullFee taken, if any.tx_hashstringThe on-chain signature, or an internal: reference for internal settlement.from_addressstringSending address. Internal movements can carry a placeholder instead of an address.to_addressstringReceiving address.statusstringPENDING, SUCCESS or FAILED.created_atstring (ISO 8601)When the transaction was recorded.
Responses can include extra fields kept for compatibility. Ignore any field that isn't documented here.