Ball Action Filter
V3: Use Event Property Filter
For analyses with data version 3+, the Event Property filter provides more powerful querying with access to all event metadata (set piece, pass type, body part, length, etc.). The ball_action filter remains available as a simpler interface for basic pass/drive/shot filtering.
Filter intervals by ball action events: passes, drives (dribbles), and shots.
Requires Analysis Version 0.5.10+
This filter requires analysis version 0.5.10 or later. Earlier analysis versions do not include ball action event data.
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
type |
string | Yes | Must be "ball_action" |
actions |
array | No | Action types: "pass", "drive", "shot". If omitted, returns all action types. |
players |
array | No | Player IDs (e.g., ["0-5", "1-13"]) |
teams |
array | No | Teams: "team_0", "team_1" |
Player ID Format
Player IDs use the format {team}-{jersey}:
0-5= Team 0, jersey number 51-13= Team 1, jersey number 13
Basic Examples
All ball actions in the match
{
"filters": [
{ "type": "ball_action" }
]
}
Returns all passes, drives, and shots.
All passes in the match
{
"filters": [
{ "type": "ball_action", "actions": ["pass"] }
]
}
All shots
{
"filters": [
{ "type": "ball_action", "actions": ["shot"] }
]
}
All drives (dribbles)
{
"filters": [
{ "type": "ball_action", "actions": ["drive"] }
]
}
Filtering by Player
Shots by a specific player
{
"filters": [
{ "type": "ball_action", "actions": ["shot"], "players": ["0-5"] }
]
}
Drives by multiple players
{
"filters": [
{
"type": "ball_action",
"actions": ["drive"],
"players": ["1-2", "1-3"]
}
]
}
All actions by a player (highlight reel)
{
"filters": [
{
"type": "ball_action",
"actions": ["pass", "drive", "shot"],
"players": ["0-10"]
}
]
}
Filtering by Team
All passes by Team 0
{
"filters": [
{ "type": "ball_action", "actions": ["pass"], "teams": ["team_0"] }
]
}
All shots by Team 1
{
"filters": [
{ "type": "ball_action", "actions": ["shot"], "teams": ["team_1"] }
]
}
Multiple Action Types
Passes and shots
{
"filters": [
{
"type": "ball_action",
"actions": ["pass", "shot"],
"teams": ["team_1"]
}
]
}
Combining with Other Filters
Shots in the penalty area
{
"operator": "AND",
"filters": [
{ "type": "ball_action", "actions": ["shot"] },
{ "type": "ball_location", "x_min": 88.5, "x_max": 105, "y_min": 13.85, "y_max": 54.15 }
]
}
Player passes in second half
{
"operator": "AND",
"filters": [
{ "type": "ball_action", "actions": ["pass"], "players": ["0-10"] },
{ "type": "match_timeline", "periods": ["second_half"] }
]
}
Team attacks with drives
{
"operator": "AND",
"filters": [
{ "type": "ball_action", "actions": ["drive"], "teams": ["team_0"] },
{ "type": "ball_location", "x_min": 70, "x_max": 105, "team_side_perspective": "team_0" }
]
}
Response Structure
Ball action intervals include additional fields for player and team identification:
{
"start": 125.5,
"end": 135.5,
"label": "shot",
"type": "ball_action",
"player_id": "0-10",
"team_id": "team_0",
"team_name": "Home Team"
}
Response Fields
| Field | Type | Description |
|---|---|---|
start |
float | Start time in seconds |
end |
float | End time in seconds |
label |
string | Action type: "pass", "drive", or "shot" |
type |
string | Always "ball_action" |
player_id |
string | null | Player ID in {team}-{jersey} format, or null if not identified |
team_id |
string | null | Team identifier: "team_0" or "team_1", or null if unknown |
team_name |
string | null | Team display name (e.g., "Home Team"), or null if unknown |
Keeping Events Separate (No Merging)
By default, adjacent ball action events may be merged into a single interval after padding. To keep each event as a separate interval, set merge_results: false:
{
"merge_results": false,
"filters": [
{ "type": "ball_action", "actions": ["pass"], "teams": ["team_0"] }
]
}
This returns each pass as a distinct interval, even if they overlap after padding:
[
{
"start": 120.5,
"end": 130.5,
"label": "pass",
"type": "ball_action",
"player_id": "0-10",
"team_id": "team_0",
"team_name": "Home Team"
},
{
"start": 128.2,
"end": 138.2,
"label": "pass",
"type": "ball_action",
"player_id": "0-7",
"team_id": "team_0",
"team_name": "Home Team"
}
]
Without merge_results: false, these two passes would be merged into a single interval 120.5 - 138.2 with label pass.
Player Pixel Coordinates
When building UI overlays to highlight players during ball actions, you can request pixel coordinates by setting include_pixel_coords: true. This returns the player's position in the video frame, sampled at 4 FPS.
{
"merge_results": false,
"include_pixel_coords": true,
"filters": [
{ "type": "ball_action", "actions": ["shot"], "players": ["0-10"] }
]
}
Response with Pixel Coordinates
{
"start": 125.5,
"end": 135.5,
"label": "shot",
"type": "ball_action",
"player_id": "0-10",
"team_id": "team_0",
"team_name": "Home Team",
"pixel_coords": {
"t0": 125.5,
"dt": 0.25,
"x": [0.4521, 0.4535, 0.4562, ...],
"y": [0.6234, 0.6198, 0.6145, ...]
}
}
Pixel Coordinates Fields
| Field | Type | Description |
|---|---|---|
pixel_coords |
object | null | Player position data, or null if insufficient tracking data |
pixel_coords.t0 |
float | Start time in seconds (matches interval start) |
pixel_coords.dt |
float | Time interval between samples (0.25 = 4 FPS) |
pixel_coords.x |
array | Normalized X coordinates (0-1, left to right) |
pixel_coords.y |
array | Normalized Y coordinates (0-1, top to bottom) |
Coordinate System
- Normalized: Values are between 0 and 1, representing position relative to video dimensions
- Origin: Top-left corner of the video frame (0, 0)
- Position: Coordinates represent the bottom-center of the player's bounding box (their feet)
- Reconstruction: To get pixel coordinates, multiply by video dimensions:
pixel_x = x * video_width
Reconstructing Timestamps
Timestamps for each coordinate can be reconstructed from t0 and dt:
// JavaScript example
const timestamps = pixel_coords.x.map((_, i) => pixel_coords.t0 + i * pixel_coords.dt);
When Pixel Coordinates are Null
pixel_coords will be null when:
- The player could not be tracked during this interval
- Tracking data coverage is below 50% (unreliable data)
- The
player_idis unknown for this event
Notes
- When both
playersandteamsare specified,playerstakes precedence (more specific filter) - Events without identified players will still be included when filtering by team
- When
merge_results: true(default), multiple events merged into a single interval will haveplayer_idreflecting the first event - Use
merge_results: falseto preserve individual event attribution