MLB API endpoint
Returns batter, batting-team, pitcher, pitching-team, or league bat-tracking rows with the live page's season, game type, swing threshold, date, side, contact, attack zone, team, pitch, count, and grouping filters. Use mlb_discovery for the same complete value sets. Multi-value filters are passed as repeated query parameters.
/mlb/statcast-bat-trackingQuery parameters:
type (optional): batter, batting-team, pitcher, pitching-team, or league. Defaults to batter.season_start, season_end (optional): ordered seasons from 2023, 2024, 2025, 2026. Defaults to 2026 and season_start respectively. The page's live selector currently exposes this four-season window; refresh the discovery values annually.game_type (optional): Any, Playoff, or Regular; defaults to Regular.min_swings (optional): q, 1, 5, 10, 25, 50, 100, 200, 500, or 1000; defaults to q (qualified).min_group_swings (optional): 1, 5, 10, 25, 50, 100, 200, 500, or 1000; defaults to 1.date_start, date_end (optional): independent date bounds in YYYY-MM-DD format; if both are supplied, start must not follow end.bat_side (optional): L or R.contact_type (optional): 2 (hit in play), 4 (foul), or 9 (whiff).is_hard_hit (optional): 1 or 0.attack_zone (optional): 0 (Heart), 1 (Shadow In), 1.1 (Shadow Out), 2 (Chase), or 3 (Waste).pitch_hand (optional): L or R.teams (optional, repeatable): one or more MLB team ids: 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 158.pitch_types (optional, repeatable): FF, SI, FC, CH, FS, FO, SC, CU, SL, ST, SV, or KN.counts (optional, repeatable): 00, 01, 02, 10, 11, 12, 20, 21, 22, 30, 31, or 32 (balls followed by strikes).group_by (optional, repeatable; up to four): year, api_game_date_month_text, bat_contact_code, api_pitch_type_group03, game_type, is_hit_into_play_hardhit, is_best_speed, pitch_hand, bat_side, is_pre_ball_count_3, or is_pre_strike_count_2.sort (optional): local row field: avg_batter_x_position, avg_batter_y_position, avg_intercept_x_vs_batter, avg_intercept_y_vs_batter, avg_foot_sep0, avg_foot_angle0, attack_direction_pullopp, rate_ideal_attack_angle, attack_angle, avg_plane_vertical_angle, avg_sweetspot_speed_mph, avg_sweetspot_speed_mph_qualified, avg_is_sweetspot_speed_high, avg_is_sweetspot_speed_high_qualified, squared_up, squared_up_qualified, squared_up_per_bat_contact, squared_up_per_swing, squared_up_with_speed, squared_up_with_speed_qualified, squared_up_with_speed_per_bat_contact, squared_up_with_speed_per_swing, swing_length_qualified, swords, swings_qualified, percent_qualified, hit_into_play_qualified, bat_contact, bat_contact_qualified, count, delta_run_exp, hit_into_play_per_swing, pitcher_delta_run_exp, strikes_swinging_qualified, sweetspot_speed_high_qualified, strike_swinging_per_swing, id, name, batter_name, b_name_display_first_last, savant_batter_id, team_id, team_name, side, n_sides, n_teams, or bat_side_formatted. Defaults to avg_sweetspot_speed_mph_qualified.sort_dir (optional): asc or desc; defaults to desc.limit (optional): 1–500; defaults to 100.offset (optional): 0–5000; defaults to 0.x-api-key (required): API key.Response behavior: The row type, season range, game type, swing thresholds, dates, and selected filters are sent using the first-party query names. Team, pitch type, count, and group-by multi-selects accept repeated API parameters and are encoded as the source page expects. Rows preserve the upstream field names and numeric precision; sorting and pagination are local. Valid filter combinations with no matching records return rows: []. Use /mlb/discovery for the matching live navigation and enum sets.
| Field | Filled in, of 40 checked | Values in the sample |
|---|---|---|
| attack_angle | 40 | 1.1 to 19.39, median 10.04 |
| attack_direction_pullopp | 40 | -16.05 to 6.14, median -2.76 |
| avg_batter_x_position | 40 | |
| avg_batter_y_position | 40 | |
| avg_foot_angle0 | 40 | -44.55 to 4.45, median -10.7 |
| avg_foot_sep0 | 40 | 18.11 to 39.95, median 28.71 |
| avg_intercept_x_vs_batter | 40 | |
| avg_intercept_y_vs_batter | 40 | |
| avg_is_sweetspot_speed_high | 40 | 0.41 to 0.78, median 0.54 |
| avg_is_sweetspot_speed_high_qualified | 40 | 0.46 to 0.85, median 0.59 |
| avg_plane_vertical_angle | 40 | 24.38 to 44.53, median 32.74 |
| avg_sweetspot_speed_mph | 40 | 72.48 to 77.83, median 74.02 |
| avg_sweetspot_speed_mph_qualified | 40 | 74.67 to 79.46, median 75.72 |
| b_name_display_first_last | 40 | “Caminero, Junior” and 39 other values |
| bat_contact | 40 | 456 to 1,035, median 773 |
| bat_contact_qualified | 40 | 421 to 996, median 713 |
| bat_side_formatted | 40 | L (19), R (18), S (3) |
| batter_name | 40 | “Caminero, Junior” and 39 other values |
| count | 40 | 718 to 1,413, median 1,095 |
| delta_run_exp | 40 | -42.89 to 22.61, median -11.06 |
| hit_into_play_per_swing | 40 | 0.27 to 0.48, median 0.35 |
| hit_into_play_qualified | 40 | 183 to 449, median 341 |
| id | 40 | |
| n_sides | 40 | 1 to 2, median 1 |
| n_teams | 40 | 1 to 2, median 1 |
| name | 40 | “Caminero, Junior” and 39 other values |
| percent_qualified | 40 | 0.9 to 0.91, median 0.91 |
| pitcher_delta_run_exp | 40 | -22.61 to 42.89, median 8.7 |
| rate_ideal_attack_angle | 40 | 0.31 to 0.73, median 0.49 |
| savant_batter_id | 40 | |
| side | 40 | R (21), L (19) |
| squared_up | 40 | 113 to 301, median 203 |
| squared_up_per_bat_contact | 40 | 0.23 to 0.36, median 0.29 |
| squared_up_per_swing | 40 | 0.15 to 0.28, median 0.21 |
| squared_up_qualified | 40 | 113 to 291, median 201 |
| squared_up_with_speed | 40 | 83 to 197, median 128 |
| squared_up_with_speed_per_bat_contact | 40 | 0.12 to 0.26, median 0.18 |
| squared_up_with_speed_per_swing | 40 | 0.08 to 0.19, median 0.13 |
| squared_up_with_speed_qualified | 40 | 83 to 197, median 128 |
| strike_swinging_per_swing | 40 | 0.18 to 0.4, median 0.27 |
| Parameter | Type | Required | Default | Description | Example |
|---|---|---|---|---|---|
| type | string | No | Table row type Allowed values: batter, batting-team, pitcher, pitching-team, league. | ||
| season_start | string | No | First season Allowed values: 2023, 2024, 2025, 2026. | ||
| season_end | string | No | Last season; must be >= season_start Allowed values: 2023, 2024, 2025, 2026. | ||
| game_type | string | No | Game type Allowed values: Any, Playoff, Regular. | ||
| min_swings | string | No | Minimum swing qualifier Allowed values: q, 1, 5, 10, 25, 50, 100, 200, 500, 1000. | ||
| min_group_swings | string | No | Minimum swings per grouped row Allowed values: 1, 5, 10, 25, 50, 100, 200, 500, 1000. | ||
| date_start | string | No | Optional date range start in YYYY-MM-DD | ||
| date_end | string | No | Optional date range end in YYYY-MM-DD | ||
| bat_side | string | No | Batter side Allowed values: L, R. | ||
| contact_type | string | No | Contact type Allowed values: 2, 4, 9. | ||
| is_hard_hit | string | No | Hard-hit filter Allowed values: 1, 0. | ||
| attack_zone | string | No | Attack zone Allowed values: 0, 1, 1.1, 2, 3. | ||
| pitch_hand | string | No | Pitcher hand Allowed values: L, R. | ||
| teams | array<string> | No | One or more MLB team ids Allowed values: 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 158. Repeat this query parameter for multiple values. | ||
| pitch_types | array<string> | No | One or more pitch types Allowed values: FF, SI, FC, CH, FS, FO, SC, CU, SL, ST, SV, KN. Repeat this query parameter for multiple values. | ||
| counts | array<string> | No | One or more ball-strike counts Allowed values: 00, 01, 02, 10, 11, 12, 20, 21, 22, 30, 31, 32. Repeat this query parameter for multiple values. | ||
| group_by | array<string> | No | Up to four grouping columns Allowed values: year, api_game_date_month_text, bat_contact_code, api_pitch_type_group03, game_type, is_hit_into_play_hardhit, is_best_speed, pitch_hand, bat_side, is_pre_ball_count_3, is_pre_strike_count_2. Repeat this query parameter for multiple values. | ||
| sort | string | No | Local row sort field Allowed values: avg_batter_x_position, avg_batter_y_position, avg_intercept_x_vs_batter, avg_intercept_y_vs_batter, avg_foot_sep0, avg_foot_angle0, attack_direction_pullopp, rate_ideal_attack_angle, attack_angle, avg_plane_vertical_angle, avg_sweetspot_speed_mph, avg_sweetspot_speed_mph_qualified, avg_is_sweetspot_speed_high, avg_is_sweetspot_speed_high_qualified, squared_up, squared_up_qualified, squared_up_per_bat_contact, squared_up_per_swing, squared_up_with_speed, squared_up_with_speed_qualified, squared_up_with_speed_per_bat_contact, squared_up_with_speed_per_swing, swing_length_qualified, swords, swings_qualified, percent_qualified, hit_into_play_qualified, bat_contact, bat_contact_qualified, count, delta_run_exp, hit_into_play_per_swing, pitcher_delta_run_exp, strikes_swinging_qualified, sweetspot_speed_high_qualified, strike_swinging_per_swing, id, name, batter_name, b_name_display_first_last, savant_batter_id, team_id, team_name, side, n_sides, n_teams, bat_side_formatted. | ||
| sort_dir | string | No | 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-bat-tracking?type=batter&season_start=2023&season_end=2023&game_type=Any&min_swings=q&min_group_swings=1&bat_side=L&contact_type=2&is_hard_hit=1&attack_zone=0&pitch_hand=L&teams=108&pitch_types=FF&counts=00&group_by=year&sort=avg_batter_x_position&sort_dir=asc&limit=10" \ -H "x-api-key: $CRAWLORA_API_KEY"
{
"code": 200,
"msg": "OK",
"data": {
"board": "bat_tracking",
"type": "batter",
"season_start": "2026",
"season_end": "2026",
"game_type": "Regular",
"min_swings": "q",
"min_group_swings": "1",
"total": 203,
"sort": "avg_sweetspot_speed_mph_qualified",
"sort_dir": "desc",
"offset": 0,
"limit": 100,
"rows": [
{
"id": 691406,
"name": "Caminero, Junior",
"team_id": 139,
"team_name": "Rays",
"avg_sweetspot_speed_mph_qualified": "79.448458618"
}
]
}
}Request schema
No body schema
Response schema
#/definitions/mlb.statcastBatTrackingResponseDoc
| Field | Type | Required | Enum | Bounds | Example | Description |
|---|---|---|---|---|---|---|
| board | string | No | ||||
| date_end | string | No | ||||
| date_start | string | No | ||||
| fetched_at | string | No | ||||
| game_type | string | No | ||||
| limit | integer | No | ||||
| min_group_swings | string | No | ||||
| min_swings | string | No | ||||
| offset | integer | No | ||||
| rows | array | No | ||||
| season_end | string | No | ||||
| season_start | string | No | ||||
| sort | string | No | ||||
| sort_dir | string | No | ||||
| source_url | string | No | ||||
| total | integer | No | ||||
| type | string | No |
| 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-bat-tracking?type=batter&season_start=2023&season_end=2023&game_type=Any&min_swings=q&min_group_swings=1&bat_side=L&contact_type=2&is_hard_hit=1&attack_zone=0&pitch_hand=L&teams=108&pitch_types=FF&counts=00&group_by=year&sort=avg_batter_x_position&sort_dir=asc&limit=10" \
-H "x-api-key: $CRAWLORA_API_KEY"