matchprior
Quickstart

Your first calibrated prediction, in three steps.

Create a key, call /v1/predictions, and read the model's calibrated probabilities. Same JSON schema across every sport, authenticated with one header. See exactly how reliable they are on the calibration page — say 70–80% and it won 75.3% across 67,667 out-of-sample backtested calls.

Get an API key

Sign up on the pricing page and generate a live key. The free tier needs no card — 500 requests a month, one sport, every /v1 endpoint. Keys look like this:

mp_live_8f3c2a9d4e7b1f60a5c8e3920d6471bb
Treat the key like a password. It is hashed at rest, so we can show it once at creation — copy it then. Send it on every request except /v1/health, and never embed a live key in client-side or public code.

Make your first call

Request one prediction from the English Premier League (league=E0), authenticating with the X-API-Key header. The same call in cURL, JavaScript and Python:

first-call.sh cURL
# One calibrated prediction, authenticated with a single header
curl https://api.matchprior.com/v1/predictions?league=E0&limit=1 \
  -H "X-API-Key: mp_live_8f3c…"
first-call.js JavaScript
// fetch — works in Node 18+ and the browser (keep the key server-side)
const url = "https://api.matchprior.com/v1/predictions?league=E0&limit=1";

const res = await fetch(url, {
  headers: { "X-API-Key": "mp_live_8f3c…" },
});

const { data } = await res.json();
console.log(data[0].pick, data[0].probs);
first_call.py Python
# pip install requests
import requests

res = requests.get(
    "https://api.matchprior.com/v1/predictions",
    params={"league": "E0", "limit": 1},
    headers={"X-API-Key": "mp_live_8f3c…"},
)
res.raise_for_status()

data = res.json()["data"]
print(data[0]["pick"], data[0]["probs"])

Read the response

Every list endpoint returns a { data, page } envelope: data is the array you asked for, page carries the count and a forward nextCursor. A single prediction looks like this:

200 OK · /v1/predictions JSON
{
  "data": [{
    "fixture": {
      "id": "E0|2026-08-15|Arsenal|Chelsea",
      "sport": "football", "league": "E0",
      "date": "2026-08-15", "time": "17:30",
      "home": "Arsenal", "away": "Chelsea",
      "market": { "H": 0.52, "D": 0.26, "A": 0.22 }
    },
    "probs": { "H": 0.55, "D": 0.25, "A": 0.20 },
    "pick": "H", "confidence": 0.55,
    "over25": 0.54, "btts": 0.58,
    "likelyScore": { "home": 2, "away": 1 },
    "marketEdge": 0.03, "contrarian": false,
    "rationale": {
      "homeRating": 1788, "awayRating": 1742,
      "ratingEdge": 111,
      "homeForm": ["W", "W", "D", "L", "W"],
      "expectedGoals": { "home": 1.7, "away": 1.1 }
    }
  }],
  "page": { "count": 1, "nextCursor": null }
}
Field Type What it means
probs { H, D, A } The model's calibrated probabilities for home win / draw / away win. They sum to ~1. A 0.55 here has historically landed close to 55% of the time — that is what calibrated means.
pick "H" | "D" | "A" The single highest-probability outcome. A summary of probs, not a recommendation to stake anything.
confidence number 0–1 The probability attached to pick — i.e. probs[pick].
over25 · btts number 0–1 P(total goals ≥ 3) and P(both teams score). Football-specific derived markets.
likelyScore { home, away } The single most likely correct-score line under the model.
marketEdge number Model probability minus market probability on the pick. This is disagreement, not value — a positive number means the model is more confident than the market here, never that acting on it is an expected gain.
contrarian boolean true when the model picks against the market favourite. A flag for where the two disagree, nothing more.
rationale object The why. Elo ratings and the ratingEdge, recent form, head-to-head and expected goals — the transparent inputs behind the probabilities.
page.nextCursor string | null Pass back as ?since= to fetch the next page. null means you have reached the end.
An honest word on what this is — and tiers & limits. These are calibrated probabilities, not predictions of profit. Across 67,667 out-of-sample backtested predictions, every confidence tier landed within about a point of its claim (say 70–80% → won 75.3%; say 80%+ → won 86.3%) — simulated results, not a betting edge or profit claim. We ship the /v1/accuracy and /v1/backtest endpoints precisely so you can check that for yourself. Every successful GET to a /v1/* endpoint counts as one request; 304 Not Modified and /v1/health are free. The Free tier is 500 req/mo on one sport with no card and no overage — it stops cleanly. Dev ($19/mo) and Pro ($49/mo) raise the cap and unlock all sports, full rationale and the track-record endpoints; Business ($99/mo) adds redistribution rights where licensing permits. Limits are metered, not throttled by accuracy — the SLA covers availability and freshness only, never results. Full breakdown on the pricing page.
Where to next

Go deeper.

The honesty endpoints

Live, graded hit rate, calibration error and Brier-vs-market — the proof layer. Lead here.

GET /v1/accuracy · /v1/backtest

Fixtures & ratings

List upcoming fixtures the model covers, and the Elo leaderboard behind every rating.

GET /v1/fixtures · /v1/ratings

One fixture, full rationale

Fetch a single prediction by id when you already know the fixture you want.

GET /v1/predictions/{fixtureId}

Calibrated probabilities, not predictions of profit. For information and entertainment only.