---
title: "Comparing Venue Prices"
description: "Fetch matched events, walk every matched market, and pull midpoints in one batch with the SDK"
---

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

The same prediction market often trades on more than one venue at the same time, at different
prices. AGG's matching pipeline links those markets together as `matchedVenueMarkets` so you
can build a cross-venue price comparison in three calls:

1. **List matched events** — events confirmed on two or more venues.
2. **Walk every market and its matched siblings** — collect each `venueMarketId`.
3. **Batch-fetch midpoints** — one request returns the live Yes-side price per market.

The midpoint is the live orderbook's headline mark on a 0–1 scale, where `0.55` means the
market implies a 55% probability of "Yes". Comparing midpoints across venues for the same
matched event surfaces the spread an arbitrageur, smart router, or "best price" badge cares
about.

## 1. Create the client

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

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

## 2. List matched events

`getVenueEvents` accepts `matchStatus` as an array. Pass `["matched", "verified"]` to restrict
the response to events confirmed across more than one venue — every market in the response
includes its `matchedVenueMarkets`. Calls [`GET /venue-events`](/api-reference/discovery/list-venue-events).

```typescript
const { data: events } = await client.getVenueEvents({
  status: ["open"],
  matchStatus: ["matched", "verified"],
  limit: 50,
});
```

## 3. Collect every venueMarketId

Walk the response and gather every market ID — the event's own markets plus each
`matchedVenueMarkets[].id`.

```typescript
const ids = new Set<string>();
for (const event of events) {
  for (const market of event.venueMarkets ?? []) {
    ids.add(market.id);
    for (const matched of market.matchedVenueMarkets ?? []) {
      ids.add(matched.id);
    }
  }
}
```

## 4. Batch-fetch midpoints

`getMidpoints` accepts up to 200 IDs per call. Chunk and parallelize for larger universes.
Calls [`GET /midpoints`](/api-reference/orderbook/get-live-midpoints-for-multiple-markets).

```typescript
function chunk<T>(arr: T[], size: number): T[][] {
  const out: T[][] = [];
  for (let i = 0; i < arr.length; i += size) out.push(arr.slice(i, i + size));
  return out;
}

const batches = chunk([...ids], 200);
const responses = await Promise.all(
  batches.map((venueMarketIds) => client.getMidpoints({ venueMarketIds })),
);
const midpoints = responses.flatMap((r) => r.data);
```

## 5. Build the comparison

Index midpoints by `venueMarketId`, then for each market look up its own midpoint plus its
siblings'.

```typescript
const byId = new Map(midpoints.map((m) => [m.venueMarketId, m]));

for (const event of events) {
  for (const market of event.venueMarkets ?? []) {
    const own = byId.get(market.id);
    const siblings = (market.matchedVenueMarkets ?? [])
      .map((m) => byId.get(m.id))
      .filter((m): m is NonNullable<typeof m> => !!m);

    const usable = [own, ...siblings].filter(
      (m): m is NonNullable<typeof m> => !!m && m.midpoint !== null,
    );
    if (usable.length < 2) continue;

    const cheapest = usable.reduce((a, b) => (a.midpoint! < b.midpoint! ? a : b));
    const richest = usable.reduce((a, b) => (a.midpoint! > b.midpoint! ? a : b));

    console.log(event.id, {
      spread: richest.midpoint! - cheapest.midpoint!,
      cheapest: { venue: cheapest.venue, midpoint: cheapest.midpoint },
      richest: { venue: richest.venue, midpoint: richest.midpoint },
    });
  }
}
```

## Live updates

`/midpoints` is a snapshot. For continuously updating prices, subscribe to the WebSocket
`orderbook` channel with the outcome IDs you care about — every snapshot and delta carries
the live `midpoint` per outcome with per-venue attribution. See
[Real-Time Orderbook](/recipes/websocket-orderbook).

## Related

<Columns cols={2}>
  <Card title="Building Market Views" icon="layer-group" href="/recipes/building-market-views">
    Compose discovery and orderbook endpoints into event grids and trading views.
  </Card>
  <Card title="Real-Time Orderbook" icon="bolt" href="/recipes/websocket-orderbook">
    Stream live midpoints and depth via WebSocket.
  </Card>
</Columns>
