---
title: "Real-Time Charts"
description: "Bootstrap TradingView-style bars by outcome id and keep the view live"
---

> **For AI agents:** the complete documentation index is at [llms.txt](/llms.txt). Append `.md` to any page URL for its markdown version.

AGG chart history is keyed by `VenueMarketOutcome.id` and comes from `GET /charts/bars`.
That endpoint returns one canonical bar series for a single outcome and resolution using
TradingView-style `[from, to)` and `countBack` semantics. Aggregate charts are not supported.

<Tabs>
  <Tab title="SDK (vanilla JS/TS)">
    <div key="sdk-vanilla-js-ts" className="[&>p]:mb-4 [&>p:last-child]:mb-0">
      Works in browsers, Node.js, and React Native. Bring your own chart library.

      ## 1. Set up the client

      ```typescript
      import { createAggClient } from "@agg-build/sdk";

      const client = createAggClient({
        baseUrl: "https://api.agg.market",
        appId: "your-app-id",
        wsUrl: "wss://ws.agg.market/ws",
      });
      ```

      ## 2. Fetch historical bars

      ```typescript
      const history = await client.getChartBars({
        venueMarketOutcomeId: "your-outcome-id",
        resolution: "5m",
        from: Date.now() - 24 * 60 * 60 * 1000,
        to: Date.now(),
      });

      const historicalBars = history.data;
      ```

      ## 3. Request bars with `countBack`

      ```typescript
      const trailingBars = await client.getChartBars({
        venueMarketOutcomeId: "your-outcome-id",
        resolution: "5m",
        to: Date.now(),
        countBack: 300,
      });
      ```

      ## 4. Render with your chart library

      ```typescript
      const chartData = historicalBars.map((c) => ({
        time: c.t / 1000,
        open: c.o,
        high: c.h,
        low: c.l,
        close: c.c,
        volume: c.v ?? undefined,
      }));

      yourChart.setData(chartData);
      ```

      ## 5. Optional live overlay

      ```typescript
      import { CandleBuilder } from "@agg-build/sdk";

      const builder = new CandleBuilder();
      const ws = client.createWebSocket({
        onSnapshot: (_outcomeId, book) => {
          if (book.midpoint != null) builder.addMidpoint(book.midpoint, book.timestamp);
        },
        onDelta: (_outcomeId, book) => {
          if (book.midpoint != null) builder.addMidpoint(book.midpoint, book.timestamp);
        },
        onTrade: (trade) => {
          builder.addTrade(trade.price, trade.size, trade.timestamp);
        },
      });

      // Both live subscriptions and historical bars are keyed by outcome ID.
      ws.subscribe("your-outcome-id", "orderbook");
      ws.subscribe("your-outcome-id", "trades");
      ```
    </div>
  </Tab>

  <Tab title="Hooks (React)">
    <div key="hooks-react" className="[&>p]:mb-4 [&>p:last-child]:mb-0">
      <Note>
        See the [Setup Guide](/api/setup) for the one-time `AggProvider` and `QueryClientProvider`
        setup. This recipe starts at the hook layer.
      </Note>

      ## 1. Use `useMarketChart`

      ```tsx
      import { useMarketChart } from "@agg-build/hooks";

      function MarketChart({ venueMarketOutcomeId }: { venueMarketOutcomeId: string }) {
        const { data, isLoading } = useMarketChart({
          marketId: venueMarketOutcomeId,
          interval: "5m",
          startTs: Date.now() - 24 * 60 * 60 * 1000,
          endTs: Date.now(),
        });

        if (isLoading) return <div>Loading...</div>;

        const primaryVenue = data?.primaryVenue;
        const candles = primaryVenue ? data.venues[primaryVenue]?.candles ?? [] : [];

        return (
          <YourChart
            data={candles.map((c) => ({
              time: c.time,
              open: c.open,
              high: c.high,
              low: c.low,
              close: c.close,
            }))}
          />
        );
      }
      ```

      ## 2. Use `countBack` for scrollback

      ```tsx
      function TrailingChart({ venueMarketOutcomeId }: { venueMarketOutcomeId: string }) {
        const { data } = useMarketChart({
          marketId: venueMarketOutcomeId,
          interval: "5m",
          endTs: Date.now(),
          countBack: 500,
        });

        const primaryVenue = data?.primaryVenue;
        const candles = primaryVenue ? data.venues[primaryVenue]?.candles ?? [] : [];

        return <YourChart data={candles} />;
      }
      ```

      ## 3. Live overlays remain optional

      `useMarketChart()` returns canonical historical bars under the hook's `primaryVenue`
      entry. If you need a forming bar on top of that history, layer on live orderbook/trade
      updates with the SDK `CandleBuilder`.
    </div>
  </Tab>

  <Tab title="UI Components">
    <div key="ui-components" className="[&>p]:mb-4 [&>p:last-child]:mb-0">
      Drop-in React components for charts, orderbooks, and full event/market layouts.

      ## [Event Market Page](/components/pages/event-market-page)

      ```tsx
      import { EventMarketPage } from "@agg-build/ui/pages";

      function EventPage({ eventId }) {
        return <EventMarketPage eventId={eventId} />;
      }
      ```

      This renders a hero chart plus stacked market detail cards with live charts and orderbooks.

      ## [Market Details](/components/events/market-details) card

      ```tsx
      import { MarketDetails } from "@agg-build/ui/events";

      function MarketCard({ event, marketId }) {
        return <MarketDetails event={event} marketId={marketId} defaultTab="graph" />;
      }
      ```

      ## Standalone chart

      ```tsx
      import { LineChart } from "@agg-build/ui/primitives";

      function Chart({ series }) {
        return <LineChart series={series} height={320} chartType="candlestick" live />;
      }
      ```

      Browse the live [Event Market Page reference](/components/pages/event-market-page) and
      [Market Details reference](/components/events/market-details).
    </div>
  </Tab>
</Tabs>

## Supported resolutions

`GET /charts/bars` supports four stored resolutions:

| Interval | Code |
|----------|------|
| 1 minute | `"1m"` |
| 5 minutes | `"5m"` |
| 1 hour | `"1h"` |
| 1 day | `"1d"` |

## How it works

```text
GET /charts/bars            -> Canonical historical bars   -> Initial render
Optional live WS overlay    -> CandleBuilder / hooks       -> Forming bar updates
```

For wire-level details, resnapshot behavior, and authenticated streaming, see
[WebSocket Protocol](/api/websocket).

## Related

<Columns cols={2}>
  <Card title="WebSocket Protocol" icon="gear" href="/api/websocket">
    Subscribe, authenticate, handle heartbeats, and reconnect safely.
  </Card>
  <Card title="Real-Time Orderbook" icon="code" href="/recipes/websocket-orderbook">
    Reuse the same orderbook stream for depth views and chart inputs.
  </Card>
  <Card title="User Notifications" icon="key" href="/recipes/websocket-notifications">
    Handle authenticated order and balance events on the same socket.
  </Card>
</Columns>
