The ShotTracker API gives consumers data needed to populate a box score and plot shot, player and ball locations in realtime. This data is published in 3 live data feeds, stats, shots, and locations.

Data Concepts

All realtime data emitted from the system will break down into 3 categories, stats, shots, and locations. With realtime data, at times, the data will be corrected which will emit adjusted the stats and shots. The categories below outline data aspects including corrections.

Stats

The system will emit all box score stats under the following abbreviations:

Stat Name Description
FGA field goal attempt
FG field goal
FGA3 3 point field goal attempt
FG3 3 point field goal
FTA free throw attempt
FT free throw
PTS points
AST assist
TO turnover
STL steal
REB rebound
OFFENSIVE_REB offensive rebound; typically paired with a REB to give more context
DEFENSIVE_REB defensive rebound; typically paired with a REB to give more context
DIST distance traveled in cm

In most cases, the stats will be paired together to represent the most current value(s) on the box score for the given player. Stats data will be paired together in single response; the example JSON snippet below represents a made field goal attempt:

“stats”:{“FGA”:11.0,“FG”:4.0,“PTS”:9.0}

The values in the above example reflect the most current stat values that would be reflective on the players box score.

Stats can also change with a manual correction. This means the example above would change to the following if the shot is deleted:

“stats”:{“FGA”:10.0,“FG”:3.0,“PTS”:7.0}

Both adding and deleting of the field goal looks the same in the paired together stats response. As a result a classification field is added to each stats response to give more context around what the collected stats values represent. The following are all of the classification values:

Classification Value Description
FREE_THROW_MISS Missed free throw
FREE_THROW_MAKE Made free throw
TWO_POINT_MISS Missed field goal
TWO_POINT_MAKE Made field goal
THREE_POINT_MISS Missed 3 point field goal
THREE_POINT_MAKE Made 3 point field goal
ASSIST Assist
TURNOVER Turnover
STEAL Steal
REBOUND Rebound
OFFENSIVE_REBOUND Offensive rebound
DEFENSIVE_REBOUND Defensive rebound
DISTANCE Distance traveled
DELETED_FREE_THROW_MISS Deleted missed free throw
DELETED_FREE_THROW_MAKE Deleted made free throw
UPDATED_FREE_THROW_MAKE_TO_MISS Updated free throw make to miss
UPDATED_FREE_THROW_MISS_TO_MAKE Updated free throw miss to make
DELETED_TWO_POINT_MISS Deleted missed field goal
DELETED_TWO_POINT_MAKE Deleted made field goal
UPDATED_TWO_POINT_MAKE_TO_MISS Updated field goal from make to miss
UPDATED_TWO_POINT_MISS_TO_MAKE Updated field goal from miss to make
DELETED_THREE_POINT_MISS Deleted missed 3 point field goal
DELETED_THREE_POINT_MAKE Deleted made 3 point field goal
UPDATED_THREE_POINT_MAKE_TO_MISS Updated 3 point field goal from make to miss
UPDATED_THREE_POINT_MISS_TO_MAKE Updated 3 point field goal from miss to make
DELETED_ASSIST Deleted assist
DELETED_TURNOVER Deleted turnover
DELETED_STEAL Deleted steal
DELETED_REBOUND Deleted rebound
DELETED_OFFENSIVE_REBOUND Deleted offensive rebound
DELETED_DEFENSIVE_REBOUND Deleted defensive rebound

Shots

Shots are location data for each made and missed shot including the ShotTracker zone. Shot data events contain a hoop_player_x and hoop_player_y that represents the xy location of the shot from the hoop. Representing a shot from the hoop assumes that the positive y runs from the hoop to the center of the court and positive x runs from the hoop to the right.

Note: All xy data is returned as mm.

Locations

The location data contains plotable xyz data for each player and ball on the court.

Note: All xyz data is returned as mm.

API Call Order

It is important to understand that the api implies a call order, the discovery of live data to the point that application attaches to the live realtime data. Below is the api call order that all client application should consider to ensure that all meta data is obtained and if joining an existing live event the client application can obtain past stats and shots.

Authentication

Authenticate, when using the API, by signing each request with the ShotTracker issued username and secret. A ShotTracker API username/secret pair contains specific privileges; be sure to keep both secured.

Signing a request is done using HMAC. The following headers are needed for signing and required to be sent with each request.

Header Name Description
date Standard UTC date; be sure to keep the current time as the clock must not skew more than 5 minutes
host The servers host
Authorization The full hmac value with signature; see example below

