Skip to main content
During development, you can use the developer endpoints without an API key. For production use, request an API key for higher rate limits.

Use Cases

  • Display global “recent fills” across all markets.
  • Display market-specific fills next to orderbook and price data.
  • Display wallet trade history scoped to a market or event.
  • Trigger alerts for large trades using minAmount filters.
1

Set Base URL and Query Helper

Define the metadata API base URL and reusable query/output helpers.
import "dotenv/config";

const DFLOW_METADATA_API_URL = process.env.DFLOW_METADATA_API_URL ?? "https://dev-prediction-markets-api.dflow.net";
const DFLOW_API_KEY = process.env.DFLOW_API_KEY; // optional; not needed for dev endpoints

const headers: HeadersInit = {};
if (DFLOW_API_KEY) headers["x-api-key"] = DFLOW_API_KEY;

type QueryValue = string | number | undefined | null;
type OnchainTrade = Record<string, any>;

function toQueryString(params: Record<string, QueryValue>): string {
  const searchParams = new URLSearchParams();

  Object.entries(params).forEach(([key, value]) => {
    if (value !== undefined && value !== null && value !== "") {
      searchParams.set(key, String(value));
    }
  });

  const query = searchParams.toString();
  return query ? `?${query}` : "";
}

function printTrades(trades: OnchainTrade[]) {
  trades.forEach((trade) => {
    console.log({
      id: trade.id,
      createdAt: trade.createdAt,
      marketTicker: trade.marketTicker,
      side: trade.side,
      inputAmount: trade.inputAmount,
      outputAmount: trade.outputAmount,
      wallet: trade.wallet,
      transactionSignature: trade.transactionSignature,
    });
  });
}
2

Get Onchain Trades by Wallet

Scope fills to a single wallet using /api/v1/onchain-trades with the wallet query parameter.
async function getWalletOnchainTrades(wallet: string) {
  const response = await fetch(
    `${DFLOW_METADATA_API_URL}/api/v1/onchain-trades?wallet=${wallet}&limit=100&sortBy=createdAt&sortOrder=desc`,
    { headers }
  );

  if (!response.ok) {
    throw new Error("Failed to fetch wallet onchain trades");
  }

  const data = await response.json();
  const trades = data.trades ?? [];
  const nextCursor = data.cursor ?? null;

  printTrades(trades);

  console.log({
    wallet,
    tradeCount: trades.length,
    nextCursor,
  });
}
3

Get Onchain Trades Across All Markets

Scope fills across all markets using /api/v1/onchain-trades.
async function getGlobalOnchainTrades() {
  const query = toQueryString({
    limit: 100,
    cursor: undefined,
    mint: undefined, // optional
    ticker: undefined, // optional
    sortBy: "createdAt",
    sortOrder: "desc",
    minAmount: undefined,
    maxAmount: undefined,
  });

  const response = await fetch(
    `${DFLOW_METADATA_API_URL}/api/v1/onchain-trades${query}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error("Failed to fetch onchain trades");
  }

  const data = await response.json();
  const trades = data.trades ?? [];
  const nextCursor = data.cursor ?? null;

  printTrades(trades);
  console.log({ tradeCount: trades.length, nextCursor });
}
4

Get Onchain Trades by Event

Scope fills to all markets inside a single event using /api/v1/onchain-trades/by-event/{event_ticker}.
async function getEventOnchainTrades(eventTicker: string) {
  const query = toQueryString({
    limit: 100,
    sortBy: "createdAt",
    sortOrder: "desc",
    minAmount: undefined,
    maxAmount: undefined,
  });

  const response = await fetch(
    `${DFLOW_METADATA_API_URL}/api/v1/onchain-trades/by-event/${eventTicker}${query}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error("Failed to fetch onchain trades by event");
  }

  const data = await response.json();
  const trades = data.trades ?? [];
  const nextCursor = data.cursor ?? null;

  printTrades(trades);
  console.log({
    eventTicker,
    tradeCount: trades.length,
    nextCursor,
  });
}
5

Get Onchain Trades by Market

Scope fills to a single market using /api/v1/onchain-trades/by-market/{market_ticker}.
async function getMarketOnchainTrades(marketTicker: string) {
  const query = toQueryString({
    limit: 100,
    sortBy: "createdAt",
    sortOrder: "desc",
    minAmount: undefined,
    maxAmount: undefined,
  });

  const response = await fetch(
    `${DFLOW_METADATA_API_URL}/api/v1/onchain-trades/by-market/${marketTicker}${query}`,
    { headers }
  );

  if (!response.ok) {
    throw new Error("Failed to fetch onchain trades by market");
  }

  const data = await response.json();
  const trades = data.trades ?? [];
  const nextCursor = data.cursor ?? null;

  printTrades(trades);
  console.log({
    marketTicker,
    tradeCount: trades.length,
    nextCursor,
  });
}
6

Paginate with Cursor

Scope historical pagination by passing each response cursor into the next /api/v1/onchain-trades request.
async function fetchAllOnchainTrades(limitPerPage = 250) {
  let cursor: string | null = null;
  const allTrades: OnchainTrade[] = [];

  do {
    const query = toQueryString({
      limit: limitPerPage,
      cursor,
      sortBy: "createdAt",
      sortOrder: "desc",
    });

    const response = await fetch(
      `${DFLOW_METADATA_API_URL}/api/v1/onchain-trades${query}`,
      { headers }
    );
    if (!response.ok) throw new Error("Failed to paginate onchain trades");

    const page = await response.json();
    allTrades.push(...(page.trades ?? []));
    cursor = page.cursor ?? null;
  } while (cursor);

  printTrades(allTrades);
  return allTrades;
}

Onchain Trade Parsing

How outcome-token trades land onchain and what fields the parser surfaces.

Track User Positions

Map wallet balances back to markets and outcomes.

Buy Outcome Tokens

Open a prediction market position from any input token.

API Routes