MLB API endpoint
Returns pitcher pitch speed, percentage, or spin rankings by pitch class. Year, minimum-pitch threshold, and hand are first-party filters. Team filtering and table sorting are applied locally because the page JavaScript applies them after receiving the embedded rows. Use mlb_discovery for exact values. CSV and pitch movement visualizations remain separate representations.
/mlb/statcast-pitch-arsenalsReturns Baseball Savant's Pitch Arsenals table: one row per pitcher, with values for each pitch class. This is a separate leaderboard from Pitch Arsenal Stats. Year, metric, throwing hand, and minimum-pitch threshold are sent to the first-party page. Team filtering and table sorting are applied locally because the page's JavaScript performs those operations after receiving the full rows.
year: 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024,
2025, 2026 in the live selector on 2026-09-30; defaults to 2026. The
selector moves forward with the current season and retains 19 seasons.type: avg_speed for average speed, n_ for pitch percentage, or
avg_spin for average spin; defaults to avg_speed. The first-party URL
accepts all three values. The page dropdown currently combines the
Average Speed and Percentage label and does not show n_ as a separate
option. Although its year-change handler hides avg_spin below 2015, a
direct anonymous request for year=2008&type=avg_spin returned 318 rows, so
the API preserves that source-supported combination. Discovery reports the
UI cutoff as 2015.hand: omit for all pitchers, R for right-handed pitchers, or L for
left-handed pitchers.min_pitches: q, 100, 250, 500, 750, 1000, 1500, 2000,
2500, or 3000; defaults to q (Qualified).team: optional local filter. The exact current codes present in all 30 live
2026 rows are ATH, ATL, AZ, BAL, BOS, CHC, CIN, CLE, COL,
CWS, DET, HOU, KC, LAA, LAD, MIA, MIL, MIN, NYM, NYY,
PHI, PIT, SD, SEA, SF, STL, TB, TEX, TOR, and WSH.
OAK is not accepted for the current Athletics abbreviation; use ATH.sort: player_name, four_seam, sinker, cutter, slider, changeup,
curve, splitter, sweeper, or slurve; defaults to four_seam.sort_dir: asc or desc; defaults to desc.limit: 1–500; defaults to 100.offset: 0–5000; defaults to 0.The table columns are Player, 4-Seamer, Sinker, Cutter, Slider, Changeup,
Curve, Splitter, Sweeper, and Slurve. Sort fields select the named pitch class
and use the active type metric. Responses replace the upstream HTML player
anchor with player_id and player_url. The page's sort column index and
sortDir are presentation state, mapped here to named sort fields. The
csv=true download and pitch-movement visualization are not JSON response
modes on this endpoint.
GET /api/v1/mlb/statcast-pitch-arsenals?year=2026&type=avg_speed&min_pitches=q&team=ATH&sort=four_seam&sort_dir=desc&limit=2
| Field | Filled in, of 40 checked | Values in the sample |
|---|---|---|
| breaking_avg_break | 40 | 2.6 to 18.3, median 8 |
| breaking_avg_break_x | 40 | |
| breaking_avg_break_z | 40 | -50.7 to -30.7, median -37.8 |
| breaking_avg_break_z_induced | 40 | -9.7 to 13.6, median -1.4 |
| breaking_avg_speed | 40 | 73.5 to 90.2, median 87.2 |
| breaking_avg_spin | 40 | 2,050 to 2,926, median 2,516 |
| breaking_calc_axis1 | 40 | 40 to 301, median 102 |
| breaking_calc_axis2 | 40 | -105 to 139, median 60 |
| breaking_range_break | 40 | 1.8 to 5.7, median 3.1 |
| breaking_range_break_x | 40 | |
| breaking_range_break_z | 40 | 3.1 to 18.7, median 5.7 |
| breaking_range_break_z_induced | 40 | 2.8 to 11.8, median 4.8 |
| breaking_range_speed | 40 | 1 to 5.4, median 1.8 |
| breaking_rel_x | 40 | |
| breaking_rel_y | 40 | |
| breaking_rel_z | 40 | 1.3 to 6.56, median 5.78 |
| ch_avg_break | 26 | 10.4 to 19.4, median 15.6 |
| ch_avg_break_x | 26 | |
| ch_avg_break_z | 26 | -39.2 to -23.4, median -29.8 |
| ch_avg_break_z_induced | 26 | -2.1 to 10.3, median 2.8 |
| ch_avg_speed | 26 | 83 to 96.6, median 90.3 |
| ch_avg_spin | 26 | 939 to 2,348, median 1,831 |
| ch_calc_axis1 | 26 | 84 to 278, median 244 |
| ch_calc_axis2 | 26 | -130 to 138, median -99 |
| ch_range_break | 26 | 2 to 3.8, median 2.8 |
| ch_range_break_x | 26 | |
| ch_range_break_z | 26 | 3.6 to 6.2, median 4.6 |
| ch_range_break_z_induced | 26 | 3.4 to 6.1, median 4.5 |
| ch_range_speed | 26 | 1 to 2.1, median 1.5 |
| ch_rel_x | 26 | |
| ch_rel_y | 26 | |
| ch_rel_z | 26 | 5.1 to 6.39, median 5.68 |
| changeup6_avg_break | 31 | 8 to 19.4, median 15.3 |
| changeup6_avg_break_x | 31 | |
| changeup6_avg_break_z | 31 | -39.2 to -23.4, median -29.8 |
| changeup6_avg_break_z_induced | 31 | -2.1 to 10.3, median 2.8 |
| changeup6_avg_speed | 31 | 83 to 96.8, median 90.3 |
| changeup6_avg_spin | 31 | 916 to 2,348, median 1,801 |
| changeup6_calc_axis1 | 31 | 84 to 278, median 250 |
| changeup6_calc_axis2 | 31 | -130 to 138, median -99 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| year | string | No | Season Allowed values: 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015, 2016, 2017, 2018, 2019, 2020, 2021, 2022, 2023, 2024, 2025, 2026. | ||
| type | string | No | Metric Allowed values: avg_speed, n_, avg_spin. | ||
| hand | string | No | Throwing hand; omit for all pitchers Allowed values: R, L. | ||
| min_pitches | string | No | Minimum pitches Allowed values: q, 100, 250, 500, 750, 1000, 1500, 2000, 2500, 3000. | ||
| team | string | No | Current MLB team abbreviation; applied locally Allowed values: ATH, ATL, AZ, BAL, BOS, CHC, CIN, CLE, COL, CWS, DET, HOU, KC, LAA, LAD, MIA, MIL, MIN, NYM, NYY, PHI, PIT, SD, SEA, SF, STL, TB, TEX, TOR, WSH. | ||
| sort | string | No | Local sort column Allowed values: player_name, four_seam, sinker, cutter, slider, changeup, curve, splitter, sweeper, slurve. | ||
| sort_dir | string | No | Local sort direction Allowed values: asc, desc. | ||
| limit | integer | No | Rows per page (1-500) Minimum: 1. Maximum: 500. | ||
| offset | integer | No | Zero-based row offset Minimum: 0. Maximum: 5000. | ||
| x-api-key (header) | string | Yes | API key required |
curl -X GET "https://api.crawlora.net/api/v1/mlb/statcast-pitch-arsenals?year=2008&type=avg_speed&hand=R&min_pitches=q&team=ATH&sort=player_name&sort_dir=asc&limit=10" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"board": "pitch-arsenals",
"year": "2026",
"type": "avg_speed",
"min_pitches": "q",
"team": "ATH",
"sort": "four_seam",
"sort_dir": "desc",
"total": 11,
"offset": 0,
"limit": 2,
"rows": [
{
"name_display_last_first": "Miller, Mason",
"player_id": "695243",
"player_url": "https://baseballsavant.mlb.com/savant-player/695243",
"name_abbrev": "ATH",
"ff_avg_speed": "101.4"
}
]
}
}Request schema
No body schema
Response schema
#/definitions/mlb.statcastPitchArsenalsResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| board | string | No | pitch-arsenals | |||
| hand | string | No | R | |||
| min_pitches | string | No | q | |||
| rows | array | No | ||||
| total | integer | No | 231 | |||
| type | string | No | avg_speed | |||
| year | string | No | 2026 |
| Status | Description | Schema |
|---|---|---|
| 400 | Bad Request | #/definitions/app.Response |
| 404 | Not Found | #/definitions/app.Response |
| 503 | Service Unavailable | #/definitions/app.Response |
Use environment variables for secrets and keep Crawlora API keys server-side.
curl -X GET "https://api.crawlora.net/api/v1/mlb/statcast-pitch-arsenals?year=2008&type=avg_speed&hand=R&min_pitches=q&team=ATH&sort=player_name&sort_dir=asc&limit=10" \
-H "x-api-key: $CRAWLORA_API_KEY"