Below is a nodejs example illustrating the data required and how to formulate the data into the signing stream.

var crypto = require("crypto");

var userName = 'ShotTracker supplied user name here';
var secret = 'ShotTracker supplied secret here';
var host = 'devapi.shottracker.com';
var path = '/v1/data/live/_search';
var method = 'GET';
var date = new Date().toUTCString();

var requestLine = method + ' ' + path + ' HTTP/1.1';
var stringToSign = 'date: ' + date.trim() + '\n'
                 + 'host: ' + host + '\n'
                 + requestLine;
var encodedSignature = crypto.createHmac("sha1", secret).update(stringToSign).digest("base64");
var hmacAuth = 'hmac username="' + userName + '",algorithm="hmac-sha1",headers="date host request-line",signature="' + encodedSignature + '"';

console.log('date: ' + date);
console.log('Authorization: ' + hmacAuth);

Note Only the API (REST Resources) require the ShotTracker username/secret signed request. The live websocket only requires the time based token obtained during the subscription request.

Live Discovery

The following services allow a consumer to discover an existing live event and obtain the needed meta-data about the team and players. If the event is in the middle of a practice or game the consumer can request all existing stats and shots. Consumers can also request information about the court to aid in the handling of plotting locations and shots.

Get Live Information

Get Live Information
GET/v1/data/live/{live_id}

Example URI

GET /v1/data/live/live_id
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 461,
      "name": "TeamAppTeam",
      "live": {
        "started_at": 1484940405508,
        "id": "6141681d-df46-11e6-a818-f20e96351dc1",
        "type": "SHOOTING",
        "name": "flex test",
        "facility_name": "ShotTracker Lab",
        "court_name": "Main Court",
        "location_id": "/114118d4-2e50-11e6-b4a4-deecc6e6f111/9e4118d4-2e50-11e6-b4a4-deecc6e6f112",
        "is_practice_event": true,
        "is_game_event": false,
        "event": {
          "started_at": 1484940405508,
          "id": "56141681d-df46-11e6-a818-f20e96351dc1",
          "name": "Adhoc Practice"
        }
      }
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Request Subscription Token

Request Subscription Token
GET/v1/data/live/{live_id}/_subscribe{?dt}

Example URI

GET /v1/data/live/live_id/_subscribe?dt=
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

dt
string (optional) 

