API reference

Analytics

One call, eight sections, no parameters. Protocol-wide totals grouped by quote asset, the live protocol configuration, and a day series built from indexed events rather than from account snapshots.

The eight sections#

KeyWhat it is
byQuoteevery counter, summed across policies, grouped by quote mint
feesClaimedUsdTotala blended USD total, or an absent figure explaining why it is withheld
policiestotal, locked, agentMode, passiveMode
openPositionsCountRemote venue accounts with non-zero attested equity
bridgeFlowByPolicyquote sent out and returned, per policy
attestationFreshnessper Remote venue account, how old the attestation is
protocolConfigthe live Config account snapshot
revenueByDayTimeSeriesper quote mint, per day, from indexed events

byQuote#

Counters are summed within a quote mint and never across them, because the base units of two different stocks are not the same unit and adding them would be meaningless. Each counter is a figure with an explicit (summed) source.

GET /analytics, one byQuote entry
{
  "quoteMint": "6CKzmJFjFctSQyWhvNVb8pX2brcBBoD5yEwk8nxrsNqA",
  "quoteSymbol": "FIXXHNE6",
  "quoteName": "Fixture Stock HNE6",
  "quoteDecimals": 8,
  "quoteSymbolSource": "chain:quote mint Token-2022 metadata",
  "quoteIconUrl": null,
  "quoteIconSource": null,
  "policyCount": 1,
  "feesClaimed":      { "value": "0",         "source": "chain:Policy.fees_claimed (summed)" },
  "protocolFees":     { "value": "50000000",  "source": "chain:Policy.protocol_fees (summed)" },
  "routedToLp":       { "value": "0",         "source": "chain:Policy.routed_to_lp (summed)" },
  "routedToBankroll": { "value": "665000000", "source": "chain:Policy.routed_to_bankroll (summed)" },
  "profitSwept":      { "value": "399000000", "source": "chain:Policy.profit_swept (summed)" },
  "paidToHolders":    { "value": "0",         "source": "chain:Policy.paid_to_holders (summed)" },
  "tokensBurned":     { "value": "250000000", "source": "chain:Policy.tokens_burned (summed)" },
  "quoteUsdPrice": null,
  "priceObservedAt": null
}

tokensBurned is grouped by quote but denominated in base

Every other counter in the entry is in the quote asset's base units, at quoteDecimals. tokensBurned counts the launched token, at that token's own decimals, which is typically 6 rather than 8. It is grouped under a quote mint because the policy is, not because the unit matches.

feesClaimedUsdTotal, and why it is withheld#

This is the clearest example in the API of refusing to serve a number that would be wrong.

GET /analytics, feesClaimedUsdTotal
{
  "value": null,
  "source": "computed",
  "asOf": null,
  "absent": true,
  "reason": "one or more quote mints in use have no cached StonkFun price yet; a blended USD total would understate reality, so it is withheld rather than shown short"
}

A blended total across quote assets needs a USD price for every one of them. If one is missing, summing the rest produces a number that is smaller than the truth and looks perfectly credible. So the endpoint reports nothing and says which condition caused it.

protocolConfig#

The live Config account, which is where most protocol-wide limits live.

GET /analytics, protocolConfig
{
  "paused": false,
  "protocolFeeBps": 500,
  "maxBankrollBps": 8000,
  "maxRemoteStaleness": "120",
  "maxDeviationBps": 2000,
  "minRiskForClass": [0, 0, 0, 10, 80, 80, 0, 0],
  "launchlabProgram": "LanMV9sAd7wArD4vJFi2qDdfnVhFxYSUg6eADduJ3uj",
  "ammProgram": "cpamdpZCGKUy5JxQXB4dcpGPiikHawvSWAd6mEn1sGG",
  "source": "chain:Config account snapshot",
  "asOf": "2026-09-23T01:34:12.751Z"
}
FieldUnitChangeable?
protocolFeeBpsbasis points of claimed feesYes, up to a hard ceiling of 2000
maxBankrollBpsbasis points, the ceiling on a policy's to_bankroll_bpsYes
maxRemoteStalenesssecondsYes
maxDeviationBpsbasis points between consecutive attestationsYes
minRiskForClassrisk 0 to 100, indexed by asset class bitNo. Set at initialize and immutable.
launchlabProgramaddressYes
ammProgramaddressYes

maxRemoteStaleness is serialised as a string because it is an i64 on chain. The one field no admin can ever change is minRiskForClass, which is why the 80 on the PERP and OPTION slots is a permanent property of this deployment. See risk, origins and asset classes.

bridgeFlowByPolicy#

GET /analytics, bridgeFlowByPolicy
[
  { "mint": "AUCgvtVBJNRaZXAqGuhRM8smJoqtXtNhiRzJ9m7zkL4x", "outQuote": "50000000000", "inQuote": "0" }
]

outQuote is the sum of VenueAccount.bridged_out for that policy: quote that has left the bankroll for a Remote venue. It is incremented at the moment of the transfer, not when a relayer moves anything. The gap between outQuote and inQuote is the exposure the design makes visible on purpose, and is discussed on remote equity and attestation.

revenueByDayTimeSeries#

Per quote mint, per day, built by summing indexed events rather than by sampling account snapshots. That distinction matters and the response states it in its own metadata.

GET /analytics, revenueByDayTimeSeries
{
  "source": "chain:FeesClaimed / Routed / ProfitSwept events, bucketed by block_time",
  "perQuoteMint": true,
  "unit": "the quote asset's own base units; divide by that quote's decimals",
  "measures": ["feesClaimed", "protocolFees", "routedToLp", "routedToBankroll", "profitSwept"],
  "measuresWithNoEvents": ["feesClaimed"],
  "series": [
    {
      "quoteMint": "6CKzmJFjFctSQyWhvNVb8pX2brcBBoD5yEwk8nxrsNqA",
      "quoteSymbol": "FIXXHNE6",
      "quoteSymbolSource": "chain:quote mint Token-2022 metadata",
      "quoteDecimals": 8,
      "quoteIconUrl": null,
      "dayCount": 1,
      "days": [
        { "day": "2026-09-22", "feesClaimed": "0", "protocolFees": "50000000",
          "routedToLp": "285000000", "routedToBankroll": "665000000", "profitSwept": "1065000000" }
      ]
    }
  ]
}

measuresWithNoEvents distinguishes a flat line from no line

A measure listed there has produced no events at all, so its zeros are "nothing has happened" rather than "the value is zero". A chart can then draw a gap instead of a flat line along the axis, which is the difference between an honest chart and a misleading one.

A quote mint with dayCount: 0 and an empty days array is a quote with policies but no events yet. It is still listed, rather than dropped, so a client can see it exists.

Two fields that mean something different here#

profitSwept in the day series is not Policy.profit_swept

The series sums the profit field of ProfitSwept events, which is the whole amount above the high water mark. The account counter Policy.profit_swept accumulates moved, which is what physically left the bankroll and can be smaller when the shortfall rule bites.

On the fixture policy above they read 1,065,000,000 and 399,000,000 respectively, and both are correct for what they measure. See profit and the high water mark.

routedToLp in the day series is not Policy.routed_to_lp either

The series sums to_lp from Routed events, which is what route earmarked for the LP. The account counter is incremented by compound_lp with the measured amount it actually pushed into the position. Above, that is 285,000,000 against 0.

Which one to use#

For "what has this policy earned", use the account counters from /coins/:mint: they are the chain's own arithmetic and cannot drift. For "what happened on which day", use the series: account snapshots carry no history at all. Do not add one to the other.