Skip to Content
RestUsers

Users

Base: /api/v1

Identity model

  • userId in URL paths (for example GET /users/{userId}) and in most JSON bodies (for example POST /getUserPools, POST /getTokenBalance, operations routes) is your external user id: the stable identifier your client uses for that end user (for example client-user-001). It is not Sonar’s internal database id.
  • POST /users uses the JSON field externalUserId for that same value (see request body below). The SDK createOrUpdate method also uses externalUserId.
  • The backend resolves external ids to internal user records for processing.
  • Active chain IDs for filters/balances: 8453, 56, 1, 4663 (Robinhood), 1399811149 (Solana).

POST /users request body

POST /users accepts CreateIntegrationUserDto (see OpenAPI / Swagger). Fields:

FieldTypeRequiredDescription
externalUserIdstringYesExternal user id from your system (partner id).
walletAddressstringNoUser’s wallet address (include when known; omit if you only have externalUserId for now).
emailstringNoUser’s email (validated as email when present).
metadataobjectNoArbitrary key-value metadata (Record<string, unknown>). Example: { "tier": "premium", "segment": "whale" }.
depositChainIdnumberNoPreferred chain id; integer ≥ 1 (for example 8453 for Base).

Minimal calls only need externalUserId. Add walletAddress, email, metadata, or depositChainId when you have them.

Typical status codes

  • 200: success
  • 201: create/update success (POST /users)
  • 401: invalid or missing API key/secret
  • 404: user or pool not found

Endpoints

GET /users — list users

Example response (User[])
[
  {
    "id": 42,
    "externalUserId": "client-user-001",
    "walletAddress": "0x9D8a62F656A8D1615c1294FD71E9cfB3e4855A4F"
  }
]
curl -X GET "https://partners.sonar.trade/api/v1/users" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

GET /users/{userId} — get one user

Example response (User)
{
  "id": 42,
  "externalUserId": "client-user-001",
  "walletAddress": "0x9D8a62F656A8D1615c1294FD71E9cfB3e4855A4F",
  "email": "user@example.com"
}
curl -X GET "https://partners.sonar.trade/api/v1/users/client-user-001" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

POST /users — create or update user

Examples include walletAddress plus other optional fields (email, metadata, depositChainId). Omit any you do not need; externalUserId alone is valid.

curl -X POST "https://partners.sonar.trade/api/v1/users" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"externalUserId":"client-user-001","walletAddress":"0x9D8a62F656A8D1615c1294FD71E9cfB3e4855A4F","email":"user@example.com","metadata":{"tier":"premium","segment":"whale"},"depositChainId":8453}'

POST /getUserPools — user’s pools and balances

getUserPools returns every pool where this user has a deposit, and includes that user’s balance and position in each pool (UserPoolItem with deposits, userBalance, totalBalanceAvailable, tokenValue, volume totals, plus top-level tokenOverallValue / tokenOverallNativeValue / tokenOverallAvailableValue). The response shape is UserPoolsResponse — see Pools — Response and related endpoints on Pools.

curl -X POST "https://partners.sonar.trade/api/v1/getUserPools" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","chainId":8453}'

POST /getTokenBalance — pool token balance for user

Returns this user’s balance for a specific token on a chain: raw string amounts in token base units (same semantics as userBalance, lockedAmount, etc. on pool deposits in getUserPools). Includes pool metadata, optional poolDepositId, and hasDeposit when there is no deposit yet.

Request body (GetTokenBalanceBody):

FieldTypeRequiredDescription
userIdstringYesExternal user id (see Identity model).
tokenAddressstringYesToken contract address on that chain.
chainIdnumberYesChain id (for example 8453 for Base).
Example response (TokenBalanceResponse)
{
  "userId": "client-user-001",
  "tokenAddress": "0x833589fcd6edb6e08f4c7c32d4f71b54bda02913",
  "chainId": 8453,
  "pool": {
    "id": 101,
    "name": "Example Pool",
    "symbol": "EXM",
    "decimals": 18
  },
  "poolDepositId": 55,
  "userBalance": "2500000000000000000000",
  "lockedAmount": "100000000000000000000",
  "availableBalance": "2400000000000000000000",
  "hasDeposit": true
}
curl -X POST "https://partners.sonar.trade/api/v1/getTokenBalance" \ -H "Content-Type: application/json" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>" \ -d '{"userId":"client-user-001","tokenAddress":"0x833589fcd6edb6e08f4c7c32d4f71b54bda02913","chainId":8453}'

Response (TokenBalanceResponse): userId, tokenAddress, chainId, pool (TokenBalancePoolSummary: id, name, symbol, decimals), poolDepositId (or null), userBalance, lockedAmount, availableBalance, hasDeposit.

For getClientPools, GET /pools/{poolId}, and a longer explanation of getUserPools, see Pools.

GET /users/{userId}/balances — list balances

Example response (NativeBalance[])
[
  {
    "chainId": 8453,
    "balance": "1.5",
    "totalClaimableNativeTokens": "0.01"
  }
]
curl -X GET "https://partners.sonar.trade/api/v1/users/client-user-001/balances" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"

GET /users/{userId}/balances/{chainId} — get chain balance

Example response (NativeBalance)
{
  "chainId": 8453,
  "balance": "1.5",
  "totalClaimableNativeTokens": "0.01"
}
curl -X GET "https://partners.sonar.trade/api/v1/users/client-user-001/balances/1399811149" \ -H "X-API-Key: <API_KEY>" \ -H "X-API-Secret: <API_SECRET>"