Subscribe to a specific data type. More than one data type can be passed using the &dt= notation. Possible values for this field are STATS, SHOTS, or LOCATIONS.

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "token": "6141681d-df46-11e6-a818-f20e96351dc1",
  "token_data_types": [
    "STATS",
    "SHOTS",
    "LOCATIONS"
  ],
  "teams": [
    {
      "id": 461,
      "name": "TeamAppTeam",
      "players": [
        {
          "id": 123,
          "first_name": "John",
          "last_name": "Doe",
          "jersey_number": 1,
          "position": "center",
          "profile_image_link": "<image link>"
        }
      ]
    }
  ],
  "_stats": "https://api.shottracker.com/v1/data/live/6141681d-df46-11e6-a818-f20e96351dc1/stats",
  "_stats_details": "https://api.shottracker.com/v1/data/live/6141681d-df46-11e6-a818-f20e96351dc1/stats/details",
  "_shots": "https://api.shottracker.com/v1/data/live/6141681d-df46-11e6-a818-f20e96351dc1/shots",
  "event_completed_results": [
    {
      "id": "a59e3734-101f-11e8-be3e-0242286dfad2",
      "type": "GAME_ROUND",
      "name": null,
      "_stats": "http://api.shottracker.com/v1/data/live/a59e3734-101f-11e8-be3e-0242286dfad2/stats",
      "_stats_details": "http://api.shottracker.com/v1/data/live/a59e3734-101f-11e8-be3e-0242286dfad2/stats/details",
      "_shots": "http://api.shottracker.com/v1/data/live/a59e3734-101f-11e8-be3e-0242286dfad2/shots"
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to LOCATIONS|STATS|SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Request Court Points

Request Court Points
GET/v1/data/live/{live_id}/court

Example URI

GET /v1/data/live/live_id/court
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "xne": 0,
  "yne": 0,
  "xse": 2,
  "yse": 2,
  "xsw": 4,
  "ysw": 4,
  "xnw": 6,
  "ynw": 6,
  "hoops": [
    {
      "x": 0,
      "y": 0,
      "z": 13
    },
    {
      "x": 10,
      "y": 10,
      "z": 23
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Current Live Stats

Current Live Stats
GET/v1/data/live/{live_id}/stats

Example URI

GET /v1/data/live/live_id/stats
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 461,
      "player_stats": [
        {
          "id": 123,
          "player_details": {
            "id": 123,
            "firstname": "John",
            "lastname": "Doe",
            "profile_image_link": "<image link>"
          },
          "version": 1,
          "stats": {
            "FG": 1,
            "FGA": 2,
            "PTS": 2
          }
        }
      ]
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Current Live Stats Details

Current Live Stats Details
GET/v1/data/live/{live_id}/stats/details

Example URI

GET /v1/data/live/live_id/stats/details
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 461,
      "player_stats": [
        {
          "id": 123,
          "player_details": {
            "id": 123,
            "firstname": "John",
            "lastname": "Doe",
            "profile_image_link": "<image link>"
          },
          "stats": {
            "FGA": [
              {
                "occurred_at": 123456789,
                "value": 1
              },
              {
                "occurred_at": 234567890,
                "value": 1
              }
            ],
            "FG": [
              {
                "occurred_at": 123456789,
                "value": 1
              }
            ],
            "PTS": [
              {
                "occurred_at": 123456789,
                "value": 2
              }
            ]
          }
        }
      ]
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Current Live Shots

Current Live Shots
GET/v1/data/live/{live_id}/shots

Example URI

GET /v1/data/live/live_id/shots
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 461,
      "player_shots": [
        {
          "id": 123,
          "player_details": {
            "id": 123,
            "firstname": "John",
            "lastname": "Doe",
            "profile_image_link": "<image link>"
          },
          "shots": [
            {
              "occurred_at": 123456789,
              "is_make": true,
              "is_3point": true,
              "zone": 1,
              "hoop_player_x": 12,
              "hoop_player_y": 3,
              "status": "RECORDED"
            }
          ]
        }
      ]
    }
  ]
}
Response  400
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 400,
  "message": "The live id is no longer active",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  404
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 404,
  "message": "Invalid id",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Live Notify

A live notify allows a service to be invoked when a practice drill or game is started. This eliminates the need to poll the search resource for new live events. When a notify url is registered the service will be called with the following query parameters:

PUT https://{url}?notify_id={registered notify id}&action=LIVE&data={live id}&state=[START|END]

The notification state indicates either the START or END of a practice drill or game half, quarter, etc… When a notification is created end notifications are disabled by default. Use the enable or disable endpoints to toggle notifications for the end notification state.

List LIVE Notifies

List LIVE Notifies
GET/v1/data/live/notify

Example URI

GET /v1/data/live/notify
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "notifications": [
    {
      "id": "abc-123",
      "action": "LIVE",
      "url": "http://localhost",
      "end_notification": false
    }
  ]
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Create LIVE Notify

Create LIVE Notify
PUT/v1/data/live/notify{?url}

Example URI

PUT /v1/data/live/notify?url=
URI Parameters
HideShow
url
string (required) 

Consumer provided url that will be called with the notification

Response  204
HideShow
Headers
X-ShotTracker-Notify-Id: <Live notify_id>
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Update LIVE Notify URL

Update LIVE Notify URL
PUT/v1/data/live/notify/{notify_id}{?url}

Example URI

PUT /v1/data/live/notify/notify_id?url=
URI Parameters
HideShow
notify_id
string (required) 

Specific id for the notify to update

url
string (required) 

New consumer provided url that will be called with the notification

Response  204
Response  422
HideShow
Body
{
  "status": 422,
  "message": "Notify id not found",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Enable LIVE End Notify

Enable LIVE End Notify
PUT/v1/data/live/notify/{notify_id}/_enableEndNotify

Example URI

PUT /v1/data/live/notify/notify_id/_enableEndNotify
URI Parameters
HideShow
notify_id
string (required) 

Specific id for the notify to update

Response  204
Response  422
HideShow
Body
{
  "status": 422,
  "message": "Notify id not found",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Disable LIVE End Notify

Disable LIVE End Notify
PUT/v1/data/live/notify/{notify_id}/_disableEndNotify

Example URI

PUT /v1/data/live/notify/notify_id/_disableEndNotify
URI Parameters
HideShow
notify_id
string (required) 

Specific id for the notify to update

Response  204
Response  422
HideShow
Body
{
  "status": 422,
  "message": "Notify id not found",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Delete LIVE Notify

Delete LIVE Notify
DELETE/v1/data/live/notify/{notify_id}

Example URI

DELETE /v1/data/live/notify/notify_id
URI Parameters
HideShow
notify_id
string (required) 

Specific id for the notify to update

Response  204
Response  422
HideShow
Body
{
  "status": 422,
  "message": "Notify id not found",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Live Realtime

All live data is delivered over a websocket (ws://live.shottracker.com). A websocket is a long lived connection between the realtime server and the client application. Before attaching to the websocket a client must request a subscription token.

Important: Tokens are only one time use. If a token is used to attach to a live session a new token is needed to reattach.

Example Connection Request

ws://live.shottracker.com?token=6141681d-df46-11e6-a818-f20e96351dc1

Example Connection Response

  • Ack Response (application/json)

    {"data":{"socketSessionId":"2edbccd1","serverAttributes":{"maxInputBufferSizeInBytes":8192,"connectionTimeoutInMs":120000}},"action":"subscribe","type":"ack"}

Keep Alives

The Ack response indicates how long the connection will stay open before timing out when no data is traveling over the connection (connectionTimeoutInMs). Clients should send a ping request to ensure the connection stays open when no data is received. The server will send back a corresponding pong response.

  • Ping Request (application/json)

    {"action":"ping"}
  • Pong Response (application/json)

    {"type":"pong"}

Data Type Responses

  • Stats Response (application/json)

    {"type":"stats","data":{"occurred_at":1484865816836,"team_id":461,"player_id":123,"stats":{"FGA":4.0,"PTS":4.0,"FG":2.0},"classification":"TWO_POINT_MAKE","version":317}}
  • Shots Response (application/json)

    {"type":"shot","data":{"occurred_at":1484865816836,"team_id":461,"player_id":123,"is_make":true,"is_3point":true,"zone":1,"hoop_player_x":12,"hoop_player_y":3,"status":"RECORDED"}}
  • Location Response (application/json)

    {"type":"location","data":{"occurred_at":1478800197342,"type":"PLAYER","id":123,"x":123,"y":456,"z":789}}

Marker Type Responses

Marker data is emitted to consumers to know when play starts and ends for a given game or practice.

Game Markers

  • Start Play Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197300,"type":"PLAY_START"}}
  • End of First Half Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197333,"type":"END_FIRST_HALF"}}
  • Play Next Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197339,"live_id":"a1140480-e1d5-4684-a619-402984b5c9ba","type":"PLAY_NEXT"}}
  • Start of Second Half Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197366,"type":"START_SECOND_HALF"}}
  • End Play Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197400,"type":"PLAY_END"}}

