{"openapi":"3.1.0","info":{"title":"Sorqen API","version":"0.1.0","description":"Sorqen API is a sports fair-value API and MCP server by Flash AI Solutions, providing sportsbook-derived no-vig probabilities, confidence, provenance, history, and prediction-market reference pricing. Discovery and schemas are public. Current product data requires an authenticated Free or paid API key; Free is real limited access, not anonymous access.","contact":{"name":"Flash AI Solutions","url":"https://flashaisolutions.org"},"license":{"name":"Proprietary hosted API; local @sorqen packages are separately licensed"},"x-sorqen-discovery-policy":"Discovery is public. Product data is authenticated."},"servers":[{"url":"https://sorqen.flashodds.live","description":"Sorqen public API origin"}],"externalDocs":{"description":"Sorqen documentation","url":"https://sorqen.flashodds.live/docs"},"tags":[{"name":"Fair Values","description":"Sportsbook-derived no-vig consensus probabilities."},{"name":"Grading","description":"Grade a pregame price against what the Sorqen record said at that moment, against Sorqen Close, and against the settled result."},{"name":"Context","description":"Settlement, source and method context for interpreting fair values."},{"name":"Account","description":"Plan, entitlement and usage introspection for the authenticated key."},{"name":"Alerts","description":"Webhook alert rules. Plan-gated."}],"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"Sorqen API key","description":"Get a Free key at https://sorqen.flashodds.live/keys."},"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"Alternative to bearer auth. Get a Free key at https://sorqen.flashodds.live/keys."}},"schemas":{"FairValue":{"type":"object","required":["outcome_id","league","market_type","fair_probability","method_version"],"properties":{"outcome_id":{"type":"string"},"market_id":{"type":"string"},"event_id":{"type":"string"},"league":{"type":"string","enum":["nfl","nba","mlb","nhl"]},"market_type":{"type":"string","enum":["moneyline","spread","total"]},"selection":{"type":"string"},"starts_at":{"type":"string","format":"date-time"},"fair_probability":{"type":["number","null"],"minimum":0,"maximum":1,"description":"Null means Sorqen refused to produce a number; limiting_factor explains why."},"confidence":{"type":["number","null"],"minimum":0,"maximum":1},"dispersion":{"type":["number","null"]},"books":{"type":"integer"},"limiting_factor":{"type":["string","null"]},"method_version":{"type":"string"},"computed_at":{"type":"string","format":"date-time"},"oldest_component_age_s":{"type":["integer","null"]},"evidence":{"type":"object","description":"Paid-plan component evidence. Omitted when the plan does not include evidence."}},"example":{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","league":"nfl","market_type":"moneyline","period":"full_game","selection":"buf","fair_probability":0.574,"confidence":0.91,"dispersion":0.018,"books":7,"limiting_factor":null,"method_version":"example-book-consensus-novig"}},"GradePrice":{"type":"object","required":["format","value"],"description":"The price you accepted, and what kind of number it is. The format is DECLARED, never inferred: a bare 1.91 is decimal odds to one caller and a nonsense probability to another, and guessing from magnitude produces a plausible wrong grade rather than an error.","properties":{"format":{"type":"string","enum":["american","decimal","probability"]},"value":{"type":"number","description":"American: any non-zero integer (-150 is 0.600000). Decimal: greater than 1. Probability: strictly between 0 and 1."}},"example":{"format":"american","value":-150}},"GradeRequest":{"type":"object","required":["outcome_id","observed_at","price"],"properties":{"outcome_id":{"type":"string","description":"Canonical Sorqen outcome id."},"observed_at":{"type":"string","format":"date-time","description":"When you saw the price. Must be before the scheduled start: Sorqen grades pregame prices and publishes no live-market benchmark. Only information that existed at or before this instant is used."},"price":{"$ref":"#/components/schemas/GradePrice"},"venue":{"type":["string","null"],"description":"Optional label for where your price came from. METADATA ONLY: Sorqen never fetches the venue and no code path reads this to decide anything."}},"example":{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","observed_at":"2026-09-19T18:05:00Z","price":{"format":"american","value":-150},"venue":"draftkings"}},"GradeBenchmarkPoint":{"type":"object","required":["state"],"description":"One anchor. `available` carries the numbers; `pending` means ask again later; `unavailable` means it will never exist. A missing anchor is never reported as zero.","properties":{"state":{"type":"string","enum":["available","pending","unavailable"]},"reason":{"type":"string","description":"Present when the state is not available."},"probability":{"type":"number","minimum":0,"maximum":1},"confidence":{"type":["number","null"]},"dispersion":{"type":["number","null"]},"books":{"type":"integer"},"method_version":{"type":"string"},"observed_at":{"type":"string","format":"date-time"},"frozen_at":{"type":"string","format":"date-time","description":"When Sorqen named this observation a benchmark. Close only."},"policy_version":{"type":"string","description":"Which benchmark selection policy chose it. Close only."},"inputs_hash":{"type":"string","description":"Recomputable from the stored benchmark row. Close only."}}},"GradeResult":{"type":"object","required":["state"],"properties":{"state":{"type":"string","enum":["settled","pending","unavailable"]},"reason":{"type":"string"},"won":{"type":["boolean","null"],"description":"Null on a push, where nobody won."},"push":{"type":"boolean"},"final_score_home":{"type":["integer","null"]},"final_score_away":{"type":["integer","null"]},"settled_at":{"type":"string","format":"date-time"}}},"GradeResponse":{"type":"object","required":["outcome_id","claim","fair_at_time","fair_close","result","provenance"],"properties":{"outcome_id":{"type":"string"},"claim":{"type":"object","properties":{"observed_at":{"type":"string","format":"date-time"},"probability":{"type":"number","description":"Your price, normalized to an implied probability."},"venue":{"type":["string","null"]}}},"fair_at_time":{"$ref":"#/components/schemas/GradeBenchmarkPoint"},"fair_close":{"$ref":"#/components/schemas/GradeBenchmarkPoint"},"edge_at_time_pts":{"type":["number","null"],"description":"(fair at time - your probability) x 100. Positive means you took the outcome cheaper than the record said it was worth at that moment. Null when the anchor is unavailable; never zero."},"clv_pts":{"type":["number","null"],"description":"(Sorqen Close - your probability) x 100. Closing-line value. Null until the close is frozen; never zero."},"result":{"$ref":"#/components/schemas/GradeResult"},"provenance":{"type":"object","description":"Deterministic: the same claim graded against the same record yields the same hash. No signature field is emitted, because Sorqen does not yet publish a verification key and a cryptographic-looking placeholder would be worse than none.","properties":{"grade_method_version":{"type":"string"},"grade_inputs_hash":{"type":"string"}}}},"example":{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","claim":{"observed_at":"2026-09-19T18:05:00Z","probability":0.6,"venue":"draftkings"},"fair_at_time":{"state":"available","probability":0.602,"confidence":0.91,"dispersion":0.018,"books":7,"method_version":"example-book-consensus-novig","observed_at":"2026-09-19T18:00:00Z"},"fair_close":{"state":"available","probability":0.611,"confidence":0.93,"dispersion":0.014,"books":8,"method_version":"example-book-consensus-novig","observed_at":"2026-09-21T16:58:00Z","frozen_at":"2026-09-21T17:05:00Z","policy_version":"benchmark-1.0.0","inputs_hash":"sha256:0f3a1c7d9b2e4a6c8d0f2b4a6c8e0d2f"},"edge_at_time_pts":0.2,"clv_pts":1.1,"result":{"state":"settled","won":true,"push":false,"final_score_home":27,"final_score_away":24,"settled_at":"2026-09-21T20:31:00Z"},"provenance":{"grade_method_version":"grade-1.0.0","grade_inputs_hash":"sha256:7a1c0f3d9b2e4a6c8d0f2b4a6c8e0d2f"}}},"Error":{"type":"object","required":["error","message"],"properties":{"error":{"type":"string"},"message":{"type":"string"},"request_id":{"type":"string"}}}}},"security":[{"bearerAuth":[]},{"apiKeyHeader":[]}],"paths":{"/v1/fair-values":{"get":{"tags":["Fair Values"],"summary":"List current sportsbook-consensus fair values","description":"Returns real current fair values for an authenticated Free or paid key. Free sees the number at the same freshness as paid plans; paid plans can include evidence and higher limits.","operationId":"listFairValues","parameters":[{"name":"league","in":"query","schema":{"type":"string"},"description":"Comma-separated league ids."},{"name":"market_type","in":"query","schema":{"type":"string"},"description":"Comma-separated market types."},{"name":"min_confidence","in":"query","schema":{"type":"number","minimum":0,"maximum":1}},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Current fair values, shaped to the caller plan.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"type":"array","items":{"$ref":"#/components/schemas/FairValue"}},"page":{"type":"object"},"meta":{"type":"object"}}},"example":{"data":[{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","league":"nfl","market_type":"moneyline","period":"full_game","selection":"buf","fair_probability":0.574,"confidence":0.91,"dispersion":0.018,"books":7,"limiting_factor":null,"method_version":"example-book-consensus-novig"}],"meta":{"plan":"free","synthetic_example":true}}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/fair-values/{outcomeId}":{"get":{"tags":["Fair Values"],"summary":"Read one current fair value by canonical outcome id","description":"The single-outcome read behind the MCP get_fair_value tool. Same plan shaping as the list route: evidence appears only on plans that include it.","operationId":"getFairValue","parameters":[{"name":"outcomeId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One current fair value, shaped to the caller plan.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/FairValue"},"meta":{"type":"object"}}},"example":{"data":{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","league":"nfl","market_type":"moneyline","period":"full_game","selection":"buf","fair_probability":0.574,"confidence":0.91,"dispersion":0.018,"books":7,"limiting_factor":null,"method_version":"example-book-consensus-novig"},"meta":{"synthetic_example":true}}}}},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No current fair value for that outcome id."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/fair-values/{outcomeId}/history":{"get":{"tags":["Fair Values"],"summary":"Read fair-value history for one outcome","description":"History is plan-gated. Free keys authenticate successfully but receive plan_required; Builder and above receive a plan-bounded window.","operationId":"getFairValueHistory","parameters":[{"name":"outcomeId","in":"path","required":true,"schema":{"type":"string"}},{"name":"days","in":"query","schema":{"type":"integer","minimum":1,"maximum":3650}}],"responses":{"200":{"description":"Historical fair-value series."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No history in the requested window."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/grade":{"post":{"tags":["Grading"],"summary":"Grade a pregame price against the Sorqen record","description":"Give Sorqen a price and the time you saw it. It answers what its fair-value record said at that exact point in market time, compares the price with an immutable Sorqen Close, and attaches the settled result when there is one.\n\nNO LOOK-AHEAD: `fair_at_time` is the last priced observation at or BEFORE `observed_at`. A nearer later observation is deliberately not used.\n\nA PARTIAL GRADE IS A NORMAL ANSWER: before kickoff there is no close and no result, so those anchors come back `pending` and the metrics that depend on them are null rather than zero.\n\nSorqen never fetches your venue. `venue` is a label for your own records.","operationId":"gradeClaim","requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/GradeRequest"}}}},"responses":{"200":{"description":"The grade, including partial grades where the close or the result does not exist yet.","content":{"application/json":{"schema":{"type":"object","properties":{"data":{"$ref":"#/components/schemas/GradeResponse"},"meta":{"type":"object"}}},"example":{"data":{"outcome_id":"pe:evt:nfl:2026-09-21:nyg-buf:moneyline:full_game:buf","claim":{"observed_at":"2026-09-19T18:05:00Z","probability":0.6,"venue":"draftkings"},"fair_at_time":{"state":"available","probability":0.602,"confidence":0.91,"dispersion":0.018,"books":7,"method_version":"example-book-consensus-novig","observed_at":"2026-09-19T18:00:00Z"},"fair_close":{"state":"available","probability":0.611,"confidence":0.93,"dispersion":0.014,"books":8,"method_version":"example-book-consensus-novig","observed_at":"2026-09-21T16:58:00Z","frozen_at":"2026-09-21T17:05:00Z","policy_version":"benchmark-1.0.0","inputs_hash":"sha256:0f3a1c7d9b2e4a6c8d0f2b4a6c8e0d2f"},"edge_at_time_pts":0.2,"clv_pts":1.1,"result":{"state":"settled","won":true,"push":false,"final_score_home":27,"final_score_away":24,"settled_at":"2026-09-21T20:31:00Z"},"provenance":{"grade_method_version":"grade-1.0.0","grade_inputs_hash":"sha256:7a1c0f3d9b2e4a6c8d0f2b4a6c8e0d2f"}},"meta":{"plan":"builder","synthetic_example":true}}}}},"400":{"description":"The claim is malformed, or `observed_at` is at or after the scheduled start. Machine-readable codes: invalid_body, invalid_outcome_id, invalid_observed_at, invalid_price, unknown_price_format, invalid_venue, claim_after_start."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No such canonical outcome."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/settlement-rules":{"get":{"tags":["Context"],"summary":"Read settlement context for local prediction-market comparison","description":"Returns per-venue settlement context and tie prior. It is not a venue market feed and does not contain venue prices.","operationId":"getSettlementRules","responses":{"200":{"description":"Settlement rules and tie prior."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/sources":{"get":{"tags":["Context"],"summary":"Read upstream source health and freshness","operationId":"listSources","responses":{"200":{"description":"Source health envelope."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/methods":{"get":{"tags":["Context"],"summary":"Read versioned fair-value method metadata","operationId":"listMethods","responses":{"200":{"description":"Method metadata."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/events":{"get":{"tags":["Context"],"summary":"List canonical sports events","operationId":"listEvents","parameters":[{"name":"league","in":"query","schema":{"type":"string"},"description":"Comma-separated league ids."},{"name":"limit","in":"query","schema":{"type":"integer","minimum":1}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Canonical event records."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/events/{eventId}":{"get":{"tags":["Context"],"summary":"Read one canonical event and its markets","operationId":"getEvent","parameters":[{"name":"eventId","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"One canonical event."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No such event."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/leagues":{"get":{"tags":["Context"],"summary":"List supported leagues, market types and coverage counts","operationId":"listLeagues","responses":{"200":{"description":"League coverage."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/changes":{"get":{"tags":["Context"],"summary":"Read the incremental change feed","description":"Cursor-paged feed of canonical changes. Entitlement changeFeed is required; Free keys authenticate and receive plan_required.","operationId":"listChanges","parameters":[{"name":"league","in":"query","schema":{"type":"string"}},{"name":"type","in":"query","schema":{"type":"string"}},{"name":"cursor","in":"query","schema":{"type":"string"}}],"responses":{"200":{"description":"Change events with a next cursor."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/plans":{"get":{"tags":["Account"],"summary":"List public plans, limits and entitlements","operationId":"listPlans","responses":{"200":{"description":"The public plan ladder."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/me":{"get":{"tags":["Account"],"summary":"Read the authenticated key, plan and entitlements","operationId":"getMe","responses":{"200":{"description":"Caller identity, limits and entitlements."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/usage":{"get":{"tags":["Account"],"summary":"Read daily request usage for this key","operationId":"getUsage","responses":{"200":{"description":"Up to 31 days of daily counts."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/alerts":{"get":{"tags":["Alerts"],"summary":"List alert rules for this key","operationId":"listAlerts","responses":{"200":{"description":"Alert rules."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}},"post":{"tags":["Alerts"],"summary":"Create an alert rule","description":"Alerts are plan-gated. The response includes a signing secret shown once; Sorqen stores only its hash.","operationId":"createAlert","requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":"string"},"target_url":{"type":"string","format":"uri"},"filters":{"type":"object"}}}}}},"responses":{"201":{"description":"Rule created; the signing secret is returned once."},"400":{"description":"Rule rejected."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/alerts/{id}":{"delete":{"tags":["Alerts"],"summary":"Delete an alert rule","operationId":"deleteAlert","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"204":{"description":"Deleted."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No such rule."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}},"/v1/alerts/{id}/deliveries":{"get":{"tags":["Alerts"],"summary":"Read recent delivery attempts for one rule","operationId":"listAlertDeliveries","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Delivery attempts."},"401":{"description":"Missing or invalid API key."},"403":{"description":"The authenticated plan does not include this entitlement."},"404":{"description":"No such rule."},"429":{"description":"Plan request limit exceeded. Retry-After and X-RateLimit headers are returned."}}}}}}