spartanboxing API v1
Read-only REST API exposing every piece of data behind the portal — live picks, sizing, CLV evolution, model internals, audit reports, and a schema browser. Designed for programmatic trading on Polymarket and sportsbooks, dashboards, and quant research.
Sign in to mint your personal API key
Browsing this catalog requires no account. Calling authenticated endpoints does — generate a key in seconds and start hitting /api/v1 from your bot, notebook, or terminal.
Check health (no auth)
curl https://spartanboxing.ai/api/v1/healthGenerate a personal API key
Create an account or sign in to mint sbp_... tokens. The plaintext is shown once and never stored.
Pull live picks (authenticated)
curl -H "Authorization: Bearer sbp_..." \
"https://spartanboxing.ai/api/v1/picks/live?bankroll=10000&bet_only=true"Send your sbp_... token in either header below. Endpoints tagged public skip auth entirely (health, policy, this catalog).
Authorization: Bearer sbp_<32 chars>
# or
X-API-Key: sbp_<32 chars>Invalid/revoked → 401 invalid_key. Storage is hash-only (SHA-256): we can verify but never reveal your token.
Every response — success or failure — has the same outer shape.meta.cron_age_minutes tells you how stale the underlying pipeline data is.
{
"ok": true,
"data": "<endpoint-specific>",
"meta": {
"generated_at": "ISO timestamp",
"api_version": "v1",
"model_version": "lgbm_ens_v5_YYYY-MM-DD (when applicable)",
"cron_age_minutes": "minutes since last successful predict-live cron"
}
}{
"ok": false,
"error": {
"code": "snake_case",
"message": "human-readable"
},
"meta": {
"generated_at": "ISO",
"api_version": "v1"
}
}Discovery & health
Self-describing endpoints with no auth. Use to detect freshness, model version, and the production decision policy before pulling picks.
/api/v1/health publicExample request
curl 'https://spartanboxing.ai/api/v1/health'Example response data
{
"status": "healthy",
"cron": {
"last_ok_started_at": "2026-05-22T06:34:56Z",
"age_minutes": 3
},
"model": {
"version": "lgbm_ens_v5_2026-05-22",
"fit_at": "2026-05-22T05:00:00Z"
},
"counts": {
"pending_live_picks": 22,
"settled_live_picks": 1431,
"predictions_last_24h": 188
}
}/api/v1/policy publicExample request
curl 'https://spartanboxing.ai/api/v1/policy'Example response data
{
"thresholds": {
"min_edge_pp": 0.03,
"max_uncertainty_std": null,
"kelly_fraction_default": 0.25,
"max_bet_pct_default": 0.03
},
"model_version_prefix": "lgbm_ens_v5",
"audit_report": "master.audit_report kind='sizing_strategy' (boxing-poe): the optional confidence gate trades volume for per-bet quality; default bets every pick clearing the 3% edge floor. Per-setting Sharpe/return/drawdown recompute live in the backtest simulator."
}/api/v1/docs publicExample request
curl 'https://spartanboxing.ai/api/v1/docs'Picks & decisions
Pending and settled picks with full pricing, Polymarket-aware implied probabilities, and Kelly sizing. The actionable surface for live trading.
Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| bankroll | query | number | 0 | USD bankroll for stake math. 0 disables sizing. |
| kelly_fraction | query | number | 0.25 | Multiplier on raw Kelly f*. 0.25 = Quarter Kelly. |
| kelly_z | query | number | 0 | σ shrink: p_used = max(0.001, fair − z·σ). 0 = naive Kelly (audit-recommended). |
| max_bet_pct | query | number | 0.03 | Per-bet stake cap as fraction of bankroll. 0 disables. |
| min_edge_pp | query | number | 0.03 | Minimum vig-removed edge to qualify as BET. |
| max_uncertainty | query | number | none (no gate) | Maximum ensemble σ to qualify as BET. Default is no gate. Pass 0.010 to apply the tight filter. |
| bet_only | query | boolean | false | Drop NO BET rows from response. |
| include_stale | query | boolean | false | Include picks the cron stopped refreshing (likely dropped from OddsAPI). |
| include_books | query | boolean | false | Include full per-book pricing table per pick. |
| books | query | string | — | CSV of sportsbook keys (e.g. `pinnacle,draftkings,fanduel`) to restrict the per-book `books[]` array to. The BET/NO BET decision is UNCHANGED — production policy was audited against global execution. To filter BET eligibility against only YOUR books, use `/api/v1/optimizer/plus-ev` instead. |
Notes
- ›Stale = predicted before (last_cron_started − 20 min grace). At the 5-min cadence this is 4 missed ticks of slack.
- ›Picks are sorted: BET-eligible first (by stake desc), then NO BET (by edge desc), then stale.
- ›Use `/api/v1/bookmakers` to discover valid book keys for the `books` param.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/picks/live'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| since | query | string | 7 days ago | ISO date — only picks predicted on or after this date. |
| limit | query | integer | 100 | Max rows. Hard cap 500. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/picks/settled'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| fight_id* | path | integer | — | Internal fight identifier (see /api/v1/picks/live or /api/v1/schemas/master/fight). |
| bankroll | query | number | 0 | Same as /picks/live. |
| kelly_fraction | query | number | 0.25 | Same as /picks/live. |
| kelly_z | query | number | 0 | Same as /picks/live. |
| max_bet_pct | query | number | 0.03 | Same as /picks/live. |
| min_edge_pp | query | number | 0.03 | Same as /picks/live. |
| max_uncertainty | query | number | none | Same as /picks/live. |
| books | query | string | — | CSV of sportsbook keys to restrict the per-book `books[]` array to. Global best_market / median_market / worst_market are unchanged. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/picks/12345'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| model | query | string | lgbm_ens | One of: lgbm_ens (production), lgbm, pca, baseline. |
| kind | query | string | all | Filter by prediction_kind. One of: dev, holdout, live, all. |
| limit | query | integer | 1000 | Max rows returned. Hard cap 10000. |
Notes
- ›Only fights with `result IN ('a_win', 'b_win')` AND `date <= CURRENT_DATE` are returned — bogus future-dated wiki imports are filtered.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/picks/historical'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| fight_id* | path | integer | — | Fight identifier. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/picks/12345/explain'Bet Optimizer
Cross-book arbitrage scanning, +EV ranking by ROI per dollar, and equal-profit hedge calculation. Every endpoint respects an optional `books` CSV so callers see only opportunities executable at the sportsbooks they actually have accounts at.
Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| books | query | string | — | CSV of sportsbook keys (e.g. `pinnacle,draftkings,fanduel`) to consider. Omit = all books. An arb at three books you don't have accounts at isn't an opportunity — always set this. |
| min_profit_pct | query | number | 0 | Drop opportunities with a modeled profit below this %. Useful to filter out paper-thin spreads whose margin may not cover bet limits or execution slippage. |
| outlay | query | number | — | Total $ outlay to size the stake split against. When set, each opportunity includes a `recommended_split` with leg_picked / leg_opposite stakes and the equal modeled payout (if both legs fill). |
Notes
- ›Boxing arbs typically persist for HOURS — sometimes days — when a soft book drifts off consensus. NBA/NFL arbs vanish in seconds.
- ›Same-book arbs are filtered out (the math holds but they're not actionable cross-book opportunities).
- ›Only pending fights with `date >= today UTC` and a model prediction are scanned. Use /api/v1/picks/live first if you need to verify the underlying pick.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/optimizer/arbitrage'Example response data
{
"fight_id": 12345,
"fight_date": "2026-05-31",
"fighter_a": "Karen Chukhadzhian",
"fighter_b": "Paddy Donovan",
"leg_picked": {
"side": "a",
"fighter": "Karen Chukhadzhian",
"book": "betfair_ex_eu",
"book_classification": "sharp",
"decimal_odds": 2.18,
"american_odds": 118,
"implied_prob_raw": 0.4587
},
"leg_opposite": {
"side": "b",
"fighter": "Paddy Donovan",
"book": "betmgm",
"book_classification": "soft",
"decimal_odds": 1.95,
"american_odds": -105,
"implied_prob_raw": 0.5128
},
"inverse_sum": 0.9715,
"profit_pct": 2.85,
"recommended_first_leg": "leg_opposite",
"recommended_split": {
"leg_picked_stake_dollars": 235.78,
"leg_opposite_stake_dollars": 263.42,
"total_outlay_dollars": 499.2,
"locked_payout_dollars": 513.42,
"locked_profit_dollars": 14.22
}
}Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| books | query | string | — | CSV of sportsbook keys to consider. Omit = all books. |
| min_edge_pp | query | number | 0 | Minimum vig-removed edge (in fraction, e.g. 0.02 = 2%) to include. |
| max_uncertainty | query | number | 1 | Maximum ensemble σ to include. Default 1.0 = no gate; pass 0.010 to apply the production gate. |
| bankroll | query | number | 0 | USD bankroll for Kelly stake sizing. 0 disables sizing. |
| kelly_fraction | query | number | 0.25 | Kelly multiplier (audit recommends 0.25 = Quarter Kelly). |
| kelly_z | query | number | 0 | σ shrink: p_used = max(0.001, fair − z·σ). 0 = naive Kelly (production default). |
| max_bet_pct | query | number | 0.03 | Per-bet stake cap as fraction of bankroll. 0 disables cap. |
Notes
- ›`roi_per_dollar` is the correct sort key for capital efficiency, not raw `edge_pp`.
- ›Books that quote only one side fall back to raw implied (best.impliedRaw) instead of vig-removed — conservative; understates edge slightly.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/optimizer/plus-ev'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| fight_id* | query | integer | — | Internal fight identifier (see /api/v1/picks/live). |
| stake* | query | number | — | USD amount you've already wagered (must be > 0). |
| odds* | query | number | — | Decimal odds your bet is locked in at. Must be > 1. (e.g. 2.10 for +110.) |
| side* | query | string | — | Which side of the fight you bet. Must be `a` or `b`. |
| books | query | string | — | CSV of sportsbook keys to consider for the opposite-side quote. Omit = all books. |
Notes
- ›Returns 404 `fight_not_found` if the fight has settled or no live pick exists for it.
- ›Returns 404 `no_hedge_quote` if no book in the (possibly filtered) set has a usable opposite-side price.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/optimizer/hedge'Example response data
{
"fight_id": 12345,
"fight_date": "2026-05-31",
"fighter_a": "Karen Chukhadzhian",
"fighter_b": "Paddy Donovan",
"your_bet": {
"side": "a",
"fighter": "Karen Chukhadzhian",
"stake_dollars": 100,
"decimal_odds": 2.5,
"american_odds": 150
},
"hedge": {
"side": "b",
"fighter": "Paddy Donovan",
"book": "fanduel",
"decimal_odds": 2,
"american_odds": 100,
"stake_dollars": 125
},
"outcome": {
"total_outlay_dollars": 225,
"gross_payout_dollars": 250,
"locked_profit_dollars": 25,
"locked_roi": 0.1111
}
}Closing Line Value
CLV measurements across the universe (devig vs raw close, decay over time, bootstrap CIs). These are the headline edge metrics.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/clv/evolution'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/clv/devig'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/clv/openclose'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/clv/ci'Model introspection
Internals of the production lgbm_ens_v5 model — feature importances, rolling metrics, calibration, refit P&L, holdout audit, MC Kelly survival curves.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/summary'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/comparison'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/coefs'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| window | query | integer | 50 | Rolling window size in predictions (1–500). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/rolling'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| bins | query | integer | 10 | Number of equal-width bins on [0, 1] (3–30). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/calibration'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/refit-sample'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/feature-pnl'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/regression'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/pca'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/mc-kelly'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/model/holdout-audit'Data & audit
Underlying data quality, distributions, odds-source coverage, and the resolution log for ingestion provenance.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/audit/data-quality'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/audit/corpus'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| limit | query | integer | 500 | Max comparison rows (10–2000). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/audit/odds-comparison'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| limit | query | integer | 100 | Max rows. Cap 500. |
| search | query | string | — | Case-insensitive fighter-name substring. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/audit/resolution-log'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/audit/distributions'Bookmakers
Catalog of every sportsbook the system tracks: region, sharp/soft classification, current pending-pick coverage, and per-book median overround (vig). Powers per-user book selection across the optimizer + picks endpoints.
Notes
- ›Sharp = Pinnacle, Bookmaker.eu, BetMGM, Circa, etc. Source list is `SHARP_BOOKS` in `src/lib/proof-of-edge.ts`.
- ›`median_overround_pp` of 0.05 = 5% vig (typical soft book). Pinnacle / sharp books typically run 2-4%.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/bookmakers'Example response data
[
{
"book": "pinnacle",
"region": "eu",
"classification": "sharp",
"pending_picks_quoting": 22,
"pending_picks_paired": 22,
"median_overround_pp": 0.0264
},
{
"book": "draftkings",
"region": "us",
"classification": "soft",
"pending_picks_quoting": 18,
"pending_picks_paired": 18,
"median_overround_pp": 0.0571
}
]Fighters
Per-fighter biographical and feature data backing the prediction model. List + detail endpoints.
Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| search | query | string | — | Case-insensitive name substring (ILIKE %search%). Trimmed. |
| limit | query | integer | 100 | Max rows per page. Hard cap 500. |
| offset | query | integer | 0 | Skip count for pagination. Hard cap 100000. |
| has_bio | query | boolean | false | When true, drop rows with no biometrics populated (no dob AND no stance AND no height AND no reach). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/fighters'Example response data
[
{
"fighter_id": 1248,
"name": "Karen Chukhadzhian",
"source": "boxrec",
"dob": "1996-05-23",
"stance": "orthodox",
"height_cm": 178,
"reach_cm": 183,
"nationality": "Ukraine",
"total_fights": 28
}
]Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| fighter_id* | path | integer | — | Internal fighter identifier (see /api/v1/fighters or /api/v1/schemas/master/fighter). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/fighters/678'Bet Journal
Per-user bet journal — log, list, settle, and analyze your bets with point-in-time model snapshots. Full CRUD + analytics aggregates.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/journal/bets'Example response data
{
"id": "uuid",
"source": "pick",
"fightId": 1234,
"pickedFighter": "Oleksandr Usyk",
"bookKey": "pinnacle",
"decimalOdds": 1.85,
"americanOdds": -118,
"stake": 250,
"currency": "USD",
"snapshotEdge": 0.042,
"snapshotClvAtLog": 0.038,
"status": "won",
"payout": 462.5,
"realizedClv": 0.035
}Line History
Universal line movement data for any fight. Per-book time series, market median, and summary stats. Public endpoints — no auth required.
My Bookmakers
Per-user sportsbook account management — save bookmaker credentials, VPN locations, and balances.
Admin (all users)
System-wide endpoints that cross the per-user boundary: list ALL users, ALL bets, ALL bookmakers and notification prefs, plus aggregate dashboard stats. These require the system API_TOKEN (not a per-user sbp_ key) and back an admin app/dashboard frontend with full read access to every user's data.
/api/v1/admin/stats bearerExample request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/stats'Example response data
{
"users": {
"total": 42,
"last_7d": 5,
"last_30d": 18
},
"bets": {
"total": 310,
"pending": 64,
"settled": 246,
"total_stake": 26350,
"realized_pnl": 1240.5,
"mean_clv": 0.031
},
"pipeline": {
"last_run_age_minutes": 3,
"last_run_ok": true,
"runs_24h": 287,
"healthy": true
},
"predictions": {
"live": 48,
"expired": 213
}
}/api/v1/admin/users bearerParameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| limit | query | integer | 500 | Max rows. Hard cap 5000. |
| offset | query | integer | 0 | Pagination offset. |
| search | query | string | — | Case-insensitive email/name substring filter. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/users'Example response data
{
"id": "uuid",
"email": "user@example.com",
"name": "Jane Doe",
"createdAt": "2026-05-01T12:00:00Z",
"betCount": 23,
"pendingBets": 4,
"settledBets": 19,
"totalStake": 1955,
"realizedPnl": 120.5,
"meanClv": 0.028,
"bookmakerCount": 3,
"apiKeyCount": 1,
"notificationsEnabled": true
}/api/v1/admin/users/{userId} bearerParameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| userId* | path | string | — | User UUID (from /api/v1/admin/users). |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/users/{userId}'/api/v1/admin/bets bearerParameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| limit | query | integer | 500 | Max rows. Hard cap 5000. |
| offset | query | integer | 0 | Pagination offset. |
| status | query | string | — | Filter by status: pending | won | lost | push. |
| user_id | query | string | — | Filter to a single user UUID. |
| since | query | string | — | ISO date — only bets placed on/after this date. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/bets'/api/v1/admin/bookmakers bearerParameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| user_id | query | string | — | Filter to a single user UUID. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/bookmakers'/api/v1/admin/notifications bearerExample request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/admin/notifications'Operations
Live cron run log and the latest persisted walk-forward backtest snapshot.
Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| limit | query | integer | 25 | Max rows. Cap 200. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/runs'Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/backtest/latest'Schema browser
Generic read-only access to the master schema. Tables, columns, and sampled rows.
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/schemas'Parameters
| Name | In | Type | Default | Description |
|---|---|---|---|---|
| schema* | path | string | — | Schema name (e.g. master). |
| table* | path | string | — | Table name. |
| limit | query | integer | 50 | Max sample rows. Cap 100. |
Example request
curl -H "Authorization: Bearer $API_TOKEN" 'https://spartanboxing.ai/api/v1/schemas/master/prediction'Status codes
| Code | When | Recovery |
|---|---|---|
| 200 | Success. data field present. | — |
| 400 | Malformed query / path param (invalid_fight_id, invalid_stake, offset_too_large, …). | Read error.code and error.message; fix the request and retry. |
| 401 | Missing, invalid, or revoked token (unauthorized, invalid_key). | Mint a new key above and resend the request. |
| 404 | Resource doesn't exist or hasn't been generated yet (fight_not_found, fighter_not_found, no_hedge_quote). | Check the underlying audit / cron has run, or remove restrictive filters. |
| 500 | Internal fetcher crashed (db_error, fetch_failed). | Retry after a few seconds. If persistent, open an issue with the request URL and timestamp. |