Practice Markers

  • Drill Start Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197300,"type":"DRILL_START"}}
  • Drill End Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197333,"type":"DRILL_END"}}
  • Drill Next Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197339,"live_id":"a1e80480-e1d5-4684-a619-402984b5c9ba","type":"DRILL_NEXT"}}
  • Practice End Marker Response (application/json)

    {"type":"marker","data":{"occurred_at":1478800197400,"type":"PRACTICE_END"}}

Live Video Indexing

Video providers can index video with ShotTracker live events. A provider must supply a unique identifier for the video and the exact epoch UTC timestamp when the video was started. For full integration, the provider must be a registered as a video provider so that it is known how ShotTracker can call back to get the video.

Video Recording

Video Recording
PUT/v1/data/live/{live_id}/video{?id,started_at}

Example URI

PUT /v1/data/live/live_id/video?id=&started_at=
URI Parameters
HideShow
live_id
string (required) 

ID of the live session

id
string (required) 

The consumer supplied id representing a video recording. Max size is 255 bytes.

started_at
number (optional) 

The exact epoch timestamp (in milliseconds) the video recording was started. If not provided it is assumed the video starts at the time of the call.

Response  204

Locations

List Locations

List Locations
GET/v1/data/locations

Example URI

GET /v1/data/locations
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "locations": [
    {
      "facility_name": "Test Facility",
      "court_name": "Test Facility Main Court",
      "location_id": "/114118d4-2e50-11e6-b4a4-deecc6e6f111/9e4118d4-2e50-11e6-b4a4-deecc6e6f112"
    }
  ]
}

List Nearest Locations

List Nearest Locations
GET/v1/data/locations/nearest/latlong/{latitude}/{longitude}{?radius,unit}

Example URI

GET /v1/data/locations/nearest/latlong/latitude/longitude?radius=&unit=
URI Parameters
HideShow
latitude
number (required) 

Callers current latitude

longitude
number (required) 

Callers current longitude

radius
number (required) 

The radius to include facilities

unit
string (required) 

The unit of measure; either MILES or KILOMETERS

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "locations": [
    {
      "facility_name": "Joes Gym",
      "court_name": "main court",
      "location_id": "/114118d4-2e50-11e6-b4a4-deecc6e6f112/9e4118d4-2e50-11e6-b4a4-deecc6e6f122",
      "distance": {
        "unit": "MILES",
        "value": 11.76
      }
    }
  ]
}

User Services

All user services require a user access token. This token is obtained using an oAuth2 Implicit Flow.

User Profile

User Profile
GET/v1/data/user/profile

Example URI

GET /v1/data/user/profile
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 123,
  "first_name": "User First Name",
  "last_name": "User Last Name",
  "email": "user@shottracker.com"
}

Team Events

List Teams

List Teams
GET/v1/data/teams

Example URI

GET /v1/data/teams
Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "teams": [
    {
      "id": 46,
      "name": "Test Team"
    }
  ]
}

Search Team Events

Search Team Events
GET/v1/data/teams/{team_id}/events{?from,to}

Example URI

GET /v1/data/teams/team_id/events?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "events": [
    {
      "id": "cf3ba789-06c4-11e8-bb65-0242286dfad2",
      "name": "TeamAppTeam vs TestTeamAlpha",
      "results": [
        {
          "id": "cf56d0aa-06c4-11e8-bb65-0242286dfad2",
          "name": null,
          "type": "GAME_ROUND",
          "started_at": 1517430299810,
          "ended_at": 1517431728868,
          "_stats": "https://api.shottracker.com/v1/data/live/cf56d0aa-06c4-11e8-bb65-0242286dfad2/stats",
          "_stats_details": "https://api.shottracker.com/v1/data/live/cf56d0aa-06c4-11e8-bb65-0242286dfad2/stats/details",
          "_shots": "https://api.shottracker.com/v1/data/live/cf56d0aa-06c4-11e8-bb65-0242286dfad2/shots"
        },
        {
          "id": "23d3344b-06c8-11e8-bb65-0242286dfad2",
          "name": null,
          "type": "GAME_ROUND",
          "started_at": 1517431730064,
          "ended_at": 1517431732978,
          "_stats": "https://api.shottracker.com/v1/data/live/23d3344b-06c8-11e8-bb65-0242286dfad2/stats",
          "_stats_details": "https://api.shottracker.com/v1/data/live/23d3344b-06c8-11e8-bb65-0242286dfad2/stats/details",
          "_shots": "https://api.shottracker.com/v1/data/live/23d3344b-06c8-11e8-bb65-0242286dfad2/shots"
        }
      ],
      "is_practice_event": false,
      "is_game_event": true,
      "started_at": 1517430299810,
      "ended_at": 1517431732978
    }
  ]
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Stats/Shots

Team Practice Stats

Team Practice Stats
GET/v1/data/teams/{team_id}/players/practice/stats{?from,to}

A practice can consist of a team practice with shooting and scrimmage drills or a players individual workout. This endpoint will return team players stats that include both team practice drills (shooting and scrimmage) and workouts.

Example URI

GET /v1/data/teams/team_id/players/practice/stats?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_stats": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "version": 1,
      "stats": {
        "FG": 1,
        "FGA": 2,
        "PTS": 2
      }
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Practice Scrimmage Stats

Team Practice Scrimmage Stats
GET/v1/data/teams/{team_id}/players/practice/scrimmage/stats{?from,to}

Example URI

GET /v1/data/teams/team_id/players/practice/scrimmage/stats?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_stats": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "version": 1,
      "stats": {
        "FG": 1,
        "FGA": 2,
        "PTS": 2
      }
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Practice Shooting Drill Stats

Team Practice Shooting Drill Stats
GET/v1/data/teams/{team_id}/players/practice/shooting/stats{?from,to}

Example URI

GET /v1/data/teams/team_id/players/practice/shooting/stats?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_stats": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "version": 1,
      "stats": {
        "FG": 1,
        "FGA": 2,
        "PTS": 2
      }
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Game Stats

Team Game Stats
GET/v1/data/teams/{team_id}/players/game/stats{?from,to}

Example URI

GET /v1/data/teams/team_id/players/game/stats?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_stats": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "version": 1,
      "stats": {
        "FG": 1,
        "FGA": 2,
        "PTS": 2
      }
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to STATS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Practice Shots

Team Practice Shots
GET/v1/data/teams/{team_id}/players/practice/shots{?from,to}

Example URI

GET /v1/data/teams/team_id/players/practice/shots?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_shots": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "shots": [
        {
          "occurred_at": 123456789,
          "is_make": true,
          "is_3point": true,
          "zone": 1,
          "hoop_player_x": 12,
          "hoop_player_y": 3,
          "status": "RECORDED"
        }
      ]
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Practice Scrimmage Shots

Team Practice Scrimmage Shots
GET/v1/data/teams/{team_id}/players/practice/scrimmage/shots{?from,to}

Example URI

GET /v1/data/teams/team_id/players/practice/scrimmage/shots?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_shots": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "shots": [
        {
          "occurred_at": 123456789,
          "is_make": true,
          "is_3point": true,
          "zone": 1,
          "hoop_player_x": 12,
          "hoop_player_y": 3,
          "status": "RECORDED"
        }
      ]
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Practice Shooting Drill Shots

Team Practice Shooting Drill Shots
GET/v1/data/teams/{team_id}/players/practice/shooting/shots{?from,to}

Example URI

GET /v1/data/teams/team_id/players/practice/shooting/shots?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_shots": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "shots": [
        {
          "occurred_at": 123456789,
          "is_make": true,
          "is_3point": true,
          "zone": 1,
          "hoop_player_x": 12,
          "hoop_player_y": 3,
          "status": "RECORDED"
        }
      ]
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Team Game Shots

Team Game Shots
GET/v1/data/teams/{team_id}/players/game/shots{?from,to}

Example URI

GET /v1/data/teams/team_id/players/game/shots?from=&to=
URI Parameters
HideShow
team_id
number (required) 

ID of the team

from
number (required) 

The starting epoch timestamp (in milliseconds)

to
number (required) 

The ending epoch timestamp (in milliseconds)

Response  200
HideShow
Headers
Content-Type: application/json
Body
{
  "id": 461,
  "player_shots": [
    {
      "id": 123,
      "player_details": {
        "id": 123,
        "firstname": "John",
        "lastname": "Doe",
        "profile_image_link": "<image link>"
      },
      "shots": [
        {
          "occurred_at": 123456789,
          "is_make": true,
          "is_3point": true,
          "zone": 1,
          "hoop_player_x": 12,
          "hoop_player_y": 3,
          "status": "RECORDED"
        }
      ]
    }
  ]
}
Response  403
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 403,
  "message": "No access to SHOTS data",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  422
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 422,
  "message": "Both from and to must be greater than 0 | from timestamp must be less than to timestamp | Request may not exceed more than 8 months",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}
Response  500
HideShow
Headers
Content-Type: application/json
Body
{
  "status": 500,
  "message": "<General System Error Message>",
  "shottrackerRequestId": "f1e80480-e1d5-4684-a619-402984b5c9ba"
}

Testing Lifecycle

Testing with live data can be tricky as it is unknown if logic works unless data is being received. We recommend first leveraging our Mock environment that simulates sending and receiving real time data. After working with the Mock environment the next step will be integrating with our Development environment, followed by Production.

Mock

When testing in a live environment live data is not always available. To test outside of a live session, mock services have been setup that emulate real live data. The endpoints in both mock services conform to the traditional live api and services.

The data feed in the live websocket is replayed in a continuous loop and represents a few minutes of live activity. The data will return a DRILL_END message followed by a DRILL_NEXT to represent moving from one drill to another in a practice.

The mock service does not expose the Live Notify endpoints directly. To simulate sending notifications from the mock service, the following endpoints may be used.

Start Notify

PUT http://mockapi.shottracker.com:8080/mock/{key}/do/live/notify/start?url={your notify url}

End Notify

PUT http://mockapi.shottracker.com:8080/mock/{key}/do/live/notify/end?url={your notify url}

Invoking this endpoint will make a call to the supplied url with the notify query string including notify_id, action, and data. Please contact ShotTracker to obtain the {key}.

The following username and secret is required to sign all requests to the “Security Required” mock service api only.

username: 2e4118d42e5011e6b4a4deecc6e6f587
secret: 2d64b892e8d434100001

Development

Production