Proba Bet
Try free

Sharp plan · REST · JSON

API documentation

Your dashboard's data as JSON, with the same filters (your bookmakers, otherwise your country's plus international ones): opportunities of the last scan (one scan a minute), surebets, parlays, and the fair probabilities of every match (updated every 5 minutes). Base URL: https://proba.bet.

Authentication

Create a key in Settings → API (Sharp plan, 3 active keys max). Send it in the Authorization: Bearer header. The ?api_key= parameter is accepted for spreadsheets but not recommended: the key then ends up in logs and history. The key is shown once; we only store its SHA-256 hash.

curl -H "Authorization: Bearer pb_live_xxxxxxxx" "https://proba.bet/api/v1/me"
{ "plan": "sharp", "daily_limit": 20000, "remaining_today": 19999 }

Quota

20,000 requests per key and per day (UTC), reset at 00:00 UTC. Every successful response carries X-RateLimit-Limit and X-RateLimit-Remaining (a 429 too, with Retry-After). Opportunities change at most once a minute (UK bookmakers' odds: every 1 to 2 minutes), match probabilities every 5 minutes: polling faster is pointless.

Endpoints

EndpointParametersReturns
GET /api/v1/me—plan, daily_limit, remaining_today
GET /api/v1/opportunitieskind=value|surebet|combo (default value) · min_ev (fraction; edge for value, default 0.02; profit for surebet, default 0.005; ignored for combo) · sport (no effect on combo) · limit (≤ 1000, default 300)kind, count, generated_at, data[] (event_id, sport_key, home, away, commence_time, market_key, outcome, point, book, book_title, price, link, fair_prob, fair_odds, ev, ev_expected, kelly, grade, flags, alt_books, exchange, first_seen, published_at… ; surebet : profit, legs[] ; combo : legs[])
GET /api/v1/matchessport · hours (1–96, default 96; tournament or race winners up to 14 days) · limit (≤ 1000, default 600) — or id=<event_id>: one row per outcome (market_key, line, outcome, point, fair_prob, fair_odds)count, generated_at, data[] (event_id, home, away, commence_time, p_home, p_draw, p_away, total_line, p_over, p_under, source, matched, thin, kind, updated_at)

Example: value bets

curl -H "Authorization: Bearer pb_live_xxxxxxxx" \
  "https://proba.bet/api/v1/opportunities?kind=value&min_ev=0.02&sport=soccer_epl&limit=50"
{
  "kind": "value", "count": 12, "generated_at": "2026-09-19T21:03:44.120Z",
  "data": [{
    "event_id": "0ab3…", "sport_key": "soccer_epl", "home": "Arsenal", "away": "Chelsea", "commence_time": "2026-09-20T15:00:00+00:00",
    "market_key": "h2h", "outcome": "Draw", "point": null,
    "book": "unibet_fr", "book_title": "Unibet (FR)", "price": 3.60, "link": "https://…",
    "fair_prob": 0.2914, "fair_odds": 3.43, "ev": 0.0490, "ev_expected": 0.0294, "kelly": 0.0113, "grade": "A", "flags": [],
    "alt_books": [{ "book": "betclic_fr", "price": 3.55, "ev": 0.0344, "ev_expected": 0.0206, "grade": "A" }],
    "first_seen": "2026-09-19T21:01:40+00:00", "published_at": "2026-09-19T21:02:41+00:00"
  }]
}

Only bets playable at your bookmakers (Settings) — or, if none are set, at your country's and international bookmakers — are returned; for a surebet, all its legs. book / price / ev are the best offer across all bookmakers: pick yours from book or alt_books. grade A = Babeth's selection (tracked in the public track record); B = published with flags; C = check before betting. ev_expected = share of the edge expected at the close (stake basis); kelly = full Kelly on ev_expected; published_at = scan time; first_seen = first appearance. Dates are ISO 8601 UTC.

Example: match probabilities

curl -H "Authorization: Bearer pb_live_xxxxxxxx" "https://proba.bet/api/v1/matches?sport=soccer_epl&hours=48"
curl -H "Authorization: Bearer pb_live_xxxxxxxx" "https://proba.bet/api/v1/matches?id=0ab3c9d1"

Errors

Webhooks

Instead of polling, let Babeth call you: in Settings → Webhook, enter a public HTTPS URL and keep the Alerts switch on. Every new selection bet at your bookmakers (same filters as your alerts, quiet hours included) is POSTed with your stake. A failed call (timeout, non-2xx status, redirect) is retried at the next scan; after 5 failures, delivery pauses for 10 minutes. A bet may exceptionally arrive twice: deduplicate on event_id + market_key + outcome + point.

POST https://example.com/proba          (Settings → Webhook)
Content-Type: application/json
X-Proba-Event: picks | test
X-Proba-Signature: sha256=<HMAC-SHA256(secret, body)>

{
  "event": "picks", "sent_at": "2026-09-20T09:00:12Z", "user_id": "…",
  "picks": [{
    "event_id": "0ab3…", "sport_key": "soccer_epl", "home": "Arsenal", "away": "Chelsea", "commence_time": "2026-09-20T15:00:00Z",
    "sport_title": "EPL", "market_key": "h2h", "outcome": "Draw", "point": null,
    "book": "unibet_fr", "book_title": "Unibet (FR)", "price": 3.60, "link": "https://…", "book_url": "https://…",
    "fair_prob": 0.2914, "fair_odds": 3.43, "min_odds": 3.50, "ev": 0.049, "ev_expected": 0.0294, "grade": "A",
    "stake": 3, "currency": "EUR", "exchange": null
  }]
}

Verify the signature before trusting the payload:

# Node.js
const sig = req.headers["x-proba-signature"];            // "sha256=…"
const mac = crypto.createHmac("sha256", SECRET).update(rawBody).digest("hex");
const a = Buffer.from(sig || ""), b = Buffer.from("sha256=" + mac);
const ok = a.length === b.length && crypto.timingSafeEqual(a, b);

# Python
ok = hmac.compare_digest(sig, "sha256=" + hmac.new(SECRET.encode(), raw_body, hashlib.sha256).hexdigest())

Respond 2xx within 5 seconds, without redirecting. The `test` event comes from the “Send a test” button.

Terms

Personal use or your own tools. No resale of the data, no public redistribution. Keys can be revoked at any time from Settings. Decision-support data, no guarantee of winnings.

Need the API?

The Sharp plan includes the API, line moves, multiple bankrolls and the full comparator.