Market-data API
Choose bootstrap, chart history, search mode, or the book id for a market-data read.
Market-data reads require x-app-id; a user access token is optional. Server-side clients can
also send an API key to use its rate-limit budget. Keep API keys on your backend. See
Server API keys.
| Decision | Use this | Not this |
|---|---|---|
| First paint of an event | GET /venue-events/{id}/bootstrap | GET /venue-events/{id} plus GET /venue-markets?venueEventId= when you need a filterable market page instead of the first slice |
| Chart history | GET /charts/history/manifest, then GET /charts/bars for the unfinished tail | Bars alone when a ready manifest already covers the prefix, or the manifest alone when history is not finalized through to |
| Search | GET /search?mode=instant for typeahead, mode=full for a submitted search | The list endpoints, which are for ordinary filtered browsing |
| Books | Outcome id on GET /orderbooks/outcomes, GET /orderbook/outcome/{outcomeId}, and the orderbook socket | Market id on GET /orderbooks and GET /midpoints. There is no midpoint socket |
Bootstrap
GET /venue-events/{id}/bootstrap is the first useful event view: event display fields, the first market slice, and the outcome ids to subscribe. Optional limit is an integer from 1 to 20. The slice is not the full event. Page the rest with List venue markets using the returned cursor. Rules, wallets, quotes, and offscreen pages are separate reads.
selectedOutcomeIds are outcome ids for chart history and the orderbook channel, not venue market ids. references points at the history manifest and that live channel. detailsDeferred is true: descriptions and rules may need a later read. freshness.assembledAt is when this response was assembled, in Unix milliseconds, not a venue timestamp.
The other way to open an event is Get venue event plus List venue markets. On both, cluster=true (the default) covers the matched cluster. cluster=false scopes counts and the market list to that one venue event. Only the strings true and false are accepted. The embedded venueMarkets array is not the market page. On a list it is a preview of up to three markets and is deprecated. Sibling venues are matchedVenueMarkets[], not extra rows inside the anchor's venueMarkets[]. Building that screen is Building market views.
import { createAggClient } from "@agg-build/sdk";
const client = createAggClient({
baseUrl: "https://api.t.sufwankhalid.com",
appId: "YOUR_APP_ID",
});
const view = await client.getEventBootstrap("EVENT_ID");Get the first useful event view.
Charts
Chart history is keyed by venueMarketOutcomeId. There is no /charts/candlesticks route.
GET /charts/history/manifest returns at most eight authorized chunk URLs, the effective resolution, the finalization boundary, and a delivery state. GET /charts/bars is the canonical bar route and the unfinished tail. Both take venueMarketOutcomeId, optional resolution, optional from, required to (Unix milliseconds), and optional countBack from 1 to 5,000. Wire resolutions are 1, 5, 60, and 1D. The SDK methods accept 1m, 5m, 1h, and 1d and map them to those wire values.
Use the resolution the manifest returns. It can be coarser than the one you asked for. Render the finalized prefix from the manifest, then request the remainder from /charts/bars when the finalization boundary is behind to. If the manifest is not ready, use a bounded /charts/bars read instead. Signed chunk URLs are temporary. Keep their query strings, do not put them in a public cache, and request a fresh manifest when they expire. loadImmutableHistory checks each chunk's SHA-256 before you draw it.
meta.state is ready, warming, unsupported, failed, or empty. ready still needs a look at completeness: ready with complete: false means cached bars that are refreshing in the background, so render them and refresh on your normal schedule. warming means keep the current view and retry within a budget using retryAfterMs. unsupported means stop polling that path. failed is an error, not an empty chart. empty means no bars for the range. An empty success body is not a healthy chart. semantics is venue-ohlcv-v1, polymarket-price-samples-v1, or kalshi-ohlcv-quote-fallback-v2. Do not draw sampled prices as venue trade candles, invent volume, or bridge a real gap.
Live overlay after that history is Real-time charts.
Get versioned chart history references. Get chart bars.
Catalog changes
To keep your own copy of events and markets current, do not poll the list routes. Subscribe to
the catalog channel and catch up with GET /catalog/changes. See
Catalog Sync.
Search
GET /search requires q and type (events or markets). mode=instant is the bounded typeahead path. mode=full is the submitted search. Omitting mode is full. Instant and full share one read quota. Debounce input and abort the request you replaced. Page with the returned cursor. Use List venue events for ordinary filtered browsing, not search.
meta.complete describes whether this search finished its ranking work, not whether more pages exist. Read hasMore for pages. A search that misses its budget returns 503, not an empty page you can cache.
Order books
Outcome ids and market ids are not interchangeable. Which id to store is Ids.
| You have | Read |
|---|---|
venueMarketOutcomeId | GET /orderbooks/outcomes (up to 100 ids) or GET /orderbook/outcome/{outcomeId}. The orderbook socket takes outcome ids too. |
venueMarketId | GET /orderbooks. Midpoints are GET /midpoints. |
The two outcome routes share one quota, charged by distinct outcome id. A single-outcome read costs one unit. Duplicate ids in a batch count once. Switching from the batch route to the single route does not reset that budget. A missing outcome on the batch route is null, not a dropped row. A market-id orderbook row carries status and error. Do not treat an empty book as proof the market is healthy.
snapshotChecksum covers the depth-limited levels in that response. checksum is the full engine book. Do not recompute the full checksum from a truncated REST slice. REST timestamp is Unix milliseconds.
There is no midpoint WebSocket channel.
Read quotas
Market-data reads have per-group caps on top of the global limits. The current numbers are on Rate limits.
Browser Worker
Worker support is optional. createWorkerWebSocket is exported from @agg-build/sdk/browser. MarketDataEngine is exported from @agg-build/sdk/market-data. Your app supplies the Worker. The default @agg-build/sdk entry does not start one, and it stays usable in Node and React Native. Do not put an API key in the Worker asset. Keep one client and one Worker for the life of the page. If the Worker fails, close it and use the direct socket.