Founding Discord member? Claim free Legacy access by 5 November 2026 (24 days left). Claim now
API plan
Build on the ledger
Picks, tips and settled history as JSON. Read the reference, then create and revoke your keys further down this same page. The OpenAPI description is public.
Your API keys
API plan
Launch price · standard price $24.99 a month
Everything in Pro, plus a keyed REST API so your own scripts, spreadsheets and AI agents can read the picks.
- Everything in Pro
- REST API: picks, tips and settled history as JSON
- Self-serve API keys with expiry and instant revoke
- OpenAPI spec and agent-ready documentation
- Rate limit: 50 requests per 30 minutes per key
Free for 7 days, then billed monthly. Cancel any time. 18+ only.
From here to your first call
Start your 7-day free trial
Pay by card, or Apple Pay or Google Pay where your device supports it, through Whop. Cancel any time before the trial ends.
Sign in to unlock it
One click with the Whop account you just paid with. It brings you straight back here.
Create a key and make your first call
Keys appear on this page with expiry and instant revoke. The Quick Start below has a copy-paste request.
Already on the API plan?
Sign in with the Whop account you subscribed with to manage your keys.
Sign inQuick Start
- Create an API key in Your API keys above (needs the API plan).
- Optionally download the Postman collection for pre-configured requests.
- Include your key in the
x-api-keyheader on every request. - All endpoints return JSON. Rate limits are included in response headers.
Authentication
All endpoints require an API key. Pass it in one of two ways:
x-api-key: pk_live_xxxxxxxx_yyyyyyyy...Or equivalently: Authorization: Bearer pk_live_xxxxxxxx_yyyyyyyy...
You create your own keys. Each key is SHA-256 hashed at rest, can have an expiry date and can be revoked instantly. Never paste a key into a chat window; read it from an environment variable.
Rate Limiting
Each API key is limited to 50 requests per 30 minutes (sliding window). Exceeding this returns HTTP 429 with a Retry-After header.
Every response includes: X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (Unix epoch seconds).
GET /api/bets/history
Returns all tracked bets (open and settled) whose event_date falls within the specified UTC window. Tracked bets carry a virtual stake and P&L.
Required Query Parameters
| Param | Type | Description |
|---|---|---|
start_utc | ISO 8601 UTC | Range start — must end with Z or +00:00 |
end_utc | ISO 8601 UTC | Range end (inclusive) |
Example Request
curl -s \
-H "x-api-key: $PROPHETAI_API_KEY" \
"https://prophetai.club/api/bets/history?start_utc=2026-04-01T00:00:00Z&end_utc=2026-04-30T23:59:59Z"Response Envelope
{
"data": [ <Bet>, <Bet>, ... ],
"count": 35,
"filter": {
"field": "event_date",
"start_utc": "2026-04-01T00:00:00.000Z",
"end_utc": "2026-04-30T23:59:59.000Z"
}
}Bet Object Schema
| Field | Type | Description |
|---|---|---|
| id | number | Internal database row ID |
| bet_id | string | Unique identifier (e.g. "PROP-037") |
| run_id | string | Pipeline run that created this bet |
| sport | string | Sport key (e.g. "football", "tennis", "ice-hockey") |
| league | string| null | Competition (e.g. "USA - NHL") |
| event_name | string | Full event description including series info |
| event_id | number| null | External odds-api event ID |
| event_date | ISO 8601| null | Scheduled kickoff time in UTC |
| selection | string | What was picked (e.g. "Philadelphia Flyers to Win") |
| bet_side | string| null | "home", "away", "over", "under", etc. |
| market | string | "ML", "Spread", "Totals", "BTTS", "WIN", etc. |
| odds_at_pick | number | Decimal odds at time of pick |
| best_odds | number| null | Best available odds across bookmakers |
| best_bookmaker | string| null | Bookmaker offering best odds |
| all_odds | object| null | Top 5 odds by bookmaker, sorted best-first (e.g. {"Bet365": "1.85", "William Hill": "1.83", ...}) |
| expected_value | number| null | Estimated edge as decimal (0.065 = +6.5% EV) |
| confidence | enum | "ELITE", "STRONG", "SOLID", "LEAN", "SPECULATIVE" (legacy: "HIGH", "MEDIUM", "LOW") |
| confidence_pct | number| null | Confidence as percentage (0–100) |
| virtual_stake | number | Virtual stake in bankroll units |
| rationale | string| null | AI-generated reasoning for the pick |
| status | enum | "open", "won", "lost", "void", or "push" |
| pnl | number| null | Profit/loss (null while open) |
| created_at | ISO 8601 | When the pick was recorded |
| settled_at | ISO 8601| null | When the bet was settled |
| settlement_src | string| null | Source (e.g. "sofascore + ai-settler") |
| settlement_detail | string| null | Score or outcome detail |
| series_info | string| null | Series context (e.g. "Game 6") |
| model_used | string| null | AI model slug that generated this bet (e.g. "claude-sonnet-4") |
| betfair_market_id | string| null | Betfair Exchange market ID |
| betfair_selection_id | number| null | Betfair Exchange selection ID |
Example Bet Object
{
"id": 37,
"bet_id": "PROP-037",
"run_id": "prophetai-20260429-082005-54197",
"sport": "ice-hockey",
"league": "USA - NHL",
"event_name": "Pittsburgh Penguins at Philadelphia Flyers (Game 6)",
"event_id": 70558128,
"event_date": "2026-04-29T23:30:00Z",
"selection": "Philadelphia Flyers to Win",
"bet_side": "home",
"market": "ML",
"odds_at_pick": 1.83,
"best_odds": 1.83,
"best_bookmaker": "Bet365",
"all_odds": { "Bet365": "1.85", "William Hill": "1.83", "Paddy Power": "1.83", "Ladbrokes": "1.80", "BetVictor": "1.80" },
"expected_value": 0.065,
"confidence": "HIGH",
"confidence_pct": 80,
"virtual_stake": 10,
"rationale": "Flyers lead this series 3-2 and come HOME for G6...",
"status": "won",
"pnl": 8.3,
"created_at": "2026-04-29T07:22:58Z",
"settled_at": "2026-05-05T09:32:41Z",
"settlement_src": "sofascore + ai-settler",
"settlement_detail": "Team A won 2-0 [AI-settled, confidence=0.95]",
"series_info": "Game 6",
"betfair_market_id": null,
"betfair_selection_id": null
}GET /api/tips
Returns tips — informational picks with no virtual staking or P&L. Tips are outcome-tracked (won/lost) but do not affect bankroll. All query parameters are optional; omitting all returns the full set.
Optional Query Parameters
| Param | Type | Description |
|---|---|---|
start_utc | ISO 8601 UTC | Filter by event_date range start |
end_utc | ISO 8601 UTC | Filter by event_date range end (inclusive) |
sport | string | Filter by sport (case-insensitive, e.g. tennis) |
status | enum | open, won, lost, void, or push |
acca_id | string | Filter to legs of a specific ACCA (e.g. ACCA-054) |
Date filters only apply when both start_utc and end_utc are provided. All filters combine freely. Use acca_id to retrieve just the legs belonging to a specific accumulator.
Example Requests
# All tips (no filters)
curl -s -H "x-api-key: $PROPHETAI_API_KEY" \
"https://prophetai.club/api/tips"
# Tennis tips that won
curl -s -H "x-api-key: $PROPHETAI_API_KEY" \
"https://prophetai.club/api/tips?sport=tennis&status=won"
# Tips for a specific date range
curl -s -H "x-api-key: $PROPHETAI_API_KEY" \
"https://prophetai.club/api/tips?start_utc=2026-04-01T00:00:00Z&end_utc=2026-04-30T23:59:59Z"
# Legs of a specific ACCA
curl -s -H "x-api-key: $PROPHETAI_API_KEY" \
"https://prophetai.club/api/tips?acca_id=ACCA-054"Response Envelope
{
"data": [ <Tip>, <Tip>, ... ],
"count": 230,
"filters": { // only present when filters are applied
"sport": "tennis",
"status": "won"
}
}Tip Object Schema
| Field | Type | Description |
|---|---|---|
| id | number | Internal database row ID |
| tip_id | string | Unique identifier (e.g. "TIP-228") |
| run_id | string | Pipeline run that created this tip |
| sport | string | Sport key (e.g. "horse-racing", "tennis") |
| league | string| null | Competition or venue (e.g. "Pontefract") |
| event_name | string | Full event description |
| event_id | number| null | External event ID (0 if unavailable) |
| event_date | ISO 8601| null | Scheduled event time in UTC |
| selection | string | What was tipped (e.g. "Infraad") |
| bet_side | string| null | "home", "away", etc. (often null) |
| market | string | "ML", "WIN", "Spread", "Totals", etc. |
| odds_at_post | number | Decimal odds at time of posting |
| confidence | enum| null | "HIGH", "MEDIUM", "LOW", or null |
| confidence_pct | number| null | Confidence percentage, or null |
| best_bookmaker | string| null | Bookmaker offering the quoted odds |
| rationale | string| null | AI-generated reasoning for the tip |
| acca_id | string| null | ACCA this tip is a leg of (e.g. "ACCA-054"), or null if standalone |
| status | enum | "open", "won", "lost", "void", or "push" |
| settled_at | ISO 8601| null | When the tip was settled |
| settlement_detail | string| null | Outcome detail |
| created_at | ISO 8601 | When the tip was recorded |
| model_used | string| null | AI model slug that generated this tip (e.g. "claude-sonnet-4") |
| betfair_market_id | string| null | Betfair Exchange market ID |
| betfair_selection_id | number| null | Betfair Exchange selection ID |
Example Tip Object
{
"id": 228,
"tip_id": "TIP-228",
"run_id": "prophetai-20260429-082005-54197",
"sport": "horse-racing",
"league": "Pontefract",
"event_name": "Pontefract 29th Apr - 1m2f NHC EBF Novice Stakes",
"event_id": 0,
"event_date": "2026-04-29T13:13:00Z",
"selection": "Infraad",
"bet_side": null,
"market": "WIN",
"odds_at_post": 1.97,
"confidence": null,
"confidence_pct": null,
"best_bookmaker": "Betfair Exchange",
"rationale": "Haggas-Marquand combo firing this spring...",
"acca_id": "ACCA-054",
"status": "won",
"settled_at": "2026-04-29T16:17:42Z",
"settlement_detail": "WINNER — Betfair market 1.257448466",
"created_at": "2026-04-29T07:23:17Z",
"betfair_market_id": "1.257448466",
"betfair_selection_id": 90262117
}Bets vs Tips
| Bets | Tips | |
|---|---|---|
| Virtual stake | Yes — affects bankroll | No — informational only |
| P&L tracking | Yes (pnl) | No |
| Outcome tracking | Yes | Yes (won/lost/void/push) |
| Expected value | expected_value | Not tracked |
| Odds field | odds_at_pick | odds_at_post |
| Multi-bookie odds | all_odds object | No |
| Date filter | Required | Optional |
Error Codes
| Code | Meaning | Common Cause |
|---|---|---|
400 | Bad Request | Missing/invalid date params, bad status filter |
401 | Unauthorized | Missing key, bad format, unknown or revoked key |
429 | Too Many Requests | 50 req / 30 min exceeded — check Retry-After |
500 | Server Error | Redis unavailable or internal error |
Error Response Shape
{
"error": "Rate limit exceeded. Max 50 requests per 30 minutes per API key."
}Postman Collection
A ready-to-use collection with pre-configured requests and built-in test scripts.
- Download the collection
- In Postman, click Import and select the file.
- Go to Variables and set
api_keyto the key you were given. - Keep
base_urlashttps://prophetai.club. - Run any request — auth headers are pre-configured.