import type { Metadata } from "next"; import Link from "next/link"; import { RelativeTime } from "@/components/ui/freshness"; import { Page, PageHeader, Section } from "@/components/ui/section"; import { RightsBadge, StatusBadge } from "@/components/ui/status-badge"; import { api } from "@/lib/api"; import { ASSET_CLASS_LABEL } from "@/lib/format"; import type { Source } from "@/lib/types"; export const metadata: Metadata = { title: "Sources", description: "Directory of the exchanges, regulators, central banks and datasets Market Atlas observes, with rights and real-time classification.", alternates: { canonical: "/sources" } }; export const dynamic = "force-dynamic"; const CATEGORY_LABEL: Record = { EXCHANGE: "Exchanges", REGULATOR: "Regulators", CENTRAL_BANK: "Central banks", GOVERNMENT: "Government", ISSUER: "Issuer websites", PUBLIC_MARKET_SOURCE: "Public market sources", OFFICIAL_DATASET: "Official & licensed datasets", NEWS: "News", INTERNAL: "Market Atlas internal" }; const RT_LABEL: Record = { REALTIME: "real time", DELAYED: "delayed", END_OF_DAY: "end of day", INDICATIVE: "indicative", UNKNOWN: "unknown", STALE: "stale" }; export default async function SourcesPage() { const sources = (await api("/v1/sources")).filter((s) => s.category !== "INTERNAL"); const cats = [...new Set(sources.map((s) => s.category))]; return ( a + s.connectors, 0)} connectors. Each source declares how its data may be used and how fresh it is; endpoints are not published to discourage abuse.`} actions={ <> Source coverage → Connector operations → } /> {cats.map((cat) => (
{sources .filter((s) => s.category === cat) .map((s) => ( ))}
Source Status Role Type Rights Freshness Coverage Reliability Last observation
{s.homepage ? ( {s.name} ) : ( s.name )}
{s.organization} {s.jurisdiction ? ` · ${s.jurisdiction}` : ""} {s.asset_classes.length ? ` · ${s.asset_classes.map((c) => ASSET_CLASS_LABEL[c] ?? c).join(", ")}` : ""}
{s.description &&
{s.description}
} {s.rights_notes && (
{s.rights_notes} {s.terms_url && ( <> {" "} terms ↗ )}
)}
{s.role === "validator" ? ( validator ) : ( contributor )} {s.likely_shared_upstream_with && s.likely_shared_upstream_with.length > 0 && (
likely shares an upstream with {s.likely_shared_upstream_with.join(", ")} — counted as one family
)}
{s.source_type} {RT_LABEL[s.realtime_status] ?? s.realtime_status} {s.coverage.toLocaleString("en-US")} {s.reliability_score ?? "—"} {s.last_observation ? : "—"}
))}

Role: contributors vote in the consensus and are redistributed with attribution; validators are sources whose data rights forbid redistribution — Market Atlas compares them to the canonical value to confirm or contest it, but they never set the price and are never displayed. Sources that statistically mirror each other (identical values within seconds) are counted as one family; see source coverage. Coverage = instruments this source has published a value for in the last 24 hours. Reliability = operational score (availability, latency, parse success, stability), see methodology. Rights statuses are explained on the data rights page.

); }