API reference

Reference data

Three endpoints with no parameters worth speaking of, backing a launch form: which origins exist, which models exist, and which pairs can be quoted against.

GET /origins#

Every Origin account on chain, ordered by id. No parameters. Origins are append-only and can never be edited or removed, so this list only ever grows.

GET /origins
{
  "source": "chain:Origin accounts",
  "items": [
    {
      "id": 1,
      "pubkey": "4LjMhsTWQrwqLPbHY6z5gf1CCxVennQcMSKmwTpfAw5g",
      "name": "stocks-only",
      "asset_class_mask": 79,
      "max_risk": 100
    }
  ]
}
id
u8
The registry id. Also the PDA seed: ["origin", id].
pubkey
string
The origin account address, so a client can pass it to init_policy without deriving it.
asset_class_mask
u32
A bitwise OR of the asset class bits this origin permits. See risk, origins and asset classes for the bit values.
max_risk
u8
The ceiling on Policy.risk for policies of this origin.

Field naming is snake_case here, and camelCase elsewhere

This endpoint returns the database row shape directly, so its keys are asset_class_mask and max_risk. The same concepts appear as assetClassMask and maxRisk inside /coins/:mint. That is an inconsistency in the API, not a difference in meaning.

GET /models#

Every Model account on chain, ordered by id. No parameters. Currently 21 entries across 9 providers.

GET /models
{
  "source": "chain:Model accounts",
  "items": [
    { "id": 1, "name": "GPT-5.5",       "provider": "OpenAI",    "enabled": true, "registeredAt": "2026-09-23T00:08:28.000Z" },
    { "id": 5, "name": "Claude Opus 5", "provider": "Anthropic", "enabled": true, "registeredAt": "2026-09-23T00:08:30.000Z" },
    { "id": 9, "name": "Llama",         "provider": "Meta",      "enabled": true, "registeredAt": "2026-09-23T00:08:32.000Z" }
  ]
}
id
u16
PDA seed: ["model", id], little-endian. This is the value written to Policy.model_id.
enabled
boolean
Whether the model can be picked at launch right now. A disabled model blocks init_policy and set_policy, and does not affect policies already pointing at it.
registeredAt
ISO 8601 string
Block time of the transaction that last wrote this entry, from the indexer. Not a field on the account. Because register_model overwrites in place, this is a last-changed time rather than a created time.

There is no price here, and there is not going to be. Prices live off chain and are documented on compute costs.

GET /quotes#

StonkFun's launchable pair catalogue, polled into the indexer.

ParameterTypeDefaultEffect
searchstringnoneCase-insensitive substring match against symbol or name. Omit it to get the whole catalogue.

Ordered by policy count descending, then symbol ascending, and hard-capped at 600 rows. There is no offset.

GET /quotes?search=SPY
{
  "source": "stonkfun:/pairs + /launchlab/pricing",
  "items": [
    {
      "mint": "XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W",
      "symbol": "SPYX",
      "name": "SP500",
      "decimals": 8,
      "category": "xstock",
      "launchable": true,
      "launchLabReady": true,
      "logoUrl": "https://www.stonkfun.xyz/api/asset/quote-logo/XsoCS1TfEyfFhfvj8EtZ528L3CaKBDBRqRapnBbDF2W?v=c2b8ddb3",
      "policyCount": 0,
      "startMarketCapUsd": null,
      "graduationMarketCapUsd": null,
      "graduationMultiple": null
    }
  ]
}
category
string
StonkFun's own label. Observed values are custom, backpack, xstock, prestock, currency, solana, collectible, tessera and leverage.
policyCount
number
How many indexed policies are quoted in this mint. This is what the default ordering sorts by, so pairs in use float to the top.
logoUrl
string | null
Absolute already. StonkFun serves this as a path that returns 404 anywhere but its own origin, so the poller resolves it once rather than every client rediscovering that.
priceUsd
Figure, optional
Present only when a cached StonkFun price exists for the quote. The key is omitted entirely rather than set to null when there is none, which is the one place in the API where absence is expressed by omission.

Not every listed pair can actually launch

The endpoint reports launchable and launchLabReady as StonkFun reports them, and every one of the 509 rows read on 2026-09-23 is true for both. It does not report the mint's token program, and 222 of the 509 are classic SPL, which init_policy cannot pair. The catalogue moves, so re-derive that split rather than quoting it. See quote assets and pairs.

Where a quote's name comes from#

Elsewhere in the API a quote mint appears attached to a policy, and it needs a symbol. Two sources are tried in order, and the response always says which one it got.

OrderSourceReported as
1StonkFun's /pairs catalogue"stonkfun:/pairs catalogue"
2the quote mint's own Token-2022 metadata extension"chain:quote mint Token-2022 metadata"
neithernothingquoteSymbolSource: null, plus a quoteSymbolAbsentReason naming both places that were checked

The absent case, verbatim#

GET /analytics, a quote with no first-party name
"quoteSymbol": null,
"quoteSymbolSource": null,
"quoteSymbolAbsentReason": "this mint is not in StonkFun's /pairs catalogue and its mint account carries no Token-2022 metadata, so there is no first-party name for it. Both sources were checked."

The launched token's own name, symbol and image come from the same Token-2022 metadata mechanism on the base mint, and are reported as mintName, mintSymbol and mintImageUrl on a ranking row. They are prefixed mint because a row already carries the quote leg's symbol and the two must not be confused.