API reference

Customers

Create customers, look them up and manage their deposit addresses.

How customers work

You create customers yourself with POST /users/, using your own user_id. Your users never sign up anywhere — each customer simply gets a Solana deposit address and a balance.

Create a customer

Creates a customer for your user_id and issues a Solana deposit address. Calling it again with the same user_id doesn't create a duplicate — it returns the existing customer and its current address.
POST/api/partner/{app_id}/users/

Create a customer (idempotent).

Body parameters

  • user_idstringrequired
    Your 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"
  }'
201 Created
{
  "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_ID400
    user_id is missing or has an invalid format.
  • CUSTOMER_API_DISABLED403
    Customer creation isn't enabled for this app yet. Ask your account manager.
  • CUSTOMER_LIMIT_EXCEEDED403
    The app's customer limit has been reached.
  • USER_ID_CONFLICT409
    This user_id can't be used — for example, it belongs to a deactivated customer. Use another ID.
  • WALLET_UNAVAILABLE503
    An address couldn't be issued right now. Retry the same request shortly.

List customers

Returns your app's customers with pagination.
GET/api/partner/{app_id}/users/

List customers.

Path parameters

  • app_idstringrequired
    Your app ID (UUID), shown on the app's Developer tab.

Query parameters

  • pageinteger
    Page number. Default 1.
  • page_sizeinteger
    Results 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}"
200 OK
{
  "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

Returns one customer by your user_id.
GET/api/partner/{app_id}/users/{user_id}/

Get a customer.

Path parameters

  • app_idstringrequired
    Your app ID (UUID), shown on the app's Developer tab.
  • user_idstringrequired
    Your 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}"
200 OK
{
  "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

Returns the customer's deposit addresses. By default you get the current address for each network; add include_retired=true to also list addresses that were replaced. Deposits to any of these addresses are credited to the customer.
GET/api/partner/{app_id}/users/{user_id}/wallets/

List a customer's deposit addresses.

Path parameters

  • app_idstringrequired
    Your app ID (UUID), shown on the app's Developer tab.
  • user_idstringrequired
    Your customer ID — the user_id you created the customer with.

Query parameters

  • include_retiredboolean
    Also 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}"
200 OK
{
  "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

Issues a new deposit address for the customer and makes it the current one. The previous address is not disabled: deposits sent to it are still detected and credited to the same customer. Show the new address to your customer from now on.
POST/api/partner/{app_id}/users/{user_id}/wallets/rotate/

Issue a new deposit address.

Path parameters

  • app_idstringrequired
    Your app ID (UUID), shown on the app's Developer tab.
  • user_idstringrequired
    Your 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}"
201 Created
{
  "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_FOUND404
    No active customer with this user_id.
  • ADDRESS_LIMIT409
    The customer already has the maximum number of addresses.
  • WALLET_UNAVAILABLE503
    An address couldn't be issued right now. Retry the same request shortly.

Response fields

Customer object

  • idstring (UUID)
    Internal ID (UUID).
  • user_idstring
    Your customer ID.
  • is_activeboolean
    Whether the customer is active.
  • connected_atstring (ISO 8601)
    When the customer was created.
  • last_used_atstring | null
    The customer's last API activity.

Address object

  • networkobject
    Network: id, name, symbol and protocol.
  • addressstring
    The deposit address.
  • is_currentboolean
    true for the address to show your customer; false for a replaced address. Returned with include_retired=true.
  • retired_atstring | null
    When the address was replaced; null for the current address.

Rotation result

  • network · address · is_current · retired_atAddress object
    The new current address (is_current: true, retired_at: null).
  • previous_addressstring | null
    The address it replaced — still credited.
  • previous_retired_atstring | null
    When the previous address was replaced.

Responses can include extra fields kept for compatibility. Ignore any field that isn't documented here.