Claimable rewards of an account
GET/v1/data/rewards/user
Every reward balance an account can claim, per source and reward token:
- Merkl campaigns (Aave, Morpho, Euler, Dolomite, Fluid, Neverland, LayerBank, … — anything distributed through Merkl),
- Aave-style incentives controllers (Aave forks' native emissions, dTRINITY's rebate, …),
- Flying Tulip FT supply emission,
- Lista DAO emissions — LISTA and partner tokens on Moolah vaults and markets (BNB and Ethereum, all claimed on BNB), the LISTA-holder bonus, Lista Credit's emission and the veLISTA lisUSD borrow rebate. Lista serves its Merkle proofs only against the account's own login signature (Credit's excepted, which is always read), so without
listaSignature+listaMessagethe response carriesauthRequiredwith the exact message topersonal_signinstead of a balance.
claimable is claimable now, pending still accruing; USD values where the token prices. breakdowns attribute each balance to the market that earned it (marketUid, or vault for share-token deposits), using the same resolution that puts the campaign's APR on the market row. A Merkl balance is per token: filtering by marketUid keeps the entry and its breakdown for that market, but the claim pays the whole token balance. claimSupported: false marks a reward the protocol only pays through its own flow (e.g. Neverland locks DUST into veDUST) — claim it in the protocol app. errors lists sources that could not be read; a failed source is never reported as zero. Build the claim with /v1/actions/rewards/claim.
Plain-text reference — GET /v1/data/rewards/user
Parameters
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
account | query | string | yes | The holder. |
chains | query | string | no | Comma-separated chain ids to read (required unless marketUid is given). |
marketUid | query | string | no | Only the rewards one market earned (lender:chainId:ref). Also sets the chain when chains is absent. |
lender | query | string | no | Only the rewards markets of this lender earned (prefix match, e.g. MORPHO_BLUE). See the LenderId schema for the full set of accepted values. |
sources | query | string | no | Comma-separated subset of merkl, aave-incentives, flying-tulip, lista (default: all). |
listaSignature | query | string | no | Lista: the account’s personal_sign over listaMessage (Lista’s own login). Without it the Lista balance is not read and authRequired says what to sign. |
listaMessage | query | string | no | Lista: the signed text, verbatim — <ISO datetime>\nThank you for your support of listaDAO., accepted for 7 days. |
listaSignatureType | query | string | no | Lista: safe when the account is a Safe (EIP-1271). |
Response 200
| Field | Type | Description |
|---|---|---|
success | True | |
data | object | |
data.account | string | |
data.totalClaimableUsd | number | |
data.rewards | object[] | |
data.rewards[].chainId | string | Chain the CLAIM runs on (Merkl may distribute elsewhere than the position). |
data.rewards[].source | merkl, aave-incentives, flying-tulip, lista | |
data.rewards[].sourceId | string | |
data.rewards[].token | object | |
data.rewards[].token.address | string | EVM contract address, lowercase or checksummed hex. |
data.rewards[].token.symbol | string | Token symbol, e.g. WETH. |
data.rewards[].token.decimals | integer | Token decimals — divide raw amounts by 10 ** decimals. |
data.rewards[].token.priceUsd | number | |
data.rewards[].claimable | string | Claimable now. |
data.rewards[].pending | string | Accrued, not claimable yet (Merkl: waits for the next root). |
data.rewards[].claimed | string | Lifetime claimed (Merkl). |
data.rewards[].claimableUsd | number | |
data.rewards[].pendingUsd | number | |
data.rewards[].claimSupported | boolean | false when a dry run of the standard claim reverts — claim in the protocol app (see warning). |
data.rewards[].warning | string | |
data.rewards[].breakdowns | object[] | |
data.rewards[].breakdowns[].market | object | The market a slice of a reward balance came from. Lending markets carry marketUid; vault-shaped deposits carry the share token in vault; Aave-fork incentives also name the aToken/vToken in reserveToken. |
data.rewards[].breakdowns[].amount | string | |
data.rewards[].breakdowns[].claimable | string | |
data.rewards[].breakdowns[].claimed | string | |
data.rewards[].breakdowns[].pending | string | |
data.rewards[].breakdowns[].merklOpportunityId | string | |
data.rewards[].breakdowns[].campaignId | string | |
data.rewards[].breakdowns[].reason | string | |
data.rewards[].claim | object | What the claim calls: merkl (Distributor), aave-incentives (controller + assets), flying-tulip (PositionsManager + assets + FT), lista (BNB Merkle distributor: program lending-v1 | lending | holder | velista-rebate | credit, shape single | multi, cumulative totalAmount, proof). |
data.errors | object[] | Sources that could not be read — NOT a zero balance. |
data.errors[].source | string | |
data.errors[].chainId | string | EVM chain id, as a decimal string. See the ChainId schema. |
data.errors[].error | string | |
data.authRequired | object[] | Sources NOT read because they need the account’s signature first — not a zero balance. Lista: personal_sign the message and pass it back as listaSignature + listaMessage (valid until expiresAt, 7 days). |
data.authRequired[].source | string | |
data.authRequired[].chainId | string | EVM chain id, as a decimal string. See the ChainId schema. |
data.authRequired[].format | personal_sign | |
data.authRequired[].message | string | |
data.authRequired[].expiresAt | integer |
Example response
{
"success": true,
"data": {
"account": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"totalClaimableUsd": 1.0,
"rewards": [
{
"chainId": "1",
"source": "merkl",
"sourceId": "merkl",
"token": {
"address": "0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2",
"symbol": "string",
"decimals": 1,
"priceUsd": 1.0
},
"claimable": "string",
"pending": "string",
"claimed": "string",
"claimableUsd": 1.0,
"pendingUsd": 1.0,
"claimSupported": true,
"warning": "string",
"breakdowns": [
{
"market": {
"chainId": "1",
"marketUid": "DOLOMITE:1:0x8d0d000ee44948fc98c9b98a4fa4921476f08b0d",
"lender": "AAVE_V3",
"underlying": "string",
"reserveToken": "string",
"vault": "string",
"side": "deposit"
},
"amount": "1000000000000000000",
"claimable": "string",
"claimed": "string",
"pending": "string",
"merklOpportunityId": "string",
"campaignId": "string",
"reason": "string"
}
],
"claim": {}
}
],
"errors": [
{
"source": "string",
"chainId": "1",
"error": "string"
}
],
"authRequired": [
{
"source": "string",
"chainId": "1",
"format": "personal_sign",
"message": "string",
"expiresAt": 1,
"description": "string"
}
]
}
}
Request
Responses
- 200
- 400
- 429
- 500
- 502
The account's reward balances
Validation error
Rate limited. Unauthenticated callers share a per-IP budget; send an x-api-key header to lift it. Retry with exponential backoff.
Unexpected server error. Safe to retry with backoff.
An upstream data source or protocol origin failed (error.code is ORIGIN_FAILED). error.details carries the per-origin status. This is also what a missing or malformed required parameter currently returns, rather than a 400.