GridTracker API Overview

Locations XY Orientation

Full Field xy Directions Coming Soon

Authentication

An API key is required on all game data service endpoints. The API key identifies the calling stats data consumer and is passed either on the URL

?apikey=your api key

or as a HTTP header:

apikey: your api key

Please contact GridTracker to obtain an API key.

Environment Connections

Production GridTracker Cloud Service API

In-venue UDP Multicast

  • ip address: 239.251.101.6

  • port: 8668

Data Overview

In-venue UDP Multicast CSV Data

The data collection is tailored to work with specific consumers needing access to very high sample rate sensor locations and events. The data is provided in 2 locations, sensor xy’s come from the GridTracker local server installed at the facility and events from the GridTracker cloud. Below represents the consumers connection diagram:

game_data

  1. The consumer resides on the same network as the GridTracker local server where location data is emitted UDP via multicast. This data represents the exact location in xy of each ball and player sensor at the defined sample rate. See the Locations CSV Format section for a complete definition of each field.

  2. Events are delivered from the GridTracker cloud. This is delivered as a JSON file each time an event occurs.

Important Note The consumer must pull the players sensor assignments from the Attributes Endpoint to know which sensor number in the CSV is what player.

PING

The GridTracker server will always send a ping event which is used to inidicate the connection is alive. Ping messages will be sent every minute.

(CSV Data)
event_timestamp,event_structure_version,ping

(Data Description)
event_timestamp = the time the event occurred in UTC ms
event_structure_version = the version of this event structure; will be 2
ping = the name of the event; will always be ping

When a game is active, the GridTracker server will also send the player and ball locations with the following format. The version that will be sent is the most recent (greatest) version number unless pre-configured otherwise to support legacy consumers.

LOCATIONS V4

(CSV Data)
event_timestamp,event_structure_version,event_type<ball>,game_clock,play_clock,stop_flag,tag_serial_number,X,Y,Z,distance,Vx,Vy,V
event_timestamp,event_structure_version,event_type<player>,game_clock,play_clock,stop_flag,tag_serial_number,player_id,X,Y,Z,distance,Vx,Vy,V,Ax,Ay,A,direction
event_timestamp,event_structure_version,event_type<sky>,game_clock,play_clock,stop_flag,tag_serial_number,player_id,X,Y,Z,distance,Vx,Vy,V,Ax,Ay,A,direction

(Data Description)
event_timestamp = the time the event occurred in UTC ms
event_structure_version = the version of the event structure; event_structure_version = 4
event_type = player, sky or ball data; sky (skycam) is the same message structure as player with player_id always blank
game_clock = Placeholder for future gameclock - MM:SS.T formatted clock data, MM = minute, SS = second, T = subsecond (depending on time subsecond might be missing)
shot_clock = placeholder for future playclock - SS.T formatted clock data, SS = second, T = subsecond (depending on time subsecond might be missing)
stop_flag = placeholder for future gameclock - 0 if clock is running; 1 if clock is stopped
tag_serial_number = the unique serial number of the device
player_id = GridTracker player ID for player locations; not included for ball
X, Y, Z = mm location of the tag relative to the court coordinate system where the center of the field is 0,0
distance = distance the object has traveled since in the network, a running total in km
Vx, Vy = instantaneous velocities in the x and y directions in m/s
V = speed in m/s
Ax, Ay = acceleration in the x and y direction in m/s
A = absolute acceleration in m/s
direction = the direction of travel in degrees relative to the XY axis where 90 degrees is in the direction of the +Y axis and -90 degrees is the direction of the -Y axis

Sample:
1611805439518,4,player,,,,105645,18672,-6113,-23444,1763,1.2122,0.2122,-1.4215,1.4372,0,0,0,0
1611805439518,4,ball,,,,2147583169,-1004,-23,455,1.2122,0.2122,-1.4215,1.4372,0,0,0,0

Note: if game/shot clock is not available these fields will be empty

Click here to download an example of the v4 player/ball locations. The file is a UDP sample of 2 player tags and 1 ball. We will add additional test files for different testing conditions.

GAME BALL

Indicates a specific ball serial number is the active game ball in play.

(CSV Data)
event_timestamp,event_structure_version,gameball,tag_serial

(Data Description)
event_timestamp = the time the event occurred in UTC ms
event_structure_version = the version of the event structure; event_structure_version = 4
gameball = the name of the event; will always be gameball
tag_serial = the unique serial number of the device

PASS

The local server will auto generated a pass evemt based on the locations of players and ball on the field and is a realtime raw event This differs from the pass event seen in from the clouds logger events as those are human entered as opposed to system generated.

(CSV Data)
event_timestamp,data_version,pass,startpass_timestamp,caughtpass_timestamp,passer_id,receiver_id,maxheight,
distance_downfield,distance_air,receiver_max_velocity,receiver_avg_velocity,ball_max_velocity_xy,ball_avg_velocity_xy,ball_max_velocity_xyz,ball_avg_velocity_xyz

(Data Description)
event_timestamp = the time the event occurred in UTC ms
data_version = the version of the event structure; data_version = 3
pass = the name of the event; will always be pass
startpass_timestamp = the time the pass was made in UTC ms
caughtpass_timestamp = the time the pass was caught in UTC ms
passer_id = GridTracker player ID for the passer
receiver_id = GridTracker player ID for the receiver
maxheight = in millimeters
distance_downfield = in millimeters
distance_air = in millimeters
receiver_max_velocity = m/s
receiver_avg_velocity = m/s
ball_max_velocity_xy = m/s
ball_avg_velocity_xy = m/s
ball_max_velocity_xyz = m/s
ball_avg_velocity_xyz = m/s

Cloud Events JSON Data

LOGGER_EVENT Type

{
    "type": "playEvent",
    "data": {
        "possessingTeamId": <team id>,
        "name": "<Play Events Name>",
        "label": "<Play Events Label>",
        "playId": "<uuid of play>",
        "eventId": "<uuid of event>"
        "playData": [            // optional attribute
            {"type":"<Type of play data in dictionary>","<Field Name of play data in dictionary>":<value of play event data>}
        ]
    }
}

Play Event Object Notes:

  • type (string) is always "playEvent" for play event objects

  • data.possessingTeamId (number) the id of the team possessing the ball when the event occured

  • data.name (string) is a human readable label for the play event

  • data.label (string) is a unique identifier for the kind of play event that occurred and is used by GridTracker cloud services for statistic calculations and third-party interfaces

  • data.playId (string) the grouping id of the event

  • data.eventId (string) the event id

  • data.playData (array) is an optional array of play data objects where each play data object provides additional information associated with the play

Play Events

The following game events are captured by GridTracker:

