Market state API
Two public read endpoints return Candle’s own view of a market’s lifecycle and of the trade page’s feed buckets. Neither requires authentication. They are convenience reads: the on-chain registry and contract state remain authoritative for market identity, as described in Terminals and indexers.
Market state
Section titled “Market state”GET /api/v1/markets/:chain/:mintchain is solana or hood. The response is one chain-agnostic shape regardless of whether the mint is a Solana bonding curve or a Hood CandleCurve, cached about 5 seconds server-side:
{ "success": true, "market": { "chain": "solana", "mint": "...", "lifecycle": "trading", "buysOpen": true, "sellsOpen": true, "curveAddress": "...", "poolAddress": null, "quoteMint": "...", "feeBps": 100, "graduationVenue": "meteora-damm-v2", "tier": "open", "crossingModel": "full-fill-surplus" }}| Field | Notes |
|---|---|
lifecycle | trading, completed, migrated, or recovery. |
buysOpen, sellsOpen | Whether each side is currently executable. The two are independent; see the table below. |
curveAddress | The bonding curve (Solana pool or Hood CandleCurve) address. |
poolAddress | The post-migration venue pool on Solana (Meteora DAMM v2); null before migration and always null on Hood, where v3 and v4 pool discovery is on-chain. See Hood market integration. |
quoteMint | The quote asset’s mint or token address. |
feeBps | Curve trading fee in basis points. |
graduationVenue | meteora-damm-v2 on Solana; uniswap-v3 or uniswap-v4 on Hood. |
tier | open or exclusive, when known. |
crossingModel | full-fill-surplus on Solana, capped-refund on Hood. |
migration | Graduation progress. See below. |
Migration status
Section titled “Migration status”"migration": { "status": "in_progress", "attempts": 3, "nextAttemptAt": 1754400120000 }status | Meaning |
|---|---|
not_started | The curve is still trading. |
in_progress | The curve is done and the graduated venue is being seeded. |
completed | Trading has moved to the graduated venue. Carries migratedAt. |
delayed | Automated seeding exhausted its retries and a human has been alerted. |
migratedAt is stamped when a token first completes migration, so markets that graduated before this release report completed without one. On Hood the block also carries the keeper’s attempts, nextAttemptAt, and gaveUpAt where they apply.
The target is that a completed curve is live on its graduated venue within 10 minutes: the graduation keepers sweep every 2 minutes and retry with backoff. delayed is the machine-readable form of “this one needs a human”, not a normal step in the sequence.
Buys and sells are independent
Section titled “Buys and sells are independent”buysOpen and sellsOpen do not always move together:
lifecycle | Solana | Hood |
|---|---|---|
trading | Buys and sells open | Buys and sells open |
completed | Both closed during migration | Buys closed, sells still open until migration completes |
migrated | Both open on the graduated venue | Both open on the graduated venue |
recovery | n/a | Both closed; recovery is a claim flow, not a trade |
Errors use the structured envelope described in the Headless launch API: an invalid chain is VALIDATION_FAILED (400) and an unknown market is MARKET_NOT_FOUND (404).
GET /api/v1/markets/:chain/:mint/quote?side=buy|sell&amountIn=<base units>&slippageBps=50Prices one trade through the exact same integer math the curve runs on-chain, so terminals do not have to re-implement crossing edge cases. Public, rate-limited to 120 requests per minute per client, cached about 5 seconds.
{ "success": true, "chain": "hood", "mint": "0x...", "side": "buy", "amountIn": "5000000000000000000", "crossingModel": "capped-refund", "quote": { "amountOut": "...", "fee": "...", "minAmountOut": "...", "crossesGraduation": true, "refund": "...", "quoteConsumed": "..." }}Every amount is a decimal string in the smallest unit of the quote asset (buys) or the base token (sells).
crossesGraduation applies to buys only, and what it implies differs by chain, which is why crossingModel travels with it. On Hood a crossing buy is capped at the threshold and the remainder refunded, so refund and quoteConsumed tell you how much was actually spent. On Solana a crossing buy fills in full and the surplus stays in the pool, so the refund fields never appear.
minAmountOut applies your slippageBps to the capped fill rather than the uncapped one, so a quote is always satisfiable on-chain, even across graduation.
A curve that cannot execute the requested side returns MARKET_NOT_TRADABLE (409), and the message names where trading continues: the Uniswap pool, the Jupiter or Meteora route, or “buys closed while graduating, sells remain open”.
Verify
Section titled “Verify”GET /api/v1/verify/:chain/:mintThe authoritative answer to “is this mint a genuine Candle launch”, so users and terminals can reject look-alike mints. Public, cached about 60 seconds.
{ "success": true, "candleLaunched": true, "chain": "hood", "mint": "0x...", "tier": "open", "quoteMint": "0x...", "graduated": false, "pool": null, "createdAt": 1754400000000, "creator": "0x...", "viaAgentKey": true, "provenance": { "curve": "0x...", "factory": "0x...", "configHash": "0x...", "dexVersion": "v4" }}An unknown mint, or one launched with non-production visibility, returns 200 with { "candleLaunched": false } rather than a 404, so a caller branches on one response shape either way.
Hood responses carry the provenance block above, re-verifiable against the registry. Solana responses instead carry attribution (the bonding-curve program and the attribution signer), so an indexer can re-derive the same conclusion on-chain using the procedure in Solana market identification.
viaAgentKey is true when the launch came through an agent API key, which is the same signal behind the agent badge in the Candle UI.
GET /api/v1/markets/feed?bucket=new|graduated|onfire|bluechip&chain=solana|hoodA thin public read onto the same feed buckets the trade page tabs use, optionally filtered to one chain, cached about 10 seconds server-side. bucket is required; chain is optional.
{ "success": true, "bucket": "new", "tokens": [ { "chain": "solana", "address": "...", "name": "Trend Coin", "symbol": "TREND", "image": "https://...", "isAgent": true } ]}Each row carries chain, address, name, symbol, image, price, volume, and market-cap statistics, and isAgent, which is true for a Candle-origin launch created through an agent API key. An unknown bucket or chain is VALIDATION_FAILED (400).
Agent profile
Section titled “Agent profile”GET /api/v1/users/:idOrWallet/agentA public read for any account: whether it has agent features enabled, its address and username, and its launch counts, total versus those attributed to an agent key.
{ "success": true, "agent": { "enabled": true, "address": "...", "username": "trendbot", "launches": 12, "launchesViaApi": 9 }}Unlike the market endpoints, this route’s errors are plain: { "error": "User not found" } with status 404.