Skip to content

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 5
  • 1-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_id is unknown for this event

Notes

  • When both players and teams are specified, players takes 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 have player_id reflecting the first event
  • Use merge_results: false to preserve individual event attribution