Name Label Data Captured Penalty? Time Out? Marker?
Arrived PASS_ARRIVED
Ball spot BALL_SPOTTED ‘endOfPlaySpottedAt’
Block BLOCKED
Booth review time out TIMEOUT_BOOTH_REVIEW Yes
Caught PASS_CAUGHT ‘receivedBy’, ‘receivedAt’
Coin flip COIN_FLIP ‘winningTeam’, ‘deferred’, ‘playStartsSpottedAt’
Defensive dropped interception DEFENSE_DROPPED_INTERCEPTION
Defensive team fumble DEFENSIVE_FUMBLE
Defensive team recovered DEFENSIVE_TEAM_FUMBLE
Defensive team recovered block DEFENSIVE_TEAM_RECOVERED_BLOCK
Direct snap DIRECT_SNAP
Double pass PASS
Downed DOWNED
Drop kick DROP_KICK
Extra point attempt EXTRA_POINT_ATTEMPT
Extra point blocked EXTRA_POINT_BLOCKED
Extra point fake EXTRA_POINT_FAKE
Extra point good EXTRA_POINT_GOOD
Extra point missed EXTRA_POINT_MISSED
Extra point play EXTRA_POINT_PLAY ‘respottedAt’
Fair catch FAIR_CATCH
Field goal FIELD_GOAL ‘playStartsSpottedAt’
Field goal attempt FIELD_GOAL_ATTEMPT
Field goal blocked FIELD_GOAL_BLOCKED
Field goal fake FIELD_GOAL_FAKE
Field goal good FIELD_GOAL_GOOD
Field goal missed FIELD_GOAL_MISSED
First contact FIRST_CONTACT
First down FIRST_DOWN
First down home FIRST_DOWN_HOME Yes
First down visitor FIRST_DOWN_VISITOR Yes
Flag thrown FLAG_THROWN Yes
Fourth down FOURTH_DOWN
Free kick FREE_KICK ‘playStartsSpottedAt’
Free kick play FREE_KICK_PLAY
Fumble FUMBLE
Fumble out of bounds FUMBLE_OUT_OF_BOUNDS
Game start GAME_START
Half time time out TIMEOUT_HALFTIME Yes
Handoff HANDOFF ‘carriedBy’, ‘handoffReceivedAt’
Home team receives HOME_TEAM_RECEIVES
Home time out TIMEOUT_HOME Yes
Huddle break HUDDLE_BREAK
Huddle start HUDDLE_START
Injury time out TIMEOUT_INJURY Yes
Interception INTERCEPTION ‘intendedReceiver’
Kick attempt KICK_ATTEMPT
Kick landed KICK_LANDED
Kick received KICK_RECEIVED
Kick-off formation KICKOFF_FORMATION
Kick-off play KICKOFF_PLAY
Kicking team recovered KICKING_TEAM_RECOVERED
Lateral LATERAL
Line set LINE_SET
Motion MOTION
Muffed MUFFED
Next down NEXT_DOWN Yes
No huddle NO_HUDDLE
Offensive team fumble OFFENSIVE_FUMBLE
Offensive team recovered OFFENSIVE_FUMBLE_RECOVERED
Official called time-out TIMEOUT_OFFICIAL Yes
Onside kick ONSIDE_KICK ‘playStartsSpottedAt’
Out of bounds OUT_OF_BOUNDS
Overtime round OVERTIME_ROUND ‘playStartsSpottedAt’
Pass PASS ‘passedBy’, ‘passedFrom’
Pass dropped PASS_DROPPED ‘intendedReceiver’
Pass dropped interception PASS_DROPPED_INTERCEPTION ‘intendedReceiver’
Pass incomplete PASS_INCOMPLETE ‘intendedReceiver’
Pass lateral LATERAL_PASS
Penalty accepted PENALTY_ACCEPTED Yes
Penalty declined PENALTY_DECLINED Yes
Pitch PITCH ‘carriedBy’, ‘pitchReceivedAt’
Play action PLAY_ACTION
Play action - auto pass PLAY_ACTION
Pre-snap PRE_SNAP ‘playStartsSpottedAt’
Punt PUNT ‘playStartsSpottedAt’
Punt attempt PUNT_ATTEMPT
Punt block PUNT_BLOCKED
Punt downed PUNT_DOWNED
Punt fake PUNT_FAKE
Punt landed PUNT_LANDED
Punt received PUNT_RECEIVED
Quarter time out TIMEOUT_QUARTER Yes
Quarterback kneel QUARTERBACK_KNEEL
Quarterback recovered QUARTERBACK_RECOVERED
Quarterback spike QUARTERBACK_SPIKE
Receiving team fumble RECEIVING_TEAM_FUMBLE
Receiving team recovered RECEIVING_TEAM_RECOVERED
Regular kick REGULAR_KICK ‘playStartsSpottedAt’
Repeat down REPEAT_DOWN Yes
Run RUN ‘carriedBy’, ‘runStartedAt’
Sack SACK
Sack safety SACK_SAFETY
Safety SAFETY Yes
Second half kick-off SECOND_HALF_KICK-OFF ‘playStartsSpottedAt’
Shift SHIFT
Shovel pass SHOVEL_PASS ‘passedBy’, ‘passedFrom’
Snap SNAP
Strip sack STRIP_SACK
Tackle TACKLE
Television time out TIMEOUT_TELEVISION Yes
Three-point conversion THREE-POINT_CONVERSION
Three-point conversion attempt THREE-POINT_CONVERSION_ATTEMPT
Three-point conversion failed THREE-POINT_CONVERSION_FAILED
Three-point play THREE-POINT_PLAY ‘respottedAt’
Time out ended TIMEOUT_END
Tipped TIPPED
Touchback TOUCHBACK Yes
Touchdown TOUCHDOWN
Touchdown pass TOUCHDOWN_PASS ‘receivedBy’, ‘receivedAt’
Two-minute warning time out TIMEOUT_TWO-MINUTE Yes
Two-point conversion TWO-POINT_CONVERSION
Two-point conversion attempt TWO-POINT_CONVERSION_ATTEMPT
Two-point conversion failed TWO-POINT_CONVERSION_FAILED
Two-point play TWO-POINT_PLAY ‘respottedAt’
Visiting team receives VISITING_TEAM_RECEIVES
Visitor time out TIMEOUT_VISITOR Yes

Play Event Notes:

  • For certain play events, additional data is captured by the logger

  • See Play Events Data Dictionary section for a full description of captured play event data

  • The event label is a unique play event identifier used by GridTracker for statistic calculations

  • Penalty events can occur either during normal game play or as a consequence of a game penalty

Play Data Dictionary

Field Name Description Typed Value Data Type
blockedBy Blocked by BY number
carriedBy Ball carrier BY number
downedBy Downed by BY number
endOfPlaySpottedAt Spotted end of play at AT AT Structure
fumbledBy Fumbled by BY number
handoffReceivedAt Handoff received at AT AT Structure
intendedReceiver Intended receiver BY number
kickedBy Kicked by BY number
kickReceiver Receiver of kick BY number
interceptedBy Intercepted by BY number
interceptedAt Intercepted at AT AT Structure
passedBy Passed by BY number
playStartsSpottedAt Spotted start of play at AT AT Structure
puntedBy Punted by BY number
receivedBy Received by BY number
receivedAt Received at AT AT Structure
recoveredBy Recovered by BY number
recoveredAt Recovered at AT AT Structure
returnedBy Returned by BY number
tackledBy Tackled by BY number
tackledBy2 Tackled by BY number
tackledBy3 Tackled by BY number
sackedBy Sacked by BY number
sackedBy2 Sacked by BY number
sackedBy3 Sacked by BY number
spottedAt Spotted at AT AT Structure

** AT Structure **

  • team (number) the side of the field denoted by the defending team id; i.e. “The Chiefs (team) 25”

  • yardage (number) the yard line on that side of the field; i.e. “The Chiefs 25 (yardage)”

SERVER_EVENT Type

PASS

A system generated event that represents location details of a pass. The fields match the same values on the location pass CSV event including the teamIds.

{"type":"SERVEREVENT",
"data":{
  "startTimestamp":1649780242167,
  "caughtTimestamp":1649780250717,
  "passer":{
    "id":"6844",
    "sensorId":"65575",
    "teamId":"515"
  },
  "receiver":{
    "id":"6844",
    "sensorId":"65575",
    "teamId":"515"
  },
  "maxHeight":5203, // mm
  "distanceDownfield":2079, // mm
  "distanceAir":4279, // mm
  "receiverMaxVelocity":80.2, // m/s
  "receiverAvgVelocity":50.2, // m/s
  "ballMaxVelocityxy": 20.2, // m/s
  "ballAvgVelocityxy": 10.0, // m/s
  "ballMaxVelocityxyz": 20.2, // m/s
  "ballAvgVelocityxyz": 10.0 // m/s
},
"label":"PASS","playData":[{"passedBy":6844}],"possessingTeamId":0}

SNAP Type

A system generated event that occurs when the ball is snapped and indicates the play direction.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "losX": 11,
  "losY": 12,
  "direction": "SOUTH",
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  }
},
"label":"SNAP","playData":[],"possessingTeamId":0}

TACKLE Type

A system generated event that represents players locations around the ball at the end of play.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "playerSensorId": "65575",
  "playerId": "6844",
  "teamId": "515",
  "playerX": 1693,
  "playerY": 9211,
  "playerZ": 0,
  "sideOfFieldTeamId": 515,
  "distanceDownfield": 2079, // mm
  "defensivePlayersNumber": 1,
  "defensivePlayers": [
    {
      "id": "8462",
      "sensorId": "65726",
      "teamId": "461"
    }
  ]
},
"label":"TACKLE","playData":[],"possessingTeamId":0}

ACTIVE_BALL Type

Returns a string that indicates the serial number of the active ball. This value will change as the ball changes throughout the game.

COMPLETED_PASS Type

A derived event that represents a completed pass. The fields match the same values on the location pass CSV event including the teamIds.

{
  "startTimestamp":1649780242167,
  "caughtTimestamp":1649780250717,
  "passer":{
    "id":"6844",
    "sensorId":"65575",
    "teamId":"515",
    "location": [1, 2]  // x,y
  },
  "receiver":{
    "id":"6844",
    "sensorId":"65575",
    "teamId":"515",
    "location": [3, 4]  // x,y
  },
  "maxHeight":5203, // mm
  "distanceDownfield":2079, // distance from the start of the pass; in mm
  "distanceAir":4279, // mm
  "distanceGained": 2000, // distance from line of scrimmage; in mm 
  "afterCatchDistance": {
    "downfield": 1000, // mm
    "total": 1500 // mm
  },
  "receiverMaxVelocity":80.2, // m/s
  "receiverAvgVelocity":50.2, // m/s
  "ballMaxVelocityxy": 20.2, // m/s
  "ballAvgVelocityxy": 10.0, // m/s
  "ballMaxVelocityxyz": 20.2, // m/s
  "ballAvgVelocityxyz": 10.0, // m/s
  "playId": "73a96e6a-bf54-401e-8f9a-ee066b2e52ae"
}

