Prometheus

Football World Cup 2026 collector facts

Publisher: deam (@deam).

Version: 1. Last updated: 2026-06-11T18:07:56.566Z.

Run this collector on demand, as an API endpoint, or on a schedule with Firecrawl Prometheus.

Sample fields: events, id, url, slug, title, endDate, markets, active, closed, outcomes, name, price.

Football World Cup 2026

v1Published

All 639 open FIFA World Cup 2026 events on Polymarket (9,217 markets) — tournament winner, group winners, every match, and props — with live odds, volume, and liquidity.

Output & API

Preview the latest data, download it, or call this collector as an API.

Author's sample data
events
sourcePolymarket (Gamma API)
eventCount639
tournamentFIFA World Cup 2026
marketCount9217

Marketplace

Publish this collector so others can deploy it — you keep ownership.

0 subscribers
deam@deam
0 runs in 14d · published 2d ago

Versions

Every build and self-heal appends a version. Pin one to lock runs to it.

managed by author
v1builtapprovedcurrent2d ago
How this script collects data
import Firecrawl from "@mendable/firecrawl-js";
import * as cheerio from "cheerio";

const apiKey = process.env.FIRECRAWL_API_KEY;
if (!apiKey) {
  console.error("FIRECRAWL_API_KEY is not set");
  process.exit(1);
}
const firecrawl = new Firecrawl({ apiKey });

// Polymarket Gamma API tag id for "FIFA World Cup" (the 2026 tournament).
const TAG_ID = 102232;
const PAGE_SIZE = 100;
const MAX_PAGES = 50;

async function fetchPage(offset: number): Promise<any[]> {
  const url = `https://gamma-api.polymarket.com/events?tag_id=${TAG_ID}&closed=false&limit=${PAGE_SIZE}&offset=${offset}`;
  const res: any = await firecrawl.scrape(url, { formats: ["rawHtml"] });
  let raw: string = res?.rawHtml ?? "";
  if (raw.trimStart().startsWith("<")) {
    // Some renderers wrap JSON responses in an HTML page; recover the text.
    raw = cheerio.load(raw)("pre").text() || cheerio.load(raw)("body").text();
  }
  let parsed: any;
  try {
    parsed = JSON.parse(raw);
  } catch {
    throw new Error(`Gamma API response at offset ${offset} was not valid JSON`);
  }
  if (!Array.isArray(parsed)) {
    throw new Error(`Gamma API response at offset ${offset} was not an array of events`);
  }
  return parsed;
}

function parseJsonArray(s: unknown): any[] {
  if (typeof s !== "string") return [];
  try {
    const v = JSON.parse(s);
    return Array.isArray(v) ? v : [];
  } catch {
    return [];
  }
}

function toNumber(v: unknown): number | null {
  if (v === null || v === undefined || v === "") return null;
  const n = Number(v);
  return Number.isFinite(n) ? n : null;
}

function mapMarket(m: any) {
  const outcomeNames = parseJsonArray(m.outcomes);
  const outcomePrices = parseJsonArray(m.outcomePrices);
  const outcomes = outcomeNames.map((name: string, i: number) => ({
    name,
    price: toNumber(outcomePrices[i]),
  }));
  return {
    id: m.id ?? null,
    question: m.question ?? null,
    groupItemTitle: m.groupItemTitle || null,
    slug: m.slug ?? null,
    outcomes,
    volumeUsd: toNumber(m.volume),
    liquidityUsd: toNumber(m.liquidity),
    endDate: m.endDate ?? null,
    active: m.active ?? null,
    closed: m.closed ?? null,
  };
}

function mapEvent(e: any) {
  const title: string = e.title ?? "";
  const slug: string = e.slug ?? "";
  const isMatch = / vs\.? /i.test(title) || slug.startsWith("fifwc-");
  return {
    id: e.id ?? null,
    title: title.trim(),
    slug,
    url: slug ? `https://polymarket.com/event/${slug}` : null,
    category: isMatch ? "match" : "futures-and-props",
    description: e.description ?? null,
    startDate: e.startDate ?? null,
    endDate: e.endDate ?? null,
    volumeUsd: toNumber(e.volume),
    liquidityUsd: toNumber(e.liquidity),
    commentCount: e.commentCount ?? null,
    markets: Array.isArray(e.markets) ? e.markets.map(mapMarket) : [],
  };
}

async function main() {
  const events: any[] = [];
  const seen = new Set<string>();
  for (let page = 0; page < MAX_PAGES; page++) {
    const offset = page * PAGE_SIZE;
    console.error(`Fetching events at offset ${offset}...`);
    const batch = await fetchPage(offset);
    for (const e of batch) {
      const id = String(e.id ?? e.slug ?? "");
      if (id && seen.has(id)) continue;
      if (id) seen.add(id);
      events.push(mapEvent(e));
    }
    if (batch.length < PAGE_SIZE) break;
  }
  if (events.length === 0) {
    throw new Error("no open FIFA World Cup events returned by the Gamma API");
  }
  events.sort((a, b) => (b.volumeUsd ?? 0) - (a.volumeUsd ?? 0));
  const marketCount = events.reduce((n, e) => n + e.markets.length, 0);
  console.error(`Collected ${events.length} events with ${marketCount} markets.`);
  const out = {
    tournament: "FIFA World Cup 2026",
    source: "Polymarket (Gamma API)",
    eventCount: events.length,
    marketCount,
    events,
  };
  process.stdout.write(JSON.stringify(out));
}

main().catch((err) => {
  console.error(err);
  process.exit(1);
});
deploy to unlock

Deploy this collector to unlock schedules, the API endpoint, and destinations.

One person builds it. Everyone keeps it fresh.
Football World Cup 2026 Data Collector | Firecrawl Prometheus