diff --git a/content/en/api-reference/common-4xx-errors.mdx b/content/en/api-reference/common-4xx-errors.mdx index d037afd..df92528 100644 --- a/content/en/api-reference/common-4xx-errors.mdx +++ b/content/en/api-reference/common-4xx-errors.mdx @@ -1,12 +1,12 @@ --- -description: "The four most common 4xx/410 mistakes against the SharpAPI REST API — offset over the pagination cap, pre-namespace opportunity paths, streaming on the API root, and unknown filter slugs — with the exact fix for each." +description: "The most common 4xx/410 mistakes against the SharpAPI REST API — offset over the pagination cap, market= vs market_type= confusion, market-segment slug passed as league, pre-namespace opportunity paths, streaming on the API root, and unknown filter slugs — with the exact fix for each." --- import { Callout } from 'nextra/components' # Common 4xx Mistakes -Four client-side usage mistakes account for most of the recurring 4xx/410 responses SharpAPI returns. Each error body already names the fix — this page collects them in one place so you can map a status code to the correction without opening a support ticket. +Six client-side usage mistakes account for most of the recurring 4xx/410 responses SharpAPI returns. Each error body already names the fix — this page collects them in one place so you can map a status code to the correction without opening a support ticket. These are **client-side** errors, not outages. The general error envelope (fields, status-code meanings, the full code list) lives in [Response Conventions](/en/api-reference/conventions/). Always branch on `error.code`, not the prose `message`. @@ -33,6 +33,38 @@ Deep pagination with `offset` is capped at **500** on [`/api/v1/odds`](/en/api-r On `/odds/delta`, advance `since=` to the previous response's `updated_at` instead of increasing `offset`. +## `market=` vs `market_type=` confusion → `400 invalid_filter` + +The response field that names the market is called `market_type` (e.g. `"market_type": "moneyline"`). The **query parameter** is `market=` — the two names differ by design, because the filter also accepts category aliases that expand to multiple types. Sending `?market_type=moneyline` works (it is accepted as an alias for `market=`), but the common mistake is passing the full exact-type name when a category alias was intended, or vice versa. + +| What you want | Correct param | +|---|---| +| All moneylines | `?market=moneyline` | +| All spreads (point spread, puck line, run line, set handicap) | `?market=spread` | +| All totals | `?market=total` | +| All player props | `?market=props` | +| Exact type from response | `?market=` (e.g. `market=point_spread`) | + +`market=` and `market_type=` are interchangeable on the query string — both reach the same filter. Category aliases (`main`, `spread`, `total`, `props`) expand to a group of types; everything else is treated as an exact type match and validated against the market registry. A value that matches neither an alias nor a registry slug returns `400 invalid_filter` with a `did_you_mean` hint. + +## League slug passed as `league=` when it is a market segment → `400 invalid_filter` + +League slugs (e.g. `nfl`, `nba`, `mlb`) and market-segment slugs (e.g. `nfl_1st_quarter_spreads`, `nba_player_points`) look similar but belong to different filter parameters. Passing a market-segment slug as a league value returns `400 invalid_filter` because it is not a valid league: + +```json +{ + "error": { + "code": "invalid_filter", + "message": "invalid filter values: league=[nfl_1st_quarter_spreads]; see GET /api/v1/leagues for valid values", + "details": { + "fields": { "league": ["nfl_1st_quarter_spreads"] } + } + } +} +``` + +**Fix:** use `market_segment=nfl_1st_quarter_spreads` (or `market=`) for market filtering, and `league=nfl` for league filtering. Fetch valid league slugs from [`GET /api/v1/leagues`](/en/api-reference/leagues/) and valid market-segment slugs from [`GET /api/v1/markets`](/en/api-reference/markets/). + ## Pre-namespace opportunity paths → `410 Gone` Every opportunity type lives under `/api/v1/opportunities/`. The bare shorthand paths (`/api/v1/ev`, `/api/v1/arbitrage`, `/api/v1/middles`, `/api/v1/low_hold`) return **410 Gone** and name their replacement: diff --git a/content/en/api-reference/odds.mdx b/content/en/api-reference/odds.mdx index 0941dad..057dec7 100644 --- a/content/en/api-reference/odds.mdx +++ b/content/en/api-reference/odds.mdx @@ -31,7 +31,7 @@ The sportsbooks returned in your results depend on your subscription tier. Free | `sportsbook` | string | tier-allowed | Comma-separated sportsbook IDs (e.g., `draftkings,fanduel`). Tier limits enforced. | | `sport` | string | all | Filter by sport(s), comma-separated (e.g., `basketball`, `football`). Supports category aliases. | | `league` | string | all | Filter by league(s), comma-separated (e.g., `nba`, `nfl`, `nhl`) | -| `market` | string | all | Filter by market type(s), comma-separated. Supports [category aliases](#market-category-aliases) (`main`, `spread`, `total`, `props`) or exact types (`point_spread`, `player_points`). Also accepted as `market_type=` (mirrors the response field name). | +| `market` | string | all | Filter by market type(s), comma-separated. Accepts [category aliases](#market-category-aliases) (`main`, `spread`, `total`, `props`) **or** exact type names as they appear in the `market_type` response field (e.g., `moneyline`, `point_spread`, `player_points`). Also accepted as `market_type=`. | | `event_id` | string | — | Filter by event ID(s), comma-separated | | `is_live` | boolean | — | `true` = live only, `false` = prematch only, omit = both | | `group_by` | string | — | Group results by field (e.g., `event`) | @@ -44,6 +44,14 @@ The sportsbooks returned in your results depend on your subscription tier. Free Use comma-separated values to filter by multiple sportsbooks: `sportsbook=draftkings,fanduel,betmgm` + +**`market=` vs `market_type` — don't confuse the filter name with the response field name.** The response object contains a field called `market_type` (e.g. `"market_type": "moneyline"`). The query parameter is `market=` — which also accepts `market_type=` as an alias. Both `?market=moneyline` and `?market_type=moneyline` work and are equivalent. Passing an unrecognized value returns `400 invalid_filter`. See [Common 4xx Mistakes](/en/api-reference/common-4xx-errors/) for the full error shape. + + + +**`league=` takes league slugs, not market-segment slugs.** League slugs look like `nfl`, `nba`, `mlb`. Market-segment slugs like `nfl_1st_quarter_spreads` belong on the `market_segment=` filter, not `league=`. Mixing them returns `400 invalid_filter`. Fetch valid league slugs from [`GET /api/v1/leagues`](/en/api-reference/leagues/). + + ### Market Category Aliases Instead of listing individual market types, you can use a category alias to match a group of related markets. Aliases and exact types can be mixed freely in a comma-separated list.