INCOMPLETED_PASS Type

A derived event that represents an incompleted pass. The fields match the same values on the location pass CSV event including the teamIds.

{
  "startTimestamp":1649780242167,
  "caughtTimestamp":1649780250717,
  "passer":{
    "id":"6844",
    "sensorId":"65575",
    "teamId":"515",
    "location": [1, 2]  // x,y
  },
  "receiver":null,
  "maxHeight":5203, // mm
  "distanceDownfield":2079, // distance from the start of the pass; in mm
  "distanceAir":4279, // mm
  "distanceGained": 0, // distance from line of scrimmage; in mm 
  "afterCatchDistance": {
    "downfield": 0, // mm
    "total": 0 // mm
  },
  "receiverMaxVelocity":80.2, // m/s
  "receiverAvgVelocity":50.2, // m/s
  "ballMaxVelocityxy": 20.2, // m/s
  "ballAvgVelocityxy": 10.0, // m/s
  "ballMaxVelocityxyz": 20.2, // m/s
  "ballAvgVelocityxyz": 10.0, // m/s
  "playId": "73a96e6a-bf54-401e-8f9a-ee066b2e52ae"
}

INTERCEPTION Type

A derived event that represents an intercepted pass. The fields match the same values on the location pass CSV event including the teamIds.

{
    "startTimestamp": 1649780242167,
    "caughtTimestamp": 1649780250717,
    "passer": {
      "id": "8462",
      "sensorId": "65726",
      "teamId": "461",
      "location": [1, 2]  // x,y
    },
    "receiver": {
      "id": "6844",
      "sensorId": "65575",
      "teamId": "515",
      "location": [3, 4]  // x,y
    },
    "maxHeight": 5203, // mm
    "distanceDownfield": 2079, // distance from the start of the pass; in mm
    "distanceAir": 4279, // mm
    "distanceGained": 2000, // distance from line of scrimmage; in mm 
    "afterCatchDistance": {
      "downfield": 1000, // mm
      "total": 1500 // mm
    },
    "receiverMaxVelocity":80.2, // m/s
    "receiverAvgVelocity":50.2, // m/s
    "ballMaxVelocityxy": 20.2, // m/s
    "ballAvgVelocityxy": 10.0, // m/s
    "ballMaxVelocityxyz": 20.2, // m/s
    "ballAvgVelocityxyz": 10.0, // m/s
    "playId": "73a96e6a-bf54-401e-8f9a-ee066b2e52ae"
  }
}

POSSESSION Type

A system generated event that represents the exact point in time and location a player either “GOT” or “LOST” possesssion of the football. The fieldPosition object contains the side (NORTH (or right side) or SOUTH (or left side) from a broadcast viewpoint) and the yardline values.

{"type":"PLAYEVENT",
"data":{
  "type":"LOST",  // possible values are GOT or LOST
  "playerSensorId":"65586",
  "playerX":1693,
  "playerY":9211,
  "playerZ":0,
  "playerId":6846,
  "teamId":123,
  "ballSensorId":"2147582453",
  "downfieldDistance":4500,  // mm, determined with LOST possession; always 0 for GOT possession
  "totalDistance":5000,  // mm, determined with LOST possession; always 0 for GOT possession
  "maxVelocity":10.5,  // m/s, determined with LOST possession; always 0.0 for GOT possession
  "avgVelocity":8.0,  // m/s, determined with LOST possession; always 0.0 for GOT possession
  "fieldPosition": {
    "side":"NORTH",
    "rawYardsFromCenter":10.07,
    "yardLine":40
  }
},
"label":"UNDEFINED","playData":[],"possessingTeamId":0}

RUSH Type

A derived event that represents specific rush attributes from a HANDOFF or RUN logger event.

{
  "startTimestamp": 1649780242167,
  "endTimestamp": 1649780247000,
  "passer": {
    "id": 6846,
    "sensorId": "65586",
    "teamId": 12,
    "locations": {
      "atStart": [1, 2],  // x,y
      "atEnd": [] // x,y
    }
  },
  "receiver": { // in the case of a RUN the passer and receiver will be the same player
    "id": 6897,
    "sensorId": "65587",
    "teamId": 12,
    "locations": {
      "atStart": [3, 4],  // x,y
      "atEnd": [5, 6] // x,y
    }
  },
  "distance": {
    "downfield": 20000, // distance from the start of the rush; in mm
    "total": 21500, // scramble distance; in mm
    "gained": 19000 // distance from line of scrimmage; in mm 
  },
  "speed": {
    "maxVelocity": 20.5, // in m/s
    "avgVelocity": 15.0  // in m/s
  },
  "playId": "73a96e6a-bf54-401e-8f9a-ee066b2e52ae"
}

LINE_OF_SCRIMMAGE Type

A system generated event that represents the current line of scrimmage.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  }
},
"label":"UNDEFINED","playData":[{"spottedAt":50}],"possessingTeamId":0}

CROSS_GOAL_LINE Type

A system generated event that occurs when a ball traverses the goal line.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  }
},
"label":"UNDEFINED","playData":[{"spottedAt":50}],"possessingTeamId":0}

CROSS_SIDE_LINE Type

A system generated event that occurs when a ball traverses the side line.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  }
},
"label":"UNDEFINED","playData":[{"spottedAt":50}],"possessingTeamId":0}

MARKER Type

Returns a string that marks the active state of the game.

Game Status Markers

Status / Type Data Description
PREGAME Start of pregame
PLAY_START Start of official play
END_FIRST_HALF End of first half
END_FIRST_QUARTER End of first quarter
END_SECOND_QUARTER End of second quarter
END_THIRD_QUARTER End of third quarter
END_OVER_TIME End of over time
START_SECOND_HALF Start of second half
START_SECOND_QUARTER Start of second quarter
START_THIRD_QUARTER Start of third quarter
START_FOURTH_QUARTER Start of fourth quarter
START_OVER_TIME Start of over time
PLAY_END End of game
  • Example marker (application/json)

    {"seq":"5","type":"data","source":"marker","data":{"t":1665763312858,"gameId":"f29b2985-4bd7-11ed-9596-0242e9e2912e","status":"PLAY_START"}}

END_OF_PLAY Type

A system generated event that represents the pre-determined spot at the end of play.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "distanceLos": "LOSS", // possible values are LOSS or GAIN
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  },
  "sideOfFieldTeamId": 515
},
"label":"SNAP","playData":[],"possessingTeamId":0}

END_OF_PLAY_SPOT Type

A system generated event that represents the actual spot at the end of play.

{"type":"SERVEREVENT",
"data":{
  "ballSensorId": "98700101",
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "distanceLos": 3000,
  "fieldPosition": {                  
    "side": "NORTH",
    "rawYardsFromCenter": 0.0,
    "yardLine": 50
  },
  "sideOfFieldTeamId": 515
},
"label":"SNAP","playData":[],"possessingTeamId":0}

FIELD_GOAL Type

A system generated event that represents the positional data of the ball as it traverses through the uprights.

{"type":"SERVEREVENT",
"data":{
  "ballX": 11,
  "ballY": 12,
  "ballZ": 13,
  "kickX": 14,
  "kickY": 15,
  "fgMakeTimestamp": 1678823745000,
  "durationFlight": 4000,
  "maxHeight": 13716,
  "distance": 3000,
  "maxProjectedDistance": 2500,
  "maxVelocity": 10.5, // m/s
  "sideOfFieldTeamId": 515
},
"label":"UNDEFINED","playData":[],"possessingTeamId":0}

LOCATION_PUNT Type

A system generated event that represents players locations around the player at the punt.

{"type":"SERVEREVENT",
"data":{
  "playerSensorId": "65575",
  "playerId": "6844",
  "teamId": "515",
  "recvPlayerId": "6845",
  "recvTeamId": "512",
  "recvPlayerSensorId": "65576",
  "kickX": 1693,
  "kickY": 9211,
  "kickZ": 0,
  "kickTimestamp": 1678823745000,
  "recvX": 1721,
  "recvY": 8761,
  "recvZ": 0,
  "durationFlight": 4000,
  "maxHeight": 5203,
  "distance": 4279,
  "maxVelocity": 10.5,
  "sideOfFieldTeamId": 515
  ]
},
"label":"UNDEFINED","playData":[],"possessingTeamId":0}

