GridTracker API Overview ¶
Locations XY Orientation
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:
-
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.
-
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 ¶
ScheduleGET/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
- 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
200
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 ColorsGET/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
- schedule_id
string
(required)ID of the scheduled game
- apikey
string
(required)The authentication key
200
Headers
Content-Type: application/json
Body
{
"teams": [
{
"id": 469,
"color": "00FF80"
},
{
"id": 470,
"color": "0080FF"
}
]
}
Teams ¶
List Teams ¶
List TeamsGET/broadcast/v1/games/teams{?apikey}
Returns all GridTracker teams.
Example URI
- apikey
string
(required)The authentication key
200
Headers
Content-Type: application/json
Body
{
"teams": [
{
"id": 461,
"name": "TestTeam"
},
{
"id": 493,
"name": "BWB"
}
]
}
Team Roster ¶
Team RosterGET/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 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
- team_id
number
(required)ID of the team
- game_event_id
string
(optional)ID of the game
- apikey
string
(required)The authentication key
200
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 TeamsGET/broadcast/v1/games/officials/teams{?apikey}
Returns all officials teams.
Example URI
- apikey
string
(required)The authentication key
200
Headers
Content-Type: application/json
Body
{
"teams": [
{
"id": 91,
"name": "Officials Team 1"
}
]
}
Officials Team And Members Attributes ¶
Officials Team And Members AttributesGET/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
- team_id
number
(required)ID of the team
- apikey
string
(required)The authentication key
200
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 ImagesGET/broadcast/v1/games/teams/{team_id}/images{?apikey}
Returns the team and player image links.
Example URI
- team_id
number
(required)ID of the team
- apikey
string
(required)The authentication key
200
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 StatsGET/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
- 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
200
Headers
Content-Type: application/json
Body
See "Game Stats JSON Format"
Live Game Stats SSE ¶
Live Game Stats SSEGET/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
- 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
200
Headers
Content-Type: text/event-stream
Body
See "Game Stats JSON Format"
Game Stats ¶
Game StatsGET/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
- 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
200
Headers
Content-Type: application/json
Body
See "Game Stats JSON Format"
Events ¶
Live Game Events SSE ¶
Live Game Events SSEGET/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
- schedule_id
string
(required)ID of the scheduled game
- apikey
string
(required)The authentication key
200
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 EventsGET/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
- schedule_id
string
(required)ID of the scheduled game
- apikey
string
(required)The authentication key
200
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 SSEGET/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
- schedule_id
string
(required)ID of the scheduled game
- apikey
string
(required)The authentication key
200
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 LocationsGET/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
- id
string
(required)Id of the session
- from
number
(required)The epoch timestamp (in milliseconds)
- to
number
(required)The epoch timestamp (in milliseconds)
200
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
}
]
}
]
400
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 ¶
MetricsGET/broadcast/v1/locomotion{?schedule_id,team_id,apikey}
This endpoint returns player locomotion metrics for the game and the given team id.
Example URI
- schedule_id
string
(required)ID of the scheduled game
- team_id
number
(required)ID of the team
- apikey
string
(required)The authentication key
200
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 SSEGET/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
- schedule_id
string
(required)ID of the scheduled game
- apikey
string
(required)The authentication key
200
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 metricsPOST/broadcast/v1/graphics/metrics{?apikey}
This endpoint accepts the graphic metrics in usage statistics purposes.
Example URI
- apikey
string
(required)The authentication key
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
}
}
204