{"openapi":"3.1.0","info":{"title":"sharksnip.com API v1","version":"1.0.0","description":"Public reads and existing authenticated operations. The discovery recipes name exact GET URLs; each operation retains its existing access rules."},"servers":[{"url":"https://sharksnip.com"}],"paths":{"/api/v1/public/picks":{"get":{"operationId":"getPublicPicks","summary":"Read the public picks board with attribution. No key, no account.","description":"Published picks under the same public visibility rules sharksnip.com/picks/{sport} serves every visitor. With no week, the upcoming slate: kickoffs in the next 7 days. With a week, that week of the newest season on our schedule. Free to quote and summarize with attribution: credit \"Shark Snip\" and link the page url this response carries. Every url is a live sharksnip.com page.","security":[],"parameters":[{"name":"sport","in":"query","required":false,"schema":{"type":"string","enum":["nfl","nba","mlb","nhl"],"default":"nfl"},"description":"Sport key. Defaults to nfl when omitted."},{"name":"week","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":30},"description":"NFL week. Supported for nfl only, because public.nfl_schedules is the first-party schedule a week resolves against; sending it with another sport is a 400 rather than an ignored filter. Omit it for the current board."}],"responses":{"200":{"description":"The public picks board with its attribution block.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPicksBoard"}}}},"400":{"description":"Unsupported sport, or a week filter for a non-NFL sport."},"429":{"description":"Per-IP rate limit exceeded."},"503":{"description":"Typed source-unavailable value. Never an empty picks array: an empty array means the board really is empty.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicApiUnavailable"}}}}}}},"/api/v1/public/pages":{"get":{"operationId":"getPublicPage","summary":"Get a shareable link to the live picks page for a slate","description":"Returns a link to the live sharksnip.com picks page, tagged with your agent name. NOTHING IS STORED: no page is created, no row is written, and the same input always returns the same url. There is no 503 because this call reads no source.","security":[],"parameters":[{"name":"sport","in":"query","required":false,"schema":{"type":"string","enum":["nfl","nba","mlb","nhl"],"default":"nfl"}},{"name":"week","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":30}},{"name":"agent","in":"query","required":false,"schema":{"type":"string","pattern":"^[a-z0-9-]{1,40}$"},"description":"Your assistant name; becomes utm_source on the returned link."}],"responses":{"200":{"description":"A link to the live picks page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPageLink"}}}},"400":{"description":"Unsupported sport, week or agent value."},"429":{"description":"Per-IP rate limit exceeded."}}},"post":{"operationId":"createPublicPage","summary":"Get a shareable link to the live picks page for a slate (JSON body)","description":"Identical to the GET form, with { sport, week, agent } in a JSON body. Named \"create\" for callers that expect a create verb; it still stores nothing.","security":[],"requestBody":{"required":false,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPageRequest"}}}},"responses":{"200":{"description":"A link to the live picks page.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPageLink"}}}},"400":{"description":"Body is not a JSON object, or an unsupported field value."},"429":{"description":"Per-IP rate limit exceeded."}}}},"/api/v1/lines":{"get":{"operationId":"getLines","summary":"Get public picks with best, earliest-in-view, and per-book sportsbook prices","security":[],"parameters":[{"name":"game","in":"query","required":false,"schema":{"type":"string"},"description":"Optional exact picks.game_id filter."},{"name":"market","in":"query","required":false,"schema":{"type":"string","enum":["spread","moneyline","total"]},"description":"Optional game-market filter."}],"responses":{"200":{"description":"Typed LineBoard; may be ready or honestly empty."},"400":{"description":"Unsupported market query."},"503":{"description":"Typed LineBoard unavailable state because a required source failed."}}}},"/api/v1/models":{"post":{"operationId":"createModel","summary":"Create a draft model in your account","security":[{"bearerAuth":[]}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateModelRequest"}}}},"responses":{"201":{"description":"Draft created","content":{"application/json":{"schema":{"$ref":"#/components/schemas/CreateModelResponse"}}}},"401":{"description":"Missing, invalid, or revoked key"},"402":{"description":"Saved-model cap reached on the free tier"},"403":{"description":"Key lacks the models:write scope"},"409":{"description":"You already have a model with this exact recipe. The error body carries `existingModelCardId`; open that model instead of retrying."},"422":{"description":"Validation failed (name, sport, or slots invalid)"},"429":{"description":"Rate limit exceeded (30 creates / hour / key)"}}},"get":{"operationId":"listModels","summary":"List your draft models (newest first, up to 50)","security":[{"bearerAuth":[]}],"responses":{"200":{"description":"Your models, newest first"},"401":{"description":"Missing, invalid, or revoked key"}}}},"/api/v1/models/{id}":{"get":{"operationId":"getModel","summary":"Get one of your draft models","security":[{"bearerAuth":[]}],"parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"The model"},"401":{"description":"Missing, invalid, or revoked key"},"404":{"description":"No such model owned by this key (existence never leaked as 403)"}}}},"/api/v1/props":{"get":{"operationId":"listProps","summary":"Read current NFL player-prop book lines and provenanced projections","security":[{"bearerAuth":[]}],"parameters":[{"name":"week","in":"query","required":false,"schema":{"type":"integer","minimum":1},"description":"NFL week. Omit to resolve the current week from nfl_schedules."},{"name":"market","in":"query","required":false,"schema":{"type":"string"},"description":"Canonical player-prop market key or registered alias."}],"responses":{"200":{"description":"PropsBoard. Projection is a discriminated provenanced(value, asOf, producer) or refused(reason) state; edge is present only with a known line and provenanced projection."},"400":{"description":"Invalid week or unsupported player-prop market"},"401":{"description":"Missing, invalid, or revoked key"},"503":{"description":"Required props-board source is unavailable"}}}},"/api/v1/record":{"get":{"operationId":"getRecord","summary":"Read the graded-record receipt for the API key owner","security":[{"bearerAuth":[]}],"parameters":[{"name":"sport","in":"query","required":false,"schema":{"type":"string","minLength":2,"maxLength":24,"pattern":"^[A-Za-z0-9_-]+$"},"description":"Sport key. Defaults to all."},{"name":"class","in":"query","required":false,"schema":{"type":"string","enum":["all","spread","total","moneyline","team-total","player-prop"]},"description":"Model class. Defaults to all."},{"name":"window","in":"query","required":false,"schema":{"type":"string","enum":["30d","90d","365d","all"]},"description":"Grading window. Defaults to 90d."},{"name":"basis","in":"query","required":false,"schema":{"type":"string","enum":["all","close","open","unpriced"]},"description":"Recorded price basis. Defaults to all."}],"responses":{"200":{"description":"Owner-scoped canonical graded-record receipt."},"400":{"description":"Invalid record filter."},"401":{"description":"Missing, invalid, or revoked key."},"503":{"description":"Record source unavailable."}}}},"/api/v1/picks":{"get":{"operationId":"listEquippedPicks","summary":"List visible picks from your equipped model set","security":[{"bearerAuth":[]}],"parameters":[{"name":"sport","in":"query","required":false,"schema":{"type":"string","default":"nfl"},"description":"Sport key. Defaults to nfl when omitted."},{"name":"week","in":"query","required":false,"schema":{"type":"integer","minimum":0},"description":"Optional week filter. Uses the active release for each equipped model."}],"responses":{"200":{"description":"Visible equipped picks; an empty array means no visible rows match the filter","content":{"application/json":{"schema":{"$ref":"#/components/schemas/PublicPicksResponse"}}}},"400":{"description":"Invalid sport or week query value"},"401":{"description":"Missing, invalid, or revoked public API key"},"403":{"description":"Key lacks the picks scope"},"429":{"description":"Per-key rate limit exceeded"},"503":{"description":"Equipped or served-pick source unavailable"}}}},"/api/v1/entities/nfl/players":{"get":{"operationId":"listNflEntityPlayers","summary":"List rostered fantasy players without a historical-feature-store cutoff.","security":[],"parameters":[{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":200,"default":100},"description":"Rows per page."},{"name":"cursor","in":"query","required":false,"schema":{"type":"string"},"description":"Opaque next_cursor. A changed identity population returns 409."},{"name":"team","in":"query","required":false,"schema":{"type":"string"},"description":"Known NFL abbreviation, alias or canonical team slug."},{"name":"position","in":"query","required":false,"schema":{"enum":["QB","RB","FB","WR","TE","K"]},"description":"Fantasy position."},{"name":"q","in":"query","required":false,"schema":{"type":"string","maxLength":80},"description":"Case-insensitive name substring. Never used as SQL."}],"responses":{"200":{"description":"Dated public data. Check partial and each module state before using a value.","headers":{"ETag":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/DirectoryResponse"}}}},"304":{"description":"Unchanged public representation; no response body."},"400":{"description":"Invalid or unsupported query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown or unsupported entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The directory changed (restart pagination), or a player name is ambiguous (use directory search and a canonical id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A required source could not be read. Retry-After is 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate-limit or transport policy may refuse the request."}}}},"/api/v1/entities/nfl/players/{player}":{"get":{"operationId":"getNflPlayerOutlook","summary":"Read one player using a GSIS ID, canonical slug or unique roster name.","security":[],"parameters":[{"name":"player","in":"path","required":true,"schema":{"type":"string"},"description":"nfl-prefixed or bare GSIS ID, optional __name suffix, exact normalized roster name, or props name@kickoff-minute. URL-encode names. Ambiguous names return 409; studio: model references return 400."}],"responses":{"200":{"description":"Dated public data. Check partial and each module state before using a value.","headers":{"ETag":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/PlayerResponse"}}}},"304":{"description":"Unchanged public representation; no response body."},"400":{"description":"Invalid or unsupported query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown or unsupported entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The directory changed (restart pagination), or a player name is ambiguous (use directory search and a canonical id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A required source could not be read. Retry-After is 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate-limit or transport policy may refuse the request."}}}},"/api/v1/entities/nfl/teams":{"get":{"operationId":"listNflEntityTeams","summary":"List the existing NFL team registry and canonical page paths.","security":[],"parameters":[],"responses":{"200":{"description":"Dated public data. Check partial and each module state before using a value.","headers":{"ETag":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamsResponse"}}}},"304":{"description":"Unchanged public representation; no response body."},"400":{"description":"Invalid or unsupported query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown or unsupported entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The directory changed (restart pagination), or a player name is ambiguous (use directory search and a canonical id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A required source could not be read. Retry-After is 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate-limit or transport policy may refuse the request."}}}},"/api/v1/entities/nfl/teams/{team}":{"get":{"operationId":"getNflTeamOutlook","summary":"Read a team roster, stored projections, season schedule and cited buzz.","security":[],"parameters":[{"name":"team","in":"path","required":true,"schema":{"type":"string"},"description":"Known abbreviation, alias or canonical team slug."}],"responses":{"200":{"description":"Dated public data. Check partial and each module state before using a value.","headers":{"ETag":{"schema":{"type":"string"}},"Cache-Control":{"schema":{"type":"string"}}},"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TeamResponse"}}}},"304":{"description":"Unchanged public representation; no response body."},"400":{"description":"Invalid or unsupported query.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown or unsupported entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"The directory changed (restart pagination), or a player name is ambiguous (use directory search and a canonical id).","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"503":{"description":"A required source could not be read. Retry-After is 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate-limit or transport policy may refuse the request."}}}},"/api/v1/entities/nfl/players/{player}/research":{"get":{"operationId":"getNflPlayerResearch","summary":"Read source-backed weekly outlook, matchup, usage, roster and availability context.","security":[],"parameters":[{"name":"player","in":"path","required":true,"schema":{"type":"string"},"description":"GSIS id, canonical slug, unique roster name or props name@kickoff-minute; URL-encode the reference."}],"responses":{"200":{"description":"Read each module state; historical usage is not a projection. No-store.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchResponse"}}}},"400":{"description":"Unsupported query or identity reference.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Ambiguous player name; use directory search and a canonical id."},"503":{"description":"Required source unavailable; retry after 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate or transport gate."}}}},"/api/v1/entities/nfl/teams/{team}/research":{"get":{"operationId":"getNflTeamResearch","summary":"Read source-backed weekly outlook, matchup, usage, roster and availability context.","security":[],"parameters":[{"name":"team","in":"path","required":true,"schema":{"type":"string"},"description":"NFL team abbreviation or slug."}],"responses":{"200":{"description":"Read each module state; historical usage is not a projection. No-store.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/ResearchResponse"}}}},"400":{"description":"Unsupported query or identity reference.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"404":{"description":"Verified unknown entity.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"409":{"description":"Ambiguous player name; use directory search and a canonical id."},"503":{"description":"Required source unavailable; retry after 60 seconds.","content":{"application/json":{"schema":{"$ref":"#/components/schemas/Error"}}}},"default":{"description":"Existing platform compliance, rate or transport gate."}}}},"/api/v1/public/props":{"get":{"operationId":"getPublicPropLines","summary":"Read the anonymous props board by player name, with the page’s visibility and pagination.","security":[],"parameters":[{"name":"sport","in":"query","required":false,"description":"nfl (default), nba, mlb or nhl.","schema":{"type":"string"}},{"name":"q","in":"query","required":false,"description":"Player display-name filter.","schema":{"type":"string"}},{"name":"week","in":"query","required":false,"description":"Optional NFL week.","schema":{"type":"string"}},{"name":"book","in":"query","required":false,"description":"Book filter.","schema":{"type":"string"}},{"name":"team","in":"query","required":false,"description":"Team filter.","schema":{"type":"string"}},{"name":"pos","in":"query","required":false,"description":"Position filter.","schema":{"type":"string"}},{"name":"market","in":"query","required":false,"description":"Market filter.","schema":{"type":"string"}},{"name":"sort","in":"query","required":false,"description":"board (default) or confidence.","schema":{"type":"string"}},{"name":"page","in":"query","required":false,"description":"Player page, starting at 1; 6 players per page.","schema":{"type":"string"}},{"name":"player","in":"query","required":false,"description":"Props grouping key returned by the board; expands that player.","schema":{"type":"string"}},{"name":"marketPage","in":"query","required":false,"description":"Expanded player market page, starting at 1; 12 markets per page.","schema":{"type":"string"}}],"responses":{"200":{"description":"{ sport, filters, board }; board includes capture state, bounded players and the same public page fields. Empty boards remain explicit."},"400":{"description":"Unsupported or invalid board filters."},"503":{"description":"The prebuilt prop source or requested week could not be read."}}}},"/api/dfs/projections":{"get":{"operationId":"getDfsPageProjections","summary":"Read the existing DFS page player pool under the existing caller visibility rules.","security":[],"parameters":[{"name":"sport","in":"query","required":true,"description":"nfl, nba, mlb or nhl.","schema":{"type":"string"}},{"name":"slate","in":"query","required":false,"description":"Optional DraftKings draft group id; omit for main slate.","schema":{"type":"string"}}],"responses":{"200":{"description":"Page player pool, slate, coverage, generatedAt and typed availability reason. Check projectionSource before quoting a projection."},"400":{"description":"Unknown sport."},"503":{"description":"Salaries or the snapshot could not be read."},"default":{"description":"Existing platform gates and unexpected source failures retain their current statuses."}}}},"/api/registry/models":{"get":{"operationId":"getPublicLiveModels","summary":"List existing public live model cards; no ranking is calculated.","security":[],"parameters":[{"name":"sport","in":"query","required":false,"description":"Optional sport key.","schema":{"type":"string"}},{"name":"owner","in":"query","required":false,"description":"Optional owner id from a public card.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"Up to 200 cards, default 60.","schema":{"type":"string"}}],"responses":{"200":{"description":"{ models: ModelCardSummary[] } from public live cards."},"500":{"description":"Model registry could not be read."}}}},"/api/benchmarks/suites":{"get":{"operationId":"getPublicBenchmarkSuites","summary":"Find the existing active benchmark suite slugs.","security":[],"parameters":[{"name":"sport","in":"query","required":false,"description":"Optional sport key.","schema":{"type":"string"}},{"name":"objective","in":"query","required":false,"description":"Optional suite objective.","schema":{"type":"string"}}],"responses":{"200":{"description":"{ ok, suites } with active suite slugs and metric definitions."},"500":{"description":"Suite source could not be read."}}}},"/api/benchmarks/leaderboard":{"get":{"operationId":"getPublicBenchmarkLeaderboard","summary":"Read a leaderboard for a returned benchmark suite slug.","security":[],"parameters":[{"name":"suite","in":"query","required":true,"description":"Slug from GET /api/benchmarks/suites.","schema":{"type":"string"}},{"name":"as_of","in":"query","required":false,"description":"Optional YYYY-MM-DD historical snapshot cutoff.","schema":{"type":"string"}},{"name":"limit","in":"query","required":false,"description":"1–250 rows, default 100.","schema":{"type":"string"}}],"responses":{"200":{"description":"{ ok, suite, leaderboard, as_of? }; ranks are those of the existing suite."},"404":{"description":"Unknown suite."},"422":{"description":"suite is required."},"500":{"description":"Suite or leaderboard source could not be read."}}}},"/build/lab/evidence":{"get":{"operationId":"getPublicLabIdeaEvidence","summary":"Read the same evidence panel as a public graded game-market Lab idea.","security":[],"parameters":[{"name":"idea","in":"query","required":true,"description":"URL-encoded corpus idea id returned by the public Lab. Do not substitute a player or model name.","schema":{"type":"string"}}],"responses":{"200":{"description":"LabIdeaEvidence: ready seasonHeat, clvRows and probability, or an explicit unavailable reason. No model execution."},"400":{"description":"Not a graded game-market idea id."}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","description":"Bearer API keys use two namespaces. Personal Picks keys are `ss_live_` plus 32 random bytes encoded as base64url (43 characters) and are minted at /account/api-keys; they authorize only GET /api/v1/picks. Legacy scoped keys are `ssk_live_<32hex>` (16 random bytes encoded as 32 lowercase hexadecimal characters) and are minted at /settings/api-keys. Legacy model reads, GET /api/v1/record, and GET /api/v1/props accept any valid legacy key; POST /api/v1/models requires the `models:write` scope; GET /api/v1/picks also accepts a legacy key with the `picks` scope. The full key is shown once at creation and is not recoverable later."}},"schemas":{"PublicApiSource":{"type":"object","required":["name","url","citation","terms"],"description":"Attribution block. Quote `citation` and link the page url beside it.","properties":{"name":{"type":"string"},"url":{"type":"string"},"citation":{"type":"string"},"terms":{"type":"string"}}},"PublicApiGame":{"type":"object","required":["id","kickoff","home","away"],"properties":{"id":{"type":"string"},"kickoff":{"type":"string","format":"date-time"},"home":{"type":["string","null"],"description":"Null for sports with no first-party schedule here; never a placeholder."},"away":{"type":["string","null"]}}},"PublicApiPick":{"type":"object","required":["id","game","market","side","line","price","model","url"],"properties":{"id":{"type":"string"},"game":{"$ref":"#/components/schemas/PublicApiGame"},"market":{"type":"string","enum":["spread","moneyline","total"]},"side":{"type":"string"},"line":{"type":["number","null"],"description":"The selected side's own line: for a spread, that side's handicap (negative = that side favoured); for a total, the total; null for a moneyline."},"price":{"type":["integer","null"],"description":"American odds."},"model":{"type":"object","required":["id","name"],"properties":{"id":{"type":"string"},"name":{"type":["string","null"]}}},"url":{"type":"string","description":"The live sharksnip.com page for this pick."}}},"PublicPicksBoard":{"type":"object","required":["source","sport","season","week","asOf","page","picks"],"properties":{"source":{"$ref":"#/components/schemas/PublicApiSource"},"sport":{"type":"string"},"season":{"type":["integer","null"]},"week":{"type":["integer","null"]},"asOf":{"type":["string","null"],"format":"date-time","description":"Newest publication time among the served picks; null when none carries one."},"page":{"type":"object","required":["url"],"properties":{"url":{"type":"string"}}},"picks":{"type":"array","items":{"$ref":"#/components/schemas/PublicApiPick"}}}},"PublicApiUnavailable":{"type":"object","required":["state","reason"],"properties":{"state":{"type":"string","enum":["unavailable"]},"reason":{"type":"string","enum":["picks-unavailable","schedule-unavailable"]}}},"PublicPageRequest":{"type":"object","properties":{"sport":{"type":"string","enum":["nfl","nba","mlb","nhl"]},"week":{"type":"integer","minimum":1,"maximum":30},"agent":{"type":"string","pattern":"^[a-z0-9-]{1,40}$"}}},"PublicPageLink":{"type":"object","required":["url","expires","note"],"properties":{"url":{"type":"string"},"expires":{"type":"null","description":"Always null: nothing is stored, so nothing can expire."},"note":{"type":"string"}}},"CreateModelRequest":{"type":"object","required":["name","slots"],"properties":{"name":{"type":"string","minLength":1,"maxLength":80},"sport":{"type":"string","enum":["nfl","nba","mlb","nhl"],"default":"nfl"},"slots":{"type":"object","description":"Builder Blueprint slot recipe: {data: SlotRef[], features: SlotRef[], target, slice, architecture, staking, ensemble}, SlotRef = {id, version}. Validated by the same validator the /build canvas uses."}},"additionalProperties":false},"CreateModelResponse":{"type":"object","required":["id","url","status"],"properties":{"id":{"type":"string"},"url":{"type":"string"},"status":{"type":"string","enum":["draft"]}}},"PublicPick":{"type":"object","required":["id","gameId","modelId","modelName","sport","market","selection","line","homeMarginLine","americanOdds","probability","predictedValue","confidence","kickoffAt"],"properties":{"id":{"type":"string"},"gameId":{"type":"string"},"modelId":{"type":"string"},"modelName":{"type":["string","null"]},"sport":{"type":"string"},"market":{"type":"string"},"selection":{"type":"string"},"line":{"type":["number","null"],"description":"The selected side's own line: for a spread, that side's handicap (negative = that side favoured); for a total, the total; null for a moneyline."},"homeMarginLine":{"type":["number","null"],"description":"The same market line in the frame of predictedValue: for a spread, home-anchored (positive = home favoured, as predictedValue is the predicted home margin); for a total, the total; null for a moneyline. Compare predictedValue only with homeMarginLine."},"americanOdds":{"type":["integer","null"]},"probability":{"type":["number","null"]},"predictedValue":{"type":["number","null"],"description":"The model value; for a spread, the predicted home margin."},"confidence":{"type":["number","null"]},"kickoffAt":{"type":"string","format":"date-time"}}},"PublicPicksResponse":{"type":"object","required":["picks"],"properties":{"picks":{"type":"array","items":{"$ref":"#/components/schemas/PublicPick"}}}},"Period":{"type":"object","additionalProperties":false,"properties":{"season":{"type":"integer"},"week":{"type":"integer"}},"required":["season","week"]},"Team":{"type":"object","additionalProperties":false,"properties":{"code":{"type":"string"},"wireKey":{"type":"string"},"name":{"type":"string"},"path":{"type":"string"}},"required":["code","wireKey","name","path"]},"Player":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"gsisId":{"type":"string"},"name":{"type":"string"},"slug":{"type":"string"},"path":{"type":"string"},"position":{"enum":["QB","RB","FB","WR","TE","K"]},"team":{"anyOf":[{"$ref":"#/components/schemas/Team"},{"type":"null"}]},"rosterStatus":{"type":"string"},"rosterSeason":{"type":["integer","null"]},"rosterWeek":{"type":["integer","null"]},"observedAt":{"type":["string","null"],"format":"date-time"}},"required":["id","gsisId","name","slug","path","position","team","rosterStatus","rosterSeason","rosterWeek","observedAt"]},"Coverage":{"type":"object","additionalProperties":false,"properties":{"sourceRows":{"type":"integer","minimum":0},"eligiblePlayers":{"type":"integer","minimum":0},"teams":{"type":"integer","minimum":0},"invalidRows":{"type":"integer","minimum":0},"conflictedPlayers":{"type":"integer","minimum":0},"unrecognizedTeams":{"type":"integer","minimum":0},"missingObservationTimes":{"type":"integer","minimum":0}},"required":["sourceRows","eligiblePlayers","teams","invalidRows","conflictedPlayers","unrecognizedTeams","missingObservationTimes"]},"Projection":{"type":"object","additionalProperties":false,"properties":{"points":{"type":"number"},"scoring":{"const":"ppr"},"kind":{"enum":["house","espn-fallback"]},"source":{"enum":["house","espn"]},"season":{"type":"integer"},"week":{"type":"integer"},"positionRank":{"type":["integer","null"]},"positionTotal":{"type":"integer"}},"required":["points","scoring","kind","source","season","week","positionRank","positionTotal"]},"GameStats":{"type":"object","additionalProperties":false,"properties":{"season":{"type":"integer"},"week":{"type":"integer"},"gameId":{"type":["string","null"]},"opponent":{"type":["string","null"]},"pprPoints":{"type":["number","null"]},"passingYards":{"type":["number","null"]},"rushingYards":{"type":["number","null"]},"receivingYards":{"type":["number","null"]},"targets":{"type":["number","null"]},"receptions":{"type":["number","null"]},"carries":{"type":["number","null"]}},"required":["season","week","gameId","opponent","pprPoints","passingYards","rushingYards","receivingYards","targets","receptions","carries"]},"Injury":{"type":"object","additionalProperties":false,"properties":{"reportStatus":{"type":["string","null"]},"practiceStatus":{"type":["string","null"]},"injury":{"type":["string","null"]},"sourceUrl":{"type":["string","null"]}},"required":["reportStatus","practiceStatus","injury","sourceUrl"]},"Buzz":{"type":"object","additionalProperties":false,"properties":{"mentions":{"type":["integer","null"]},"velocity":{"type":["number","null"]},"quotes":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"text":{"type":"string"},"source":{"type":"string"},"title":{"type":"string"},"url":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"}},"required":["text","source","title","url","publishedAt"]}},"news":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"headline":{"type":"string"},"url":{"type":"string"},"publishedAt":{"type":"string","format":"date-time"}},"required":["headline","url","publishedAt"]}}},"required":["mentions","velocity","quotes","news"]},"TeamGame":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"season":{"type":"integer"},"week":{"type":"integer"},"date":{"type":"string","format":"date"},"opponent":{"anyOf":[{"$ref":"#/components/schemas/Team"},{"type":"null"}]},"home":{"type":"boolean"},"venue":{"type":["string","null"]},"final":{"type":"boolean"},"pointsFor":{"type":["number","null"]},"pointsAgainst":{"type":["number","null"]},"spread":{"type":["number","null"]},"total":{"type":["number","null"]},"moneyline":{"type":["number","null"]},"oddsAsOf":{"type":["string","null"],"format":"date-time"},"oddsState":{"enum":["ready","stale","unavailable"]}},"required":["id","season","week","date","opponent","home","venue","final","pointsFor","pointsAgainst","spread","total","moneyline","oddsAsOf","oddsState"]},"PlayerHub":{"type":"object","additionalProperties":false,"properties":{"schemaVersion":{"const":1},"player":{"$ref":"#/components/schemas/Player"},"period":{"anyOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}]},"roster":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"projection":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Projection"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"projectionLabel":{"type":"string"},"history":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/GameStats"}},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"injury":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Injury"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"buzz":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Buzz"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"indexable":{"type":"boolean"}},"required":["schemaVersion","player","period","roster","projection","projectionLabel","history","injury","buzz","indexable"]},"TeamHub":{"type":"object","additionalProperties":false,"properties":{"schemaVersion":{"const":1},"team":{"$ref":"#/components/schemas/Team"},"season":{"type":["integer","null"]},"roster":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"type":"object","additionalProperties":false,"properties":{"period":{"$ref":"#/components/schemas/Period"},"coverage":{"$ref":"#/components/schemas/Coverage"}},"required":["period","coverage"]},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"players":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"player":{"$ref":"#/components/schemas/Player"},"projection":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Projection"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]}},"required":["player","projection"]}},"games":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/TeamGame"}},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"buzz":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Buzz"},{"type":"null"}]},"asOf":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]}},"required":["schemaVersion","team","season","roster","players","games","buzz"]},"PlayerResponse":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"sport":{"const":"nfl"},"partial":{"type":"boolean"},"hub":{"$ref":"#/components/schemas/PlayerHub"},"links":{"type":"object","additionalProperties":false,"properties":{"canonical":{"type":"string"},"documentation":{"type":"string"}},"required":["canonical","documentation"]}},"required":["schema_version","sport","partial","hub","links"]},"TeamResponse":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"sport":{"const":"nfl"},"partial":{"type":"boolean"},"hub":{"$ref":"#/components/schemas/TeamHub"},"links":{"type":"object","additionalProperties":false,"properties":{"canonical":{"type":"string"},"documentation":{"type":"string"}},"required":["canonical","documentation"]}},"required":["schema_version","sport","partial","hub","links"]},"DirectoryResponse":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"sport":{"const":"nfl"},"period":{"$ref":"#/components/schemas/Period"},"state":{"enum":["ready","stale","empty","unavailable"]},"as_of":{"type":["string","null"],"format":"date-time"},"reason":{"type":["string","null"]},"coverage":{"$ref":"#/components/schemas/Coverage"},"total":{"type":"integer"},"players":{"type":"array","items":{"$ref":"#/components/schemas/Player"}},"next_cursor":{"type":["string","null"]},"links":{"type":"object","additionalProperties":false,"properties":{"directory":{"type":"string"},"documentation":{"type":"string"}},"required":["directory","documentation"]}},"required":["schema_version","sport","period","state","as_of","reason","coverage","total","players","next_cursor","links"]},"TeamsResponse":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"sport":{"const":"nfl"},"teams":{"type":"array","items":{"$ref":"#/components/schemas/Team"}},"documentation":{"type":"string"}},"required":["schema_version","sport","teams","documentation"]},"Error":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"error":{"type":"object","additionalProperties":false,"properties":{"reason":{"type":"string"}},"required":["reason"]},"documentation":{"type":"string"}},"required":["schema_version","error","documentation"]},"ResearchIdentity":{"type":"object","additionalProperties":false,"properties":{"kind":{"enum":["team","player"]},"id":{"type":"string"},"name":{"type":"string"},"path":{"type":"string"}},"required":["kind","id","name","path"]},"ResearchMatchup":{"type":"object","additionalProperties":false,"properties":{"gameId":{"type":"string"},"period":{"$ref":"#/components/schemas/Period"},"opponent":{"$ref":"#/components/schemas/Team"},"home":{"type":"boolean"},"kickoffAt":{"type":"string"},"kickoffSource":{"type":"string"},"phase":{"enum":["scheduled","kickoff-reached"]}},"required":["gameId","period","opponent","home","kickoffAt","kickoffSource","phase"]},"ResearchDepth":{"type":"object","additionalProperties":false,"properties":{"playerId":{"type":"string"},"name":{"type":"string"},"formation":{"type":"string"},"position":{"type":"string"},"depthSlot":{"type":"string"},"observedAt":{"type":["string","null"]},"sourceUrl":{"type":["string","null"]}},"required":["playerId","name","formation","position","depthSlot","observedAt","sourceUrl"]},"ResearchDepthSnapshot":{"type":"object","additionalProperties":false,"properties":{"rows":{"type":"array","items":{"$ref":"#/components/schemas/ResearchDepth"}},"coverage":{"type":"object","additionalProperties":false,"properties":{"sourceRows":{"type":"integer"},"fantasyRows":{"type":"integer"},"quarantinedRows":{"type":"integer"},"conflictedGroups":{"type":"integer"}},"required":["sourceRows","fantasyRows","quarantinedRows","conflictedGroups"]}},"required":["rows","coverage"]},"ResearchAvailability":{"type":"object","additionalProperties":false,"properties":{"playerId":{"type":"string"},"name":{"type":"string"},"position":{"type":["string","null"]},"reportStatus":{"type":["string","null"]},"practiceStatus":{"type":["string","null"]},"injury":{"type":["string","null"]},"observedAt":{"type":["string","null"]},"sourceUrl":{"type":["string","null"]},"path":{"type":["string","null"]}},"required":["playerId","name","position","reportStatus","practiceStatus","injury","observedAt","sourceUrl","path"]},"ResearchPeer":{"type":"object","additionalProperties":false,"properties":{"player":{"$ref":"#/components/schemas/Player"},"projection":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/Projection"},{"type":"null"}]},"asOf":{"type":["string","null"]},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]}},"required":["player","projection"]},"UsageWindow":{"type":"object","additionalProperties":false,"properties":{"season":{"type":"integer"},"weeks":{"type":"array","items":{"type":"integer"}},"observations":{"type":"integer"},"value":{"type":["number","null"]}},"required":["season","weeks","observations","value"]},"UsageMetric":{"type":"object","additionalProperties":false,"properties":{"key":{"enum":["targets","carries","receptions","passingYards","rushingYards","receivingYards","pprPoints"]},"label":{"type":"string"},"unit":{"type":"string"},"recent":{"$ref":"#/components/schemas/UsageWindow"},"previous":{"$ref":"#/components/schemas/UsageWindow"},"difference":{"type":["number","null"]},"series":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"season":{"type":"integer"},"week":{"type":"integer"},"value":{"type":["number","null"]}},"required":["season","week","value"]}}},"required":["key","label","unit","recent","previous","difference","series"]},"WeeklyFact":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"text":{"type":"string"},"category":{"enum":["matchup","projection","usage","availability","depth","discussion"]},"sourceLabel":{"type":"string"},"sourcePath":{"type":"string"},"asOf":{"type":["string","null"]},"state":{"enum":["ready","stale","historical"]}},"required":["id","text","category","sourceLabel","sourcePath","asOf","state"]},"WeeklyWatch":{"type":"object","additionalProperties":false,"properties":{"id":{"type":"string"},"text":{"type":"string"},"sourcePath":{"type":"string"}},"required":["id","text","sourcePath"]},"WeeklyPacket":{"type":"object","additionalProperties":false,"properties":{"schemaVersion":{"const":1},"entity":{"$ref":"#/components/schemas/ResearchIdentity"},"period":{"anyOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}]},"evidenceVersion":{"type":"string","pattern":"^[a-f0-9]{64}$"},"sourceAsOf":{"type":["string","null"]},"preparedAt":{"type":"string"},"validUntil":{"type":"string"},"facts":{"type":"array","items":{"$ref":"#/components/schemas/WeeklyFact"}},"requiredFactIds":{"type":"array","items":{"type":"string"}},"watch":{"type":"array","items":{"$ref":"#/components/schemas/WeeklyWatch"}},"editorialEligible":{"type":"boolean"}},"required":["schemaVersion","entity","period","evidenceVersion","sourceAsOf","preparedAt","validUntil","facts","requiredFactIds","watch","editorialEligible"]},"WeeklyBrief":{"type":"object","additionalProperties":false,"properties":{"mode":{"enum":["automatic","gptwork-curated"]},"state":{"enum":["current","needs-refresh"]},"reason":{"type":["string","null"]},"period":{"anyOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}]},"updatedAt":{"type":["string","null"]},"expiresAt":{"type":"string"},"paragraphs":{"type":"array","items":{"type":"object","additionalProperties":false,"properties":{"text":{"type":"string"},"facts":{"type":"array","items":{"$ref":"#/components/schemas/WeeklyFact"}}},"required":["text","facts"]}},"watch":{"type":"array","items":{"$ref":"#/components/schemas/WeeklyWatch"}}},"required":["mode","state","reason","period","updatedAt","expiresAt","paragraphs","watch"]},"WeeklySelection":{"type":"object","additionalProperties":false,"properties":{"schemaVersion":{"const":1},"entityId":{"type":"string"},"evidenceVersion":{"type":"string"},"period":{"$ref":"#/components/schemas/Period"},"paragraphs":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"array","minItems":1,"maxItems":3,"items":{"type":"string"}}},"watchIds":{"type":"array","minItems":1,"maxItems":3,"uniqueItems":true,"items":{"type":"string"}}},"required":["schemaVersion","entityId","evidenceVersion","period","paragraphs","watchIds"]},"EntityResearch":{"type":"object","additionalProperties":false,"properties":{"schemaVersion":{"const":1},"entity":{"$ref":"#/components/schemas/ResearchIdentity"},"period":{"anyOf":[{"$ref":"#/components/schemas/Period"},{"type":"null"}]},"evaluatedAt":{"type":"string"},"matchup":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/ResearchMatchup"},{"type":"null"}]},"asOf":{"type":["string","null"]},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"depth":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"$ref":"#/components/schemas/ResearchDepthSnapshot"},{"type":"null"}]},"asOf":{"type":["string","null"]},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"availability":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ResearchAvailability"}},{"type":"null"}]},"asOf":{"type":["string","null"]},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"peers":{"type":"object","additionalProperties":false,"properties":{"state":{"enum":["ready","stale","empty","unavailable"]},"value":{"anyOf":[{"type":"array","items":{"$ref":"#/components/schemas/ResearchPeer"}},{"type":"null"}]},"asOf":{"type":["string","null"]},"reason":{"type":["string","null"]}},"required":["state","value","asOf","reason"]},"usage":{"type":"array","items":{"$ref":"#/components/schemas/UsageMetric"}},"weekly":{"type":"object","additionalProperties":false,"properties":{"packet":{"$ref":"#/components/schemas/WeeklyPacket"},"brief":{"$ref":"#/components/schemas/WeeklyBrief"},"publicationState":{"enum":["ready","empty","unavailable"]}},"required":["packet","brief","publicationState"]}},"required":["schemaVersion","entity","period","evaluatedAt","matchup","depth","availability","peers","usage","weekly"]},"ResearchResponse":{"type":"object","additionalProperties":false,"properties":{"schema_version":{"const":1},"research":{"$ref":"#/components/schemas/EntityResearch"},"documentation":{"type":"string"}},"required":["schema_version","research","documentation"]}}},"x-sharksnip-discovery":{"documents":[{"path":"/api/v1/openapi.json","label":"API OpenAPI","description":"Master API contract, public reads, authentication and intent recipes."},{"path":"/api/v1/entities/openapi.json","label":"Entities API","description":"NFL player search, roster, team and schedule reads."},{"path":"/api/v1/entities/research/openapi.json","label":"Research API","description":"Public source-backed player and team evidence packets."}],"intents":[{"intent":"Week 7 NFL picks","url":"/api/v1/public/picks?sport=nfl&week=7","note":"Published picks under the anonymous page visibility rules. Check source state and cite each returned page URL."},{"intent":"Prop lines for Bijan Robinson","url":"/api/v1/public/props?sport=nfl&q=Bijan%20Robinson","note":"The same bounded player page and visible forecasts as the anonymous props board. Use page and marketPage for pagination."},{"intent":"Find a player by name","url":"/api/v1/entities/nfl/players?q=Bijan%20Robinson","note":"Directory name search returns canonical ids and page paths. It can return several players; never guess between them."},{"intent":"Evidence packet by player name","url":"/api/v1/entities/nfl/players/Bijan%20Robinson/research","note":"An exact normalized name must identify one rostered player. An ambiguous name returns 409. GSIS ids, canonical slugs and props name@kickoff-minute references are also accepted; studio: references identify models, not players."},{"intent":"Find a matchup by team name","url":"/api/v1/entities/nfl/teams/pittsburgh-steelers","note":"The team hub includes schedule opponents, dates and game ids. Choose the matching opponent/date, then GET /api/v1/lines?game=<returned game id>; do not invent an opaque id."},{"intent":"Sportsbook odds","url":"/api/v1/lines","note":"Public pick-aware book prices, with capture times and explicit missing/stale states. Optional game and market filters."},{"intent":"DFS projections","url":"/api/dfs/projections?sport=nfl","note":"The existing DFS page endpoint applies the caller’s existing visibility rules. It does not grant paid access."},{"intent":"Public models","url":"/api/registry/models?sport=nfl&limit=60","note":"Existing public live model cards; this catalog is not a ranking."},{"intent":"Model leaderboard","url":"/api/benchmarks/suites?sport=nfl","note":"First read the available suite slugs, then GET /api/benchmarks/leaderboard?suite=<returned slug>. Suite order and rank are supplied by the existing benchmark owner, not recomputed here."},{"intent":"Lab model evidence","url":"/build/lab","note":"Read a public graded game-market idea id from the Lab, then GET /build/lab/evidence?idea=<URL-encoded returned idea id>. Use only public ideas; this endpoint does not execute a model."}]}}