Cloud Service(s) Stats JSON Data

The json file contains stats at the following levels:
- Full game stats (game_stats object)
- First half stats (half_1_stats object)
- Second half stats (half_2_stats object)
- First quarter stats (quarter_1_stats object)
- Second quarter stats (quarter_2_stats object)
- Third quarter stats (quarter_3_stats object)
- Fourth quarter stats (quarter_4_stats object)
- Overtime stats (ot_1_stats object)

at (number) - epoch timestamp of file
at_formatted (string) - human readable timestamp represent by the at field
period (string) - the current or last period of the active game (PRE, Q1, Q2, Q3, Q4, HT, OT, END); completed games will have COMPLETED and scheduled games with test pattern with have TP

Each game, half and quarter stats object has the same format and contains the following fields:

reference (string) - the internal value to represent the GridTracker internal tracking id
home (object) - all team and player stats for the home team
away (object) - all team and player stats for the away team

Each home and away objects contains the same fields; those are:

team (object) - contains all team level stats
team,team_id (number) - the GridTracker internal team id
team,consumer_code (string) - the calling consumers defined code for the team or the GridTracker team_id
team,team_name (string) - the name of the team defined in GridTracker
team,DIST (number) - total team distance in cm
team,DIST_MILES (number) - total team distance in miles
team,DEF_AST (number)
team,DEF_BK (number)
team,DEF_FF (number)
team,DEF_FUM_FORCED (number)
team,DEF_FUM_RCV (number)
team,DEF_FUM_RCV_BLK (number)
team,DEF_INT (number)
team,DEF_PASS_DEFL (number)
team,DEF_PD (number)
team,DEF_PTS (number)
team,DEF_SACK (number)
team,DEF_SNAP (number)
team,DEF_SOLO (number)
team,DEF_TD (number)
team,DEF_TLOSS (number)
team,DEF_TOT (number)
team,DEF_INT_YDS (number)
team,FLAG_BAT (number)
team,FLAG_BLI (number)
team,FLAG_CHB (number)
team,FLAG_CLP (number)
team,FLAG_DH (number)
team,FLAG_DOD (number)
team,FLAG_DOF (number)
team,FLAG_DOG (number)
team,FLAG_DOK (number)
team,FLAG_DPI (number)
team,FLAG_DSQ (number)
team,FLAG_DTM (number)
team,FLAG_ENC (number)
team,FLAG_FCI (number)
team,FLAG_FMM (number)
team,FLAG_FST (number)
team,FLAG_HC (number)
team,FLAG_IBW (number)
team,FLAG_ICB (number)
team,FLAG_ICT (number)
team,FLAG_ICU (number)
team,FLAG_IDK (number)
team,FLAG_IDP (number)
team,FLAG_IDT (number)
team,FLAG_IFC (number)
team,FLAG_IFH (number)
team,FLAG_IFP (number)
team,FLAG_ILF (number)
team,FLAG_ILH (number)
team,FLAG_ILM (number)
team,FLAG_ILS (number)
team,FLAG_ING (number)
team,FLAG_IPB (number)
team,FLAG_ISH (number)
team,FLAG_ITK (number)
team,FLAG_ITP (number)
team,FLAG_KIK (number)
team,FLAG_KOB (number)
team,FLAG_LBL (number)
team,FLAG_LEA (number)
team,FLAG_LEV (number)
team,FLAG_NZI (number)
team,FLAG_OFK (number)
team,FLAG_OH (number)
team,FLAG_OOF (number)
team,FLAG_OPI (number)
team,FLAG_OTM (number)
team,FLAG_POK (number)
team,FLAG_RNK (number)
team,FLAG_RPS (number)
team,FLAG_RRK (number)
team,FLAG_SFK (number)
team,FLAG_TAU (number)
team,FLAG_TRP (number)
team,FLAG_UNR (number)
team,FLAG_UNS (number)
team,FLAG_UOH (number)
team,FLAG_YDS (number)
team,KICK_FGA (number)
team,KICK_FGM (number)
team,KICK_OFF (number)
team,KICK_ONS (number)
team,KICK_PTS (number)
team,KICK_RTN_ATT (number)
team,KICK_RTN_FC (number)
team,KICK_RTN_PTS (number)
team,KICK_RTN_TD (number)
team,KICK_RTN_YDS (number)
team,KICK_TB (number)
team,KICK_XPA (number)
team,KICK_XPM (number)
team,PASS_2PT_ATT (number)
team,PASS_2PT_CMP (number)
team,PASS_3PT_ATT (number)
team,PASS_3PT_CMP (number)
team,PASS_ATT (number)
team,PASS_CMP (number)
team,PASS_FUM_RCV (number)
team,PASS_INT (number)
team,PASS_SK (number)
team,PASS_SYD (number)
team,PASS_TD (number)
team,PASS_YDS (number)
team,PASS_YPA (number)
team,PTS (number)
team,PUNT_BP (number)
team,PUNT_DOWN (number)
team,PUNT_GAVG (number)
team,PUNT_GYDS (number)
team,PUNT_IN20 (number)
team,PUNT_PUNTS (number)
team,PUNT_RET (number)
team,PUNT_RTN_ATT (number)
team,PUNT_RTN_FC (number)
team,PUNT_RTN_PTS (number)
team,PUNT_RTN_TD (number)
team,PUNT_RTN_YDS (number)
team,PUNT_TB (number)
team,PUNT_YDS (number)
team,RECV_2PT_REC (number)
team,RECV_3PT_REC (number)
team,RECV_DROP (number)
team,RECV_FUM (number)
team,RECV_FUM_RCV (number)
team,RECV_LONG (number)
team,RECV_LST (number)
team,RECV_PTS (number)
team,RECV_REC (number)
team,RECV_TARGET (number)
team,RECV_SCRIM_REC (number)
team,RECV_SCRIM_REC_PG (number)
team,RECV_SCRIM_RUSH (number)
team,RECV_SCRIM_RU_PG (number)
team,RECV_SCRIM_YDS_PG (number)
team,RECV_TD (number)
team,RECV_YDS (number)
team,RUSH_2PT (number)
team,RUSH_2PT_ATT (number)
team,RUSH_3PT (number)
team,RUSH_3PT_ATT (number)
team,RUSH_ATT (number)
team,RUSH_FUM (number)
team,RUSH_FUM_RCV (number)
team,RUSH_LONG (number)
team,RUSH_LST (number)
team,RUSH_PTS (number)
team,RUSH_TD (number)
team,RUSH_YDS (number)
team,RUSH_YPA (number)
team,RUSH_YPG (number)
team,SAFE_DEF (number)
team,SAFE_OFF (number)
team,SAFE_PTS (number)
team,SNAP (number)
team,TOTAL_SNAP_TO_PASS (number) - total time taken in all plays between the snap and the pass
team,SNAP_TO_PASS (number) - the avg time taken from all plays between the snap and the pass

