Campaign Identity
A campaign is identified by a compound key, not a single scalar ID:"chainId:campaignIndex", so { chainId: 8453, campaignIndex: 56 } becomes "8453:56". The SDK does that conversion for you; every method takes the object form.
configHash, the keccak256 commitment of its configuration that was submitted on-chain. If you want to verify a campaign’s parameters independently, recompute the hash and compare.
Event Chain Versus Reward Chain
Two chains matter for every campaign, and confusing them is the most common integration bug.
They are the same for most campaigns. They differ for cross-chain campaigns, such as positions tracked on Polygon with rewards claimed on Worldchain.
The operating rule:
- Filtering campaigns by vault or pool address? Use the event chain.
- Connecting a wallet to claim? Use the reward chain.
Lifecycle and Claimability
For the business-facing view of these phases (what a creator can change in each, and when budget becomes recoverable), see Campaign Lifecycle.
Reading Accrual From the API
Rewards are computed off-chain by Boost’s indexers from on-chain events. You never reproduce the math; you read a field.
Two properties of the accrual engine matter when you build a UI:
- Earnings are continuous and already exact.
accumulatedRewardsreflects every second up to the latest on-chain event or price checkpoint. There is no per-second feed to poll. - There is no retroactive credit. Time a user was not holding is time they did not accumulate, which is why, at equal size, an earlier holder out-earns a later one.
For priced targets such as prediction-market shares or LP positions,
balance is the position’s value, not its raw token count, and it drifts with price checkpoints even when the user does not trade. Plain ERC-20 targets count raw token units.Modes as Data
campaign.modes is a keyed object. A key is present only when that mode is enabled, and {} means a plain pro-rata campaign. Modes compose, so a campaign can carry several at once.
Units.
*Bps fields are basis points (1250 = 12.5%). *Usd fields are USD with 6 decimals. Bare balance fields are raw target-token units. earningCap.maxRewards is the exception: it caps rewards, so it is denominated in reward-token units.
For what each mode is for (the campaign-design view rather than the data view), see Campaign Modes.
Targets
campaign.target describes the position being tracked. Its shape varies by tokenStandard, and fields that do not apply to a standard are omitted entirely rather than set to null:
Match on
target.address for ERC-20 style targets and on target.poolId for Uniswap v4 pools.
shareModel on a v4 target says how an LP’s slice is computed. Treat it as an open string rather than a closed set:
What Discovery Returns
campaigns.list and campaigns.active exclude campaigns that require a Forwarder deposit unless you pass includeForwarderRequired: true. That keeps integrations from surfacing campaigns their users cannot earn from. campaigns.get returns any campaign regardless of the flag.
This is a visibility convention for partner discovery, not an authorization boundary. If you already have a campaign ID,
campaigns.get and campaigns.stats still work, and rewards.forUser and claims.get still return that user’s financial data.Keep Exploring
How Claiming Works
Merkle roots, cumulative amounts, and the three reward numbers.
Data Conventions
Wire formats, bigint amounts, and pagination.
Forwarder Deposits
Routing deposits for campaigns that require them.