API reference
Customers
Create customers, look them up and manage their deposit addresses.
How customers work
Create a customer
/api/partner/{app_id}/users/Create a customer (idempotent).
Body parameters
user_idstringrequiredYour customer ID. 1–64 characters: letters, digits and _ . : @ - only.
Request example
curl -X POST "https://api.moallet.com/api/partner/{app_id}/users/" \
-H "Authorization: ApiKey {client_id}:{client_secret}" \
-H "Content-Type: application/json" \
-d '{
"user_id": "customer-1001"
}'{
"success": true,
"data": {
"user_id": "customer-1001",
"created": true,
"wallets": [
{
"network": {
"id": 8,
"name": "Solana Mainnet",
"symbol": "SOL",
"protocol": "SOL"
},
"address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV"
}
]
},
"error": null
}A new customer returns 201 with created: true. An existing one returns 200 with created: false.
Error codes
INVALID_USER_ID400user_id is missing or has an invalid format.CUSTOMER_API_DISABLED403Customer creation isn't enabled for this app yet. Ask your account manager.CUSTOMER_LIMIT_EXCEEDED403The app's customer limit has been reached.USER_ID_CONFLICT409This user_id can't be used — for example, it belongs to a deactivated customer. Use another ID.WALLET_UNAVAILABLE503An address couldn't be issued right now. Retry the same request shortly.
List customers
/api/partner/{app_id}/users/List customers.
Path parameters
app_idstringrequiredYour app ID (UUID), shown on the app's Developer tab.
Query parameters
pageintegerPage number. Default 1.page_sizeintegerResults per page. Default 50, maximum 100.
Request example
curl "https://api.moallet.com/api/partner/{app_id}/users/?page=1" \
-H "Authorization: ApiKey {client_id}:{client_secret}"{
"success": true,
"data": {
"count": 42,
"next": "https://api.moallet.com/api/partner/3f6c1a52-8d4e-4b7a-9c21-5e0d7b8a9f14/users/?page=2",
"previous": null,
"results": [
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "customer-1001",
"is_active": true,
"connected_at": "2026-10-01T09:30:00Z",
"last_used_at": "2026-10-20T15:45:00Z"
}
]
},
"error": null
}Get a customer
/api/partner/{app_id}/users/{user_id}/Get a customer.
Path parameters
app_idstringrequiredYour app ID (UUID), shown on the app's Developer tab.user_idstringrequiredYour customer ID — the user_id you created the customer with.
Request example
curl "https://api.moallet.com/api/partner/{app_id}/users/{user_id}/" \
-H "Authorization: ApiKey {client_id}:{client_secret}"{
"success": true,
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"user_id": "customer-1001",
"is_active": true,
"connected_at": "2026-10-01T09:30:00Z",
"last_used_at": "2026-10-20T15:45:00Z"
},
"error": null
}List deposit addresses
/api/partner/{app_id}/users/{user_id}/wallets/List a customer's deposit addresses.
Path parameters
app_idstringrequiredYour app ID (UUID), shown on the app's Developer tab.user_idstringrequiredYour customer ID — the user_id you created the customer with.
Query parameters
include_retiredbooleanAlso return addresses that were replaced. Default false.Default:
false
Request example
curl "https://api.moallet.com/api/partner/{app_id}/users/{user_id}/wallets/?include_retired=true" \
-H "Authorization: ApiKey {client_id}:{client_secret}"{
"success": true,
"data": [
{
"network": {
"id": 8,
"name": "Solana Mainnet",
"symbol": "SOL",
"protocol": "SOL"
},
"address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
"is_current": true,
"retired_at": null
},
{
"network": {
"id": 8,
"name": "Solana Mainnet",
"symbol": "SOL",
"protocol": "SOL"
},
"address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
"is_current": false,
"retired_at": "2026-10-18T08:12:00Z"
}
],
"error": null
}Issue a new deposit address
/api/partner/{app_id}/users/{user_id}/wallets/rotate/Issue a new deposit address.
Path parameters
app_idstringrequiredYour app ID (UUID), shown on the app's Developer tab.user_idstringrequiredYour customer ID — the user_id you created the customer with.
No request body is needed.
Request example
curl -X POST "https://api.moallet.com/api/partner/{app_id}/users/{user_id}/wallets/rotate/" \
-H "Authorization: ApiKey {client_id}:{client_secret}"{
"success": true,
"data": {
"network": {
"id": 8,
"name": "Solana Mainnet",
"symbol": "SOL",
"protocol": "SOL"
},
"address": "7EcDhSYGxXyscszYEp35KHN8vvw3svAuLKTzXwCFLtV",
"is_current": true,
"retired_at": null,
"previous_address": "9WzDXwBbmkg8ZTbNMqUxvQRAyrZzDsGYdLVL9zYtAWWM",
"previous_retired_at": "2026-10-22T09:00:00Z"
},
"error": null
}Old addresses keep working indefinitely, so a customer who still has an old address saved never loses a deposit.
Error codes
USER_NOT_FOUND404No active customer with this user_id.ADDRESS_LIMIT409The customer already has the maximum number of addresses.WALLET_UNAVAILABLE503An address couldn't be issued right now. Retry the same request shortly.
Response fields
Customer object
idstring (UUID)Internal ID (UUID).user_idstringYour customer ID.is_activebooleanWhether the customer is active.connected_atstring (ISO 8601)When the customer was created.last_used_atstring | nullThe customer's last API activity.
Address object
networkobjectNetwork: id, name, symbol and protocol.addressstringThe deposit address.is_currentbooleantrue for the address to show your customer; false for a replaced address. Returned with include_retired=true.retired_atstring | nullWhen the address was replaced; null for the current address.
Rotation result
network · address · is_current · retired_atAddress objectThe new current address (is_current: true, retired_at: null).previous_addressstring | nullThe address it replaced — still credited.previous_retired_atstring | nullWhen the previous address was replaced.
Responses can include extra fields kept for compatibility. Ignore any field that isn't documented here.