players (object array) - all team and player stats; team stats will be identified by a player_id of 0
players,#,player_id (number) - the GridTracker internal player id or will be 0 if team
players,#,consumer_code (string) - the calling consumers defined code for the player or the GridTracker player_id
players,#,jersey_number (number) - player team jersey number or -1 if team
players,#,first_name (string) - players first name or null if team
players,#,last_name (string) - players last name or null if team
players,#,position_abbr (string) - player position abbreviations, C (Center),OG (Offensive guard),OT (Offensive tackle),OL (Offensive linemen),R (Receiver),QB (Quarterback),RB (Running back),FB (Fullback),HB (Halfback),WR (Wide receiver),TE (Tight end),ILB (Interior linebacker aka "jack"),DT (Defensive tackle),DE (Defensive end),DL (Defensive linemen),MLB (Middle linebacker),OLB (Outside linebacker),CB (Cornerback),FS (Free safety),S (Safety),K (Kicker),KOS (Kickoff specialist),P (Punter),H (Holder),LS (Long snapper),KR (Kick returner),PR (Punt returner)
players,#,sensor (number) - current player assigned sensor or 0 if team
players,#,on_the_floor (boolean) - true if currently on the field in lineup
players,#,DIST (number) - total player distance in cm
players,#,DIST_MILES (number) - total player distance in miles
players,#,DEF_AST (number)
players,#,DEF_BK (number)
players,#,DEF_FF (number)
players,#,DEF_FUM_FORCED (number)
players,#,DEF_FUM_RCV (number)
players,#,DEF_FUM_RCV_BLK (number)
players,#,DEF_INT (number)
players,#,DEF_PASS_DEFL (number)
players,#,DEF_PD (number)
players,#,DEF_PTS (number)
players,#,DEF_SACK (number)
players,#,DEF_SNAP (number)
players,#,DEF_SOLO (number)
players,#,DEF_TD (number)
players,#,DEF_TLOSS (number)
players,#,DEF_TOT (number)
players,#,DEF_YDS (number)
players,#,FLAG_BAT (number)
players,#,FLAG_BLI (number)
players,#,FLAG_CHB (number)
players,#,FLAG_CLP (number)
players,#,FLAG_DH (number)
players,#,FLAG_DOD (number)
players,#,FLAG_DOF (number)
players,#,FLAG_DOG (number)
players,#,FLAG_DOK (number)
players,#,FLAG_DPI (number)
players,#,FLAG_DSQ (number)
players,#,FLAG_DTM (number)
players,#,FLAG_ENC (number)
players,#,FLAG_FCI (number)
players,#,FLAG_FMM (number)
players,#,FLAG_FST (number)
players,#,FLAG_HC (number)
players,#,FLAG_IBW (number)
players,#,FLAG_ICB (number)
players,#,FLAG_ICT (number)
players,#,FLAG_ICU (number)
players,#,FLAG_IDK (number)
players,#,FLAG_IDP (number)
players,#,FLAG_IDT (number)
players,#,FLAG_IFC (number)
players,#,FLAG_IFH (number)
players,#,FLAG_IFP (number)
players,#,FLAG_ILF (number)
players,#,FLAG_ILH (number)
players,#,FLAG_ILM (number)
players,#,FLAG_ILS (number)
players,#,FLAG_ING (number)
players,#,FLAG_IPB (number)
players,#,FLAG_ISH (number)
players,#,FLAG_ITK (number)
players,#,FLAG_ITP (number)
players,#,FLAG_KIK (number)
players,#,FLAG_KOB (number)
players,#,FLAG_LBL (number)
players,#,FLAG_LEA (number)
players,#,FLAG_LEV (number)
players,#,FLAG_NZI (number)
players,#,FLAG_OFK (number)
players,#,FLAG_OH (number)
players,#,FLAG_OOF (number)
players,#,FLAG_OPI (number)
players,#,FLAG_OTM (number)
players,#,FLAG_POK (number)
players,#,FLAG_RNK (number)
players,#,FLAG_RPS (number)
players,#,FLAG_RRK (number)
players,#,FLAG_SFK (number)
players,#,FLAG_TAU (number)
players,#,FLAG_TRP (number)
players,#,FLAG_UNR (number)
players,#,FLAG_UNS (number)
players,#,FLAG_UOH (number)
players,#,FLAG_YDS (number)
players,#,KICK_FGA (number)
players,#,KICK_FGM (number)
players,#,KICK_OFF (number)
players,#,KICK_ONS (number)
players,#,KICK_PTS (number)
players,#,KICK_RTN_ATT (number)
players,#,KICK_RTN_FC (number)
players,#,KICK_RTN_PTS (number)
players,#,KICK_RTN_TD (number)
players,#,KICK_RTN_YDS (number)
players,#,KICK_TB (number)
players,#,KICK_XPA (number)
players,#,KICK_XPM (number)
players,#,PASS_2PT_ATT (number)
players,#,PASS_2PT_CMP (number)
players,#,PASS_3PT_ATT (number)
players,#,PASS_3PT_CMP (number)
players,#,PASS_ATT (number)
players,#,PASS_CMP (number)
players,#,PASS_FUM_RCV (number)
players,#,PASS_INT (number)
players,#,PASS_SK (number)
players,#,PASS_SYD (number)
players,#,PASS_TD (number)
players,#,PASS_YDS (number)
players,#,PASS_YPA (number)
players,#,PTS (number)
players,#,PUNT_BP (number)
players,#,PUNT_DOWN (number)
players,#,PUNT_GAVG (number)
players,#,PUNT_GYDS (number)
players,#,PUNT_IN20 (number)
players,#,PUNT_PUNTS (number)
players,#,PUNT_RET (number)
players,#,PUNT_RTN_ATT (number)
players,#,PUNT_RTN_FC (number)
players,#,PUNT_RTN_PTS (number)
players,#,PUNT_RTN_TD (number)
players,#,PUNT_RTN_YDS (number)
players,#,PUNT_TB (number)
players,#,PUNT_YDS (number)
players,#,RECV_2PT_REC (number)
players,#,RECV_3PT_REC (number)
players,#,RECV_DROP (number)
players,#,RECV_FUM (number)
players,#,RECV_FUM_RCV (number)
players,#,RECV_LONG (number)
players,#,RECV_LST (number)
players,#,RECV_PTS (number)
players,#,RECV_REC (number)
players,#,RECV_SCRIM_REC (number)
players,#,RECV_SCRIM_REC_PG (number)
players,#,RECV_SCRIM_RUSH (number)
players,#,RECV_SCRIM_RU_PG (number)
players,#,RECV_SCRIM_YDS_PG (number)
players,#,RECV_TD (number)
players,#,RECV_YDS (number)
players,#,RUSH_2PT (number)
players,#,RUSH_2PT_ATT (number)
players,#,RUSH_3PT (number)
players,#,RUSH_3PT_ATT (number)
players,#,RUSH_ATT (number)
players,#,RUSH_FUM (number)
players,#,RUSH_FUM_RCV (number)
players,#,RUSH_LONG (number)
players,#,RUSH_LST (number)
players,#,RUSH_PTS (number)
players,#,RUSH_TD (number)
players,#,RUSH_YDS (number)
players,#,RUSH_YPA (number)
players,#,RUSH_YPG (number)
players,#,SAFE_DEF (number)
players,#,SAFE_OFF (number)
players,#,SAFE_PTS (number)
players,#,SNAP (number)
players,#,TOTAL_SNAP_TO_PASS (number) - total time taken in all plays between the snap and the pass
players,#,SNAP_TO_PASS (number) - the avg time taken from all plays between the snap and the pass

Games

Schedule

Schedule
GET/broadcast/v1/games/schedule{?from,to,apikey}

Requests the GridTracker game schedule. If from and to are not provided it will return all games at the time of the request to all into the future. If from and to are provided will return only the games during the timeframe. The intention of a from/to search would be in the future as the broadcast service is live and upcoming scheduled games.

Example URI

GET /broadcast/v1/games/schedule?from=&to=&apikey=
URI Parameters
HideShow
from
number (optional) 

The starting epoch timestamp (in milliseconds); in UTC

to
number (optional) 

The ending epoch timestamp (in milliseconds); in UTC

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "games": [
    {
      "schedule_id": "1a4118d4-2e50-11e6-b4a4-deecc6e6f111",
      "event_id": "1a4118d4-2e50-11e6-b4a4-deecc6e6f111",
      "location": "Test Location",
      "kickoff_at": 1549587600000,
      "name": "TestTeam at BWB",
      "gender": "MEN",
      "status": "SCHEDULED",
      "home_team_id": 461,
      "away_team_id": 493,
      "officials_team_id": 0,
      "_link": "/broadcast/display?schedule_id=1a4118d4-2e50-11e6-b4a4-deecc6e6f111",
      "_home_team_link": "/broadcast/v1/games/teams/461?testing=true",
      "_home_team_images": "/broadcast/v1/games/teams/461/images?testing=true",
      "_away_team_link": "/broadcast/v1/games/teams/493?testing=true",
      "_away_team_images": "/broadcast/v1/games/teams/493/images?testing=true",
      "_sse_events_link": "/broadcast/v1/events/logger-stream?schedule_id=1a4118d4-2e50-11e6-b4a4-deecc6e6f111",
      "_events_link": "/broadcast/v1/events?schedule_id=1a4118d4-2e50-11e6-b4a4-deecc6e6f111",
      "udp_multicast_ip": "127.0.0.1",
      "udp_multicast_port": 8765,
      "locations": {
        "links": [
          {
            "name": "Q1",
            "_locations_links": [
              "/broadcast/v1/locations?id=aa913656-c977-11ec-bba3-02427afb34b5&from=1549587600000&to=1549588600000"
            ]
          }
        ]
      }
    }
  ]
}

Active Game Colors

Active Game Colors
GET/broadcast/v1/games/active/{schedule_id}/colors{?apikey}

Returns the team colors for the active game. This endpoint only works with games in an ACTIVE status. It is possible to subscribe to a game before it is active which means once a game marker message is received this endpoint could be called to get the current colors set by GridTracker game success group. The base team color (color_rgb) is returned under the teams endpoint and can be used to represent the team color however this endpoint represents the exact jersey color each team is wearing at the time of the active game.

Example URI

GET /broadcast/v1/games/active/schedule_id/colors?apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 469,
      "color": "00FF80"
    },
    {
      "id": 470,
      "color": "0080FF"
    }
  ]
}

Teams

List Teams

List Teams
GET/broadcast/v1/games/teams{?apikey}

Returns all GridTracker teams.

Example URI

GET /broadcast/v1/games/teams?apikey=
URI Parameters
HideShow
apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 461,
      "name": "TestTeam"
    },
    {
      "id": 493,
      "name": "BWB"
    }
  ]
}

Team Roster

Team Roster
GET/broadcast/v1/games/teams/{team_id}{?apikey,game_event_id}

The current active players on the team. The endpoint also returns the players current assigned sensor which can change during a game. The game_event_id parameter can be used to look up all of the players on the team at the time of a game. With this query parameter an additional field is return ‘sensor_assignments_history’ which indicates the sensor assignments during the game. This field is the same response from the Event API Sensor Assignments History Players who are no longer on the team will have an ‘is_active’ false. The special_services field returns items for specific special events; possible type values are MIC, VIDEO.

Football Player Positions

Abbreviation Description
BJ Back Judge
CB Center
CB Corner Back
DB Defensive Back
DE Defensive End
DJ Down Judge
DL Defensive Lineman
DT Defensive Tackle
FB Fullback
FJ Field Judge
FS Free Safety
ILB Inside Linebacker
K Kicker
KR Kick Return
LG Left Guard
LJ Line Judge
LS Long Snapper
LT Left Tackle
MLB Middle Linebacker
OL Offensive Lineman
OLB Outside Linebacker
P Punter
PR Punt Return
QB Quarterback
R Referee
RB Running Back
RG Right Guard
RT Right Tackle
S Safety
SJ Side Judge
ST Special Teams
TE Tight End
U Umpire
WR Wide Receiver

Example URI

GET /broadcast/v1/games/teams/team_id?apikey=&game_event_id=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

game_event_id
string (optional) 

ID of the game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 493,
  "name": "BWB",
  "abbr": "BB",
  "city": "Kansas City",
  "state": "MO",
  "color_rgb": "0066CC",
  "players": [
    {
      "id": 3531,
      "first_name": "Shelden",
      "last_name": "Williams",
      "jersey_number": 4,
      "jersey_number_str": "4",
      "position_abbr": "QB",
      "sensor": 100630,
      "special_services": []
    },
    {
      "id": 3541,
      "first_name": "Casey",
      "last_name": "Jacobsen",
      "jersey_number": 3,
      "jersey_number_str": "3",
      "position_abbr": "WR",
      "sensor": 100520,
      "special_services": [
        {
          "type": "MIC",
          "value": "mic6"
        }
      ]
    },
    {
      "id": 3548,
      "first_name": "Mateen",
      "last_name": "Cleaves",
      "jersey_number": 2,
      "jersey_number_str": "2",
      "position_abbr": "K",
      "sensor": 100539,
      "special_services": []
    },
    {
      "id": 3532,
      "first_name": "Alando",
      "last_name": "Tucker",
      "jersey_number": 6,
      "jersey_number_str": "6",
      "position_abbr": "P",
      "sensor": null,
      "special_services": []
    }
  ]
}

List Officials Teams

List Officials Teams
GET/broadcast/v1/games/officials/teams{?apikey}

Returns all officials teams.

Example URI

GET /broadcast/v1/games/officials/teams?apikey=
URI Parameters
HideShow
apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 91,
      "name": "Officials Team 1"
    }
  ]
}

Officials Team And Members Attributes

Officials Team And Members Attributes
GET/broadcast/v1/games/officials/teams/{team_id}{?apikey}

The special_services field returns items for specific special events; possible type values are MIC, VIDEO.

Example URI

GET /broadcast/v1/games/officials/teams/team_id?apikey=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 91,
  "name": "Officials Team 1",
  "abbr": "OT",
  "members": [
    {
      "id": 3531,
      "first_name": "Doug",
      "last_name": "Williams",
      "jersey_number": 0,
      "jersey_number_str": "00",
      "position_abbr": "C",
      "sensor": 100699,
      "special_services": []
    }
  ]
}

Team And Player Images

Team And Player Images
GET/broadcast/v1/games/teams/{team_id}/images{?apikey}

Returns the team and player image links.

Example URI

GET /broadcast/v1/games/teams/team_id/images?apikey=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "team_image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3",
  "players": [
    {
      "id": 2907,
      "image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3"
    },
    {
      "id": 2908,
      "image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3"
    },
    {
      "id": 2909,
      "image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3"
    },
    {
      "id": 2910,
      "image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3"
    },
    {
      "id": 2911,
      "image_url": "https://shottracker.com/pimg/bc1b6e06-3a44-11e6-857c-06a15c73f3c3"
    }
  ]
}

Stats

Test Pattern Game Stats

Test Pattern Game Stats
GET/broadcast/v1/stats/testpattern{?schedule_id,format,apikey}

This endpoint returns the a zero’ed out stats file for any scheduled, live or ended game. As a test pattern in broadcast, this file is intended to be used as a calibration test of the stats file. Actual stats for live or ended games are not available on this endpoint; the Full Game Stats or Full Game Stats SSE endpoints should be used.

Example URI

GET /broadcast/v1/stats/testpattern?schedule_id=&format=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

format
string (optional) 

indicates the response format; values are json or xml; if no value is given the default format is json

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
See "Game Stats JSON Format"

Live Game Stats SSE

Live Game Stats SSE
GET/broadcast/v1/stats/event-stream{?schedule_id,format,include_player_season,test_pattern,stats_level,apikey}

Opens a Server Sent Events (SSE) connection that will remain open as long as the connection persists. This endpoint will push updated live game stats to the consumer as they occur. The schedule_id from the Schedule endpoint is required. If the connection drops during the game, after reconnecting, the latest game stats file will be pushed. See the Full Game Stats JSON Format for a complete description of each field.

Example connecting to the SSE endpoint using javascript:

var EventSource = require("eventsource");
var fs = require('fs');

const SCHEDULE_ID = '<schedule id>';
const API_KEY = '<your api key>';

var es = new EventSource(`https://api-gridtracker.ddsports.com/broadcast/v1/stats/event-stream?schedule_id=${SCHEDULE_ID}&apikey=${API_KEY}`);

var listener = function (event) {
    var type = event.type;
    if (type === 'message') {
        var data = event.data;
        console.log(data);

        fs.writeFile("./sse_data.json", data, function(err) {
            if(err) {
                return console.log(err);
            }

            console.log("The file was saved!");
        });
    }
};

es.addEventListener('open', listener);
es.addEventListener('message', listener);
es.addEventListener('error', listener);

Example connection to the SSE endpoint using golang (download tool):

package main

import (
  "bufio"
  "fmt"
  "io"
  "net/http"
  "os"
  "strings"
  "time"
)

const CONNECTED_STATUS = "CONNECTED"
const DISCONNECTED_STATUS = "DISCONNECTED"

var timer *time.Timer

func main() {
  reader := bufio.NewReader(os.Stdin)
  fmt.Println("GridTracker SSE Download Utility")
  fmt.Println("--------------------------------")
  fmt.Println("Enter Event Stream URL")
  fmt.Print("> ")
  url, _ := reader.ReadString('\n')
  fmt.Println("Enter Output File Name")
  fmt.Print("> ")
  fileName, _ := reader.ReadString('\n')
  fmt.Println("================================")

  run(strings.TrimSpace(url), strings.TrimSpace(fileName))
}

func run(url string, fileName string) {
  for {
    response, _ := getResponse(nil, url)

    if response == nil {
      time.Sleep(5000 * time.Millisecond)
      continue
    }

    logToConsole(CONNECTED_STATUS, "waiting for data ...")
    read(response, fileName)

    response.Body.Close()
  }
}

func getResponse(body io.Reader, url string) (*http.Response, error) {
  request, requestErr := http.NewRequest(http.MethodGet, url, body)
  if requestErr != nil {
    panic(fmt.Sprintf("Error occurred creating new request: %s", requestErr))
  }
  request.Header.Add("Accept", "text/event-stream")

  httpClient := http.Client{}

  response, err := httpClient.Do(request)
  if err != nil {
    logToConsole(DISCONNECTED_STATUS, fmt.Sprintf("error occurred connecting to %s: %s", url, err))
    return nil, err
  }
  if response.StatusCode != http.StatusOK {
    panic(fmt.Sprintf("Expected a %d status code; got a %d", http.StatusOK, response.StatusCode))
  }
  return response, err
}

func read(response *http.Response, fileName string) {
  handleHeartbeat(response)

  dataChannel := make(chan string)
  cancelChannel := make(chan struct{})
  go func() {
    for {
      select {
      case data := <-dataChannel:
        {
          dataHandler(fileName, data, response)
        }
      case <-cancelChannel:
        return
      }
    }
  }()

  defer close(cancelChannel)

  reader := bufio.NewReader(response.Body)
  for {
    data, err := reader.ReadString('\n')
    if err != nil && err != io.EOF {
      fmt.Fprintf(os.Stderr, "Error reading response: %s\n", err)
      break
    }

    dataChannel <- data
  }
}

func dataHandler(fileName string, data string, response *http.Response) {
  if data == "\n" {
    return
  }

  if data == ":\n" {
    logToConsole(CONNECTED_STATUS, "server heartbeat received")
    handleHeartbeat(response)
  }

  if strings.HasPrefix(data, "data:") {
    logToConsole(CONNECTED_STATUS, "data received, updating "+fileName)
    writeToFile(fileName, strings.TrimSpace(data[6:]))
  }
}

func handleHeartbeat(response *http.Response) {
  if timer != nil {
    timer.Stop()
  }
  timer = time.NewTimer(30 * time.Second)
  go func() {
    <-timer.C
    logToConsole(DISCONNECTED_STATUS, "no heartbeat received in 30 seconds; reconnecting...")
    response.Body.Close()
  }()
  return
}

func writeToFile(filename string, data string) {
  file, err := os.Create(filename)
  if err != nil {
    fmt.Fprintf(os.Stderr, "Error creating file: %s\n", err)
  }

  defer file.Close()

  _, err = io.WriteString(file, data)
  if err != nil {
    fmt.Fprintf(os.Stderr, "Error writing to file: %s\n", err)
  }

  file.Sync()
}

func logToConsole(status string, value string) {
  dateTime := time.Now().Format("2006.01.02 15:04:05")

  fmt.Printf("\r%s [%s] %s", status, dateTime, value)
}

Example URI

GET /broadcast/v1/stats/event-stream?schedule_id=&format=&include_player_season=&test_pattern=&stats_level=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

format
string (optional) 

indicates the response format; values are json or xml; if no value is given the default format is json

include_player_season
string (optional) 

indicates to include the season_stats node for each player; example usage include_player_season=2021-22

test_pattern
boolean (optional) 

when set to true will return a zero’ed stats file as done in the test pattern endpoint for games that have not yet started (SCHEDULED); once the game starts the file will be replaced with the actual live game; defaults to false

stats_level
string (optional) 

when set will return only the specific stats level; possible values are game_stats, half_1_stats, half_2_stats, quarter_1_stats, quarter_2_stats, quarter_3_stats, quarter_4_stats, ot_1_stats; example stats_level=game_stats to return only the game totaled stats

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: text/event-stream
Body
See "Game Stats JSON Format"

Game Stats

Game Stats
GET/broadcast/v1/stats{?schedule_id,format,include_player_season,test_pattern,stats_level,apikey}

This endpoint returns the latest updated stats for an active or completed game. To receive realtime stats, as they happen, consumers should use the Full Game Stats SSE. See the Full Game Stats JSON Format for a complete description of each field.

Example URI

GET /broadcast/v1/stats?schedule_id=&format=&include_player_season=&test_pattern=&stats_level=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

format
string (optional) 

indicates the response format; values are json or xml; if no value is given the default format is json

include_player_season
string (optional) 

indicates to include the season_stats node for each player; example usage include_player_season=2021-22

test_pattern
boolean (optional) 

when set to true will return a zero’ed stats file as done in the test pattern endpoint for games that have not yet started (SCHEDULED); this parameter has no effect for active or completed games; defaults to false

stats_level
string (optional) 

when set will return only the specific stats level; possible values are game_stats, half_1_stats, half_2_stats, quarter_1_stats, quarter_2_stats, quarter_3_stats, quarter_4_stats, ot_1_stats; example stats_level=game_stats to return only the game totaled stats

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
See "Game Stats JSON Format"

Events

Live Game Events SSE

Live Game Events SSE
GET/broadcast/v1/events/logger-stream{?schedule_id,apikey}

Opens a Server Sent Events (SSE) connection that will remain open as long as the connection persists. This endpoint will push updated live game events to the consumer as they occur. The schedule_id from the Schedule endpoint is required. If the connection drops during the game, after reconnecting, all of the existing game events will be pushed. See Cloud Events for the format of each event type.

Note: This endpoint only works with active or upcoming scheduled games. Once the game is completed this endpoint will no longer provide live events and will return a 404.

Example URI

GET /broadcast/v1/events/logger-stream?schedule_id=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: text/event-stream
Body
{
  "state": "SAVED",  // possible values are SAVED, UPDATED or DELETED and represents the change to the attributes
  "type": "GENERATED",
  "event": {
    "eventId": "bc1b6e09-3a44-11e6-857c-06a15c73f3c3",
    "sessionId": "aa1b6e01-3a44-11e6-857c-06a15c73f3c3",
    "gameId": "ce1b6e06-3a44-11e6-857c-06a15c73f3c3",
    "eventType": "...",    // see event type description chart for values
    "timestamp": 123456789,
    "attributes": {
      "data": ...    // values will vary; see event type description chart for data details
    }
  }
}

Game Events

Game Events
GET/broadcast/v1/events{?schedule_id,apikey}

This endpoint returns the latest updated events for an active or completed game. To receive realtime events, as they happen, consumers should use the Live Game Events SSE. See Cloud Events for the format of each event type.

Example URI

GET /broadcast/v1/events?schedule_id=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: text/event-stream
Body
{
  "events": [
    {
      "state": "SAVED",  // possible values are SAVED, UPDATED or DELETED and represents the change to the attributes
      "type": "GENERATED",
      "event": {
        "eventId": "bc1b6e09-3a44-11e6-857c-06a15c73f3c3",
        "sessionId": "aa1b6e01-3a44-11e6-857c-06a15c73f3c3",
        "gameId": "ce1b6e06-3a44-11e6-857c-06a15c73f3c3",
        "eventType": "...",    // see event type description chart for values
        "timestamp": 123456789,
        "attributes": {
          "data": ...    // values will vary; see event type description chart for data details
        }
      }
    }
  ]
}

Locations

Live Game Locations SSE

Live Game Locations SSE
GET/broadcast/v1/locations-stream{?schedule_id,apikey}

Opens a Server Sent Events (SSE) connection that will remain open as long as the connection persists. This endpoint will push live game (low sample rate 2hz) locations to the consumer. The schedule_id from the Schedule endpoint is required. If the connection drops during the game, after reconnecting, only new locations will be received.

Note: This endpoint only works with active or upcoming scheduled games. Once the game is completed this endpoint will no longer provide live events and will return a 404.

Example URI

GET /broadcast/v1/locations-stream?schedule_id=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: text/event-stream
Body
{
  "type":"data",
  "source":"location",
  "data": {
    "gcms": 925000,  // "15:25:00"
    "scms": 9000,   // "09:00"
    "cr": true,
    "period": "H1",
    "facilityId": "cd530020-9f63-4ae1-a9d6-8946a79057af",
    "courtId": "ab530020-9f63-4ae1-a9d6-8946a79057af",
    "sessionId": "ef530020-9f63-4ae1-a9d6-8946a79057af",
    "locations": [
        {
            "t":1469741020607,
            "sid":"ef530020-9f63-4ae1-a9d6-8946a79057af",
            "type":"BALL",
            "bid":"99123456",
            "x":60,
            "y":30,
            "z":12
        },
        {
            "t":1469741020607,
            "sid":"ef530020-9f63-4ae1-a9d6-8946a79057af",
            "type":"PLAYER",
            "pid":52,
            "tid":461,
            "tag":"12345",
            "x":86,
            "y":89,
            "z":57
        },
        {
            "t":1469741020607,
            "sid":"ef530020-9f63-4ae1-a9d6-8946a79057af",
            "type":"OFFICIAL",
            "pid":91,
            "tid":461,
            "tag":"99191",
            "x":86,
            "y":89,
            "z":57
        }
    ]
  }
}

Game Locations

Game Locations
GET/broadcast/v1/locations{?id,from,to}

This endpoint will return game (low sample rate 2hz) locations to the consumer. For live 2hz locations use Live Game Events SSE. The timeframe of the request can not exceed 10 minutes.

Example URI

GET /broadcast/v1/locations?id=&from=&to=
URI Parameters
HideShow
id
string (required) 

Id of the session

from
number (required) 

The epoch timestamp (in milliseconds)

to
number (required) 

The epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
[
  {
    "locations": [
      {
        "x": 5785,
        "t": 163475794089,
        "z": 45,
        "type": "PLAYER",
        "sid": "649778d4-31db-11ec-942c-0242615ec82f",
        "y": 7930,
        "tag": "65575",
        "tid": 515,
        "speed": 0.238894,
        "pid": 6844
      }
    ]
  },
  {
    "locations": [
      {
        "x": 5785,
        "t": 163475794589,
        "z": 45,
        "type": "PLAYER",
        "sid": "649778d4-31db-11ec-942c-0242615ec82f",
        "y": 8000,
        "tag": "65575",
        "tid": 515,
        "speed": 0.238894,
        "pid": 6844
      }
    ]
  }
]
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "Locations must be requested in 30 min timeframes",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Locomotion

Metrics

Metrics
GET/broadcast/v1/locomotion{?schedule_id,team_id,apikey}

This endpoint returns player locomotion metrics for the game and the given team id.

Example URI

GET /broadcast/v1/locomotion?schedule_id=&team_id=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

team_id
number (required) 

ID of the team

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "metrics": [
    {
      "pid": "1",
      "tid": "461",
      "gid": "860e825e-38c2-11ea-9d3b-02422f8cbade",
      "metrics": {
        "DIST_TOTAL": 167.5,
        "DIST_SPRINT": 56.9,
        "DIST_JOG": 80.4,
        "DIST_WALK": 30.2,
        "DIST_SPRINT_COUNT": 3,
        "DIST_JOG_COUNT": 5,
        "DIST_WALK_COUNT": 8,
        "ACCEL_HIGH_COUNT": 3,
        "ACCEL_MED_COUNT": 2,
        "ACCEL_LOW_COUNT": 1,
        "DECEL_HIGH_COUNT": 3,
        "DECEL_MED_COUNT": 2,
        "DECEL_LOW_COUNT": 1,
        "VELOCITY_CURR_AVG": 10.2,
        "VELOCITY_TOP": 12.6
      }
    }
  ]
}

Live Locomotion Metrics SSE

Live Locomotion Metrics SSE
GET/broadcast/v1/locomotion/metric-stream{?schedule_id,apikey}

Opens a Server Sent Events (SSE) connection that will remain open as long as the connection persists. This endpoint will push updated live locomotion metrics to the consumer as they occur. The schedule_id is required. If the connection drops during the game, after reconnecting, the latest locomotion metrics file will be pushed.

Example connecting to the SSE endpoint using javascript:

var EventSource = require("eventsource");
var fs = require('fs');

const SCHEDULE_ID = '<schedule id>';
const API_KEY = '<your api key>';

var es = new EventSource(`https://api-shottracker.ddsports.com/broadcast/v1/locomotion/metric-stream?schedule_id=${SCHEDULE_ID}&apikey=${API_KEY}`);

var listener = function (event) {
    var type = event.type;
    if (type === 'message') {
        var data = event.data;
        console.log(data);

        fs.writeFile("./sse_data.json", data, function(err) {
            if(err) {
                return console.log(err);
            }

            console.log("The file was saved!");
        });
    }
};

es.addEventListener('open', listener);
es.addEventListener('message', listener);
es.addEventListener('error', listener);

Example connection to the SSE endpoint using golang:

package main

import (
  "bufio"
  "fmt"
  "io"
  "net/http"
  "os"
  "strings"
  "time"
)

const CONNECTED_STATUS = "CONNECTED"
const DISCONNECTED_STATUS = "DISCONNECTED"

var timer *time.Timer

func main() {
  reader := bufio.NewReader(os.Stdin)
  fmt.Println("ShotTracker SSE Download Utility")
  fmt.Println("--------------------------------")
  fmt.Println("Enter Event Stream URL")
  fmt.Print("> ")
  url, _ := reader.ReadString('\n')
  fmt.Println("Enter Output File Name")
  fmt.Print("> ")
  fileName, _ := reader.ReadString('\n')
  fmt.Println("================================")

  run(strings.TrimSpace(url), strings.TrimSpace(fileName))
}

func run(url string, fileName string) {
  for {
    response, _ := getResponse(nil, url)

    if response == nil {
      time.Sleep(5000 * time.Millisecond)
      continue
    }

    logToConsole(CONNECTED_STATUS, "waiting for data ...")
    read(response, fileName)

    response.Body.Close()
  }
}

func getResponse(body io.Reader, url string) (*http.Response, error) {
  request, requestErr := http.NewRequest(http.MethodGet, url, body)
  if requestErr != nil {
    panic(fmt.Sprintf("Error occurred creating new request: %s", requestErr))
  }
  request.Header.Add("Accept", "text/event-stream")

  httpClient := http.Client{}

  response, err := httpClient.Do(request)
  if err != nil {
    logToConsole(DISCONNECTED_STATUS, fmt.Sprintf("Error occurred connecting to %s: %s", url, err))
    return nil, err
  }
  if response.StatusCode != http.StatusOK {
    panic(fmt.Sprintf("Expected a %d status code; got a %d", http.StatusOK, response.StatusCode))
  }
  return response, err
}

func read(response *http.Response, fileName string) {
  handleHeartbeat(response)

  dataChannel := make(chan string)
  cancelChannel := make(chan struct{})
  go func() {
    for {
      select {
      case data := <-dataChannel:
        {
          dataHandler(fileName, data, response)
        }
      case <-cancelChannel:
        return
      }
    }
  }()

  defer close(cancelChannel)

  reader := bufio.NewReader(response.Body)
  for {
    data, err := reader.ReadString('\n')
    if err != nil && err != io.EOF {
      fmt.Fprintf(os.Stderr, "Error reading response: %s\n", err)
      break
    }

    dataChannel <- data
  }
}

func dataHandler(fileName string, data string, response *http.Response) {
  if data == "\n" {
    return
  }

  if data == ":\n" {
    logToConsole(CONNECTED_STATUS, "server heartbeat received")
    handleHeartbeat(response)
  }

  if strings.HasPrefix(data, "data:") {
    logToConsole(CONNECTED_STATUS, "data received, updating "+fileName)
    writeToFile(fileName, strings.TrimSpace(data[6:]))
  }
}

func handleHeartbeat(response *http.Response) {
  if timer != nil {
    timer.Stop()
  }
  timer = time.NewTimer(30 * time.Second)
  go func() {
    <-timer.C
    logToConsole(DISCONNECTED_STATUS, "no heartbeat received in 30 seconds; reconnecting...")
    response.Body.Close()
  }()
  return
}

func writeToFile(filename string, data string) {
  file, err := os.Create(filename)
  if err != nil {
    fmt.Fprintf(os.Stderr, "Error creating file: %s\n", err)
  }

  defer file.Close()

  _, err = io.WriteString(file, data)
  if err != nil {
    fmt.Fprintf(os.Stderr, "Error writing to file: %s\n", err)
  }

  file.Sync()
}

func logToConsole(status string, value string) {
  dateTime := time.Now().Format("2006.01.02 15:04:05")

  fmt.Printf("\r%s [%s] %s", status, dateTime, value)
}

Example URI

GET /broadcast/v1/locomotion/metric-stream?schedule_id=&apikey=
URI Parameters
HideShow
schedule_id
string (required) 

ID of the scheduled game

apikey
string (required) 

The authentication key

Response  200
HideShow
Headers
Content-Type: text/event-stream
Body
{
  "type": "data",
  "source": "locomotion",
  "data": {
    "t": 1663773345277,
    "sid": "4c298764-39bf-11ed-bbae-0242e9e2912e",
    "st": "FOOTBALL_GAME_QUARTER",
    "pid": 123,
    "tid": 515,
    "gid": "4bb6ef73-39bf-11ed-bbae-0242e9e2912e",
    "metrics": {
      "DIST_TOTAL": 167.5,
      "DIST_SPRINT": 56.9,
      "DIST_JOG": 80.4,
      "DIST_WALK": 30.2,
      "ACCEL_CURR_AVG": 2,
      "ACCEL_HIGH": 3,
      "ACCEL_MED": 2,
      "ACCEL_LOW": 1,
      "DECEL_HIGH": 3,
      "DECEL_MED": 2,
      "DECEL_LOW": 1,
      "VELOCITY_CURR_AVG": 10.2,
      "VELOCITY_TOP": 12.6
    }
  }
}

Utilities

Graphic metrics

Graphic metrics
POST/broadcast/v1/graphics/metrics{?apikey}

This endpoint accepts the graphic metrics in usage statistics purposes.

Example URI

POST /broadcast/v1/graphics/metrics?apikey=
URI Parameters
HideShow
apikey
string (required) 

The authentication key

Request
HideShow
Headers
Content-Type: application/json
Body
{
  "consumer_id": "4c298764-39bf-11ed-bbae-0242e9e2912e",
  "graphic_name": "Shot Chart",
  "team_id": "515",
  "stats": {
    "FG2": 3,
    "FGA2": 6,
    "FG2_RATE": 50,
    "FG3": 2,
    "FGA3": 5,
    "FG3_RATE": 40
  }
}
Response  204