The purpose of this guide is to show step-by-step how a piece of competition management software would make use of the warehouse API.
This guide will make use of a sample basketball league. This should be applicable to most sports. Only minimal/required information will be used for each API call. Please check the API Documentation to find out what other pieces of data are possible.
This example assumes that the league being used is leagueId = 1 and that the APIKey being used (TESTAPIKEY) has all the permissions required.
Describing the data warehouse
As all the API calls make use of the IDs for each entity/record it is important to manage these.
When a new record is created the warehouse system assigns the record a unique identifier, this identifier is used for subsequent API calls.
All API calls make use of the warehouse assigned unique number, however the majority of API calls also support an extra parameter useExternalForLeague
that allows the use of the league's own unique identifier in the API call instead of the warehouse assigned one (Check the documentation for the specific API call for more information).
Based on the requirement to know IDs and make it easier for the API calls, best to pass CREATES through in this order:
One of the ways to handle what communications need to happen to the warehouse is via a log table
As users update and write new records in competition software, a new log table will store all updated, deleted and inserted records.
When the user / system next talks to the warehouse, the code will work through these records in order calling the appropriate POST, PUT or DELETE api calls. (using a basic processlog methodology).
table: warehouse_log
id - autocounter table type (Team etc) action type (POST,PUT,DELETE) ID key (allow many fields for multi-key primary keys) dateRowCreated - date this row added. dateToWarehouse - store the date this row was sent to warehouse
The warehouse system will return from some apis a warehouse primary key.
There are 2 ways of storing this.
For PUT,DELETE calls to warehouse, will need to send this warehouse Id field up.
Note:If the useExternalForLeague
functionality is used then there may be no need to store this id as all operations will use your local id.
Instead of writing a new bulk feature as well as the row by row integration from above, for the bulk we'd suggest filling the warehouse_records table in the appropriate order and then stepping through it. There may be 100,000 rows (or whatever) but once your 'working log' works through send each of these POST/PUT/DELETE calls up you would have done all the bulk load, and without having to write a new module.
The warehouse does support a 'bulk' mode for a number of API calls that would be significantly faster than individual calls.
This example league contains only one competition that has 4 teams. The schedule for the competition is as follows.
Date/Time | Match Number | Round Number | Home Team | Away Team | Venue |
---|---|---|---|---|---|
26 April 2014 10am | 1 | 1 | Dragonfield | Northaven | Eastern Basketball Centre |
26 April 2014 1pm | 2 | 1 | Greenfield | Summerloch | Eastern Basketball Centre |
3 May 2014 10am | 3 | 2 | Dragonfield | Summerloch | Eastern Basketball Centre |
3 May 2014 | 4 | 2 | Greenfield | Bye | |
3 May 2014 | 5 | 2 | Northaven | Bye | |
10 May 2014 10am | 6 | 3 | Summerloch | Northaven | Eastern Basketball Centre |
10 May 2014 1pm | 7 | 3 | Greenfield | Dragonfield | Eastern Basketball Centre |
Grand Final | |||||
17 May 2014 1pm | 8 | 1 | Greenfield | Dragonfield | Eastern Basketball Centre |
{ "venueName" : "Eastern Basketball Centre", "status" : "ACTIVE", "latitude" : "-37.811784", "longitude" : "145.316557", "timezone" : "Australia/Melbourne", "countryCode" : "AU", "externalId" : "65" }Response
{ "venueId" : 1, "externalId" : "65" }
[ { "teamName" : "Dragonfield", "teamNickname" : "Dragons", "teamCode" : "DGN", "status" : "ACTIVE", "externalId" : "134" }, { "teamName" : "Northaven", "teamNickname" : "Bats", "teamCode" : "NHV", "status" : "ACTIVE", "externalId" : "135" }, { "teamName" : "Greenfield", "teamNickname" : "Rhinos", "teamCode" : "GFD", "status" : "ACTIVE", "externalId" : "136" }, { "teamName" : "Summerloch", "teamNickname" : "Falcons", "teamCode" : "SLC", "status" : "ACTIVE", "externalId" : "137" } ]Response
{ "teamId" : 1, "externalId" : "134" }, { "teamId" : 2, "externalId" : "135" }, { "teamId" : 3, "externalId" : "136" }, { "teamId" : 4, "externalId" : "137" }, { "teamId" : 5, "externalId" : "138" }
[ { "firstName" : "Roger", "familyName" : "Anderson", "nationality" : "AU", "gender" : "MALE", "externalId" : "134" }, { "firstName" : "William", "familyName" : "Jon", "nationality" : "AU", "gender" : "MALE", "externalId" : "136" }, { "firstName" : "Patrick", "familyName" : "Armstrong", "nationality" : "AU", "gender" : "MALE", "externalId" : "137" }, { "firstName" : "Andrew", "familyName" : "Hill", "nationality" : "AU", "gender" : "MALE", "externalId" : "138" }, { "firstName" : "Philip", "familyName" : "Hudsen", "nationality" : "AU", "gender" : "MALE", "externalId" : "139" } ]Response
{ "personId" : 1, "externalId" : "134" }, { "personId" : 2, "externalId" : "136" }, { "personId" : 3, "externalId" : "137" }, { "personId" : 4, "externalId" : "138" }, { "personId" : 5, "externalId" : "139" }
{ "competitionName" : "Test Competition", "competitionAbbrev" : "Test", "season" : "2014", "leagueId" : 1, "year" : "2014", "startDate" : "2014-04-25", "current" : 1, "gender" : "MALE", "ageGroup" : "SENIOR", "standard" : "TIER2", "competitorType" : "TEAM", "numberOfPeriods" : 4, "extraTime" : 1, "finalsPositions" : 2, "externalId" : "23" }Response
{ "competitionId" : 1, "externalId" : "23" }
[ { "competitionId" : 1, "personId" : 1, "playerTeamId" : 1, "shirtNumber" : "45", }, { "competitionId" : 1, "personId" : 2, "playerTeamId" : 1, "shirtNumber" : "22", }, { "competitionId" : 1, "personId" : 5, "playerTeamId" : 2, "shirtNumber" : "00", } ]Response
[ { "competitionId" : 1, "personId" : 1, "playerTeamId" : 1 }, { "competitionId" : 1, "personId" : 2, "playerTeamId" : 1 }, { "competitionId" : 1, "personId" : 5, "playerTeamId" : 2 } ]
[ { "matchNumber" : 1, "roundNumber" : 1, "matchStatus" : "SCHEDULED", "matchTime" : "2014-04-26 10:00:00", "externalId" : "3456", "matchType" : "REGULAR", "venueId" : 1, "liveStream" : 1, "competitors": [ { "teamId": 1, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" }, { "teamId": 2, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 2, "roundNumber" : 1, "matchStatus" : "SCHEDULED", "matchTime" : "2014-04-26 13:00:00", "externalId" : "3457", "matchType" : "REGULAR", "venueId" : 1, "liveStream" : 1, "competitors": [ { "teamId": 3, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" }, { "teamId": 4, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 3, "roundNumber" : 2, "matchStatus" : "SCHEDULED", "matchTime" : "2014-05-03 10:00:00", "externalId" : "3458", "matchType" : "REGULAR", "venueId" : 1, "liveStream" : 1, "competitors": [ { "teamId": 1, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" }, { "teamId": 4, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 4, "roundNumber" : 2, "matchStatus" : "BYE", "matchTime" : "2014-05-03 00:00:00", "externalId" : "3459", "matchType" : "REGULAR", "competitors": [ { "teamId": 3, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 5, "roundNumber" : 2, "matchStatus" : "BYE", "matchTime" : "2014-05-03 00:00:00", "externalId" : "3460", "matchType" : "REGULAR", "competitors": [ { "teamId": 3, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 6, "roundNumber" : 3, "matchStatus" : "SCHEDULED", "matchTime" : "2014-05-10 10:00:00", "externalId" : "3461", "matchType" : "REGULAR", "venueId" : 1, "liveStream" : 1, "competitors": [ { "teamId": 4, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" }, { "teamId": 2, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 7, "roundNumber" : 3, "matchStatus" : "SCHEDULED", "matchTime" : "2014-05-10 13:00:00", "externalId" : "3462", "matchType" : "REGULAR", "venueId" : 1, "liveStream" : 1, "competitors": [ { "teamId": 3, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE" }, { "teamId": 1, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE" } ] }, { "matchNumber" : 8, "roundNumber" : 1, "matchStatus" : "SCHEDULED", "matchTime" : "2014-05-17 13:00:00", "externalId" : "3463", "matchType" : "FINALS", "venueId" : 1, "liveStream" : 1, "matchName" : "Grand Final", "competitors": [ { "teamId": 3, "competitorType": "TEAM", "isHomeCompetitor": 1, "completionStatus": "NOT_COMPLETE", "placeIfWon" : 1, "placeIfLost" : 2 }, { "teamId": 1, "competitorType": "TEAM", "isHomeCompetitor": 0, "completionStatus": "NOT_COMPLETE", "placeIfWon" : 1, "placeIfLost" : 2 } ] } ]Response
{ "matchId" : 1, "streamKey" : "39Y34240J45R3234", "externalId" : "3456" }, { "matchId" : 2, "streamKey" : "RH982HKF9243JF9J", "externalId" : "3457" }, { "matchId" : 3, "streamKey" : "NNJ394HDJH87HDW2", "externalId" : "3458" }, { "matchId" : 4, "externalId" : "3459" }, { "matchId" : 5, "externalId" : "3460" }, { "matchId" : 6, "streamKey" : "RWU0945J04590J5I", "externalId" : "3461" }, { "matchId" : 7, "streamKey" : "V005695JH45925JU", "externalId" : "3462" }, { "matchId" : 8, "streamKey" : "348JH04J93J0U9U2", "externalId" : "3463" }
Players can be added to the match prior to the match starting, or once the match is completed
[ { "matchId" : "3", "teamId" : "1", "competitionId" : "1", "personId" : "1", "isPlayer" : 1, "shirtNumber" : "34" }, { "matchId" : "3", "teamId" : "1", "competitionId" : "1", "personId" : "2", "isPlayer" : 1, "shirtNumber" : "55" }, { "matchId" : "3", "teamId" : "1", "competitionId" : "1", "personId" : "3", "isPlayer" : 1, "shirtNumber" : "7" }, { "matchId" : "3", "teamId" : "1", "competitionId" : "1", "personId" : "4", "isPlayer" : 1, "shirtNumber" : "11" }, { "matchId" : "3", "teamId" : "1", "competitionId" : "1", "personId" : "5", "isPlayer" : 1, "shirtNumber" : "44" } ]
After the match is completed there are many different calls that need to be peformed to update all the data required.
The examples below happen display how to update the system at the end of round 2. It is assumed round 1 has already been updated
Note: If using a courtside capture device and the livestream API then then all the match completion steps are done automatically in the warehouse. The competition management software is not required to do anything. The competition management software can get the saved/generated data using GET API calls.
The score for matchId = 3 is below
Team | Period 1 | Period 2 | Period 3 | Period 4 | Final Score | Result Placing |
---|---|---|---|---|---|---|
Dragonfield | 10 | 11 | 12 | 12 | 45 | 1 |
Summerloch | 8 | 9 | 11 | 10 | 38 | 2 |
The score for Roger Anderson (personId = 1) in matchId = 3 is below
Roger was in the starting 5 for the match, played in shirt number #34 and played FORWARD for the entire match
Period | Minutes | Field Goals Attempted | Field Goals Made | Free Throws Attempted | Free Throws Made | Points |
---|---|---|---|---|---|---|
1 | 2.5 | 1 | 1 | 0 | 0 | 2 |
2 | 7.5 | 0 | 0 | 2 | 1 | 1 |
3 | 0 | 0 | 0 | 0 | 0 | 0 |
4 | 3 | 4 | 3 | 0 | 0 | 6 |
0 (TOTALS) | 13 | 5 | 4 | 2 | 1 | 2 |
{ "matchStatus" : "COMPLETE", "timeActual" : "2014-05-03 10:01:34", "timeEndActual" : "2014-05-03 10:51:31", "competitors": [ { "teamId": 1, "scoreString" : "45", "resultPlacing" : 1, "completionStatus": "COMPLETE" }, { "teamId": 4, "scoreString" : "38", "resultPlacing" : 2, "completionStatus": "COMPLETE" } ] }
{ "competitors": [ { "teamId": 3, "resultPlacing" : 1, "completionStatus": "COMPLETE" } ] }
{ "competitors": [ { "teamId": 3, "resultPlacing" : 1, "completionStatus": "COMPLETE" } ] }
[ { "matchId" : "3", "teamId" : "1", "periodNumber" : "1", "periodType" : "REGULAR", "sPoints" : "10", }, { "matchId" : "3", "teamId" : "1", "periodNumber" : "2", "periodType" : "REGULAR", "sPoints" : "11", }, { "matchId" : "3", "teamId" : "1", "periodNumber" : "3", "periodType" : "REGULAR", "sPoints" : "12", }, { "matchId" : "3", "teamId" : "1", "periodNumber" : "4", "periodType" : "REGULAR", "sPoints" : "12", }, { "matchId" : "3", "teamId" : "1", "periodNumber" : "0", "periodType" : "REGULAR", "sPoints" : "45", } ]
[ { "matchId" : "3", "teamId" : "1", "personId" : "1", "periodNumber" : "1", "periodType" : "REGULAR", "sPoints" : "2", "sFieldGoalsAttempted" : "1", "sFieldGoalsMade" : "1", "sAssists" : "0", "sMinutes" : "2.5", "isStarter" : "1", "participated" : "1", "shirtNumber" : "34", "playingPosition" : "FORWARD" }, { "matchId" : "3", "teamId" : "1", "personId" : "1", "periodNumber" : "2", "periodType" : "REGULAR", "sPoints" : "1", "sFreeThrowsAttempted" : "2", "sFreeThrowsMade" : "2", "sMinutes" : "7.5", "isStarter" : "1", "participated" : "1", "shirtNumber" : "34", "playingPosition" : "FORWARD" }, { "matchId" : "3", "teamId" : "1", "personId" : "1", "periodNumber" : "3", "periodType" : "REGULAR", "isStarter" : "1", "participated" : "1", "shirtNumber" : "34", "playingPosition" : "FORWARD" }, { "matchId" : "3", "teamId" : "1", "personId" : "1", "periodNumber" : "4", "periodType" : "REGULAR", "sPoints" : "6", "sFieldGoalsAttempted" : "4", "sFieldGoalsMade" : "3", "sMinutes" : "3", "isStarter" : "1", "participated" : "1", "shirtNumber" : "34", "playingPosition" : "FORWARD" }, { "matchId" : "3", "teamId" : "1", "personId" : "1", "periodNumber" : "0", "periodType" : "REGULAR", "sPoints" : "9", "sFieldGoalsAttempted" : "5", "sFieldGoalsMade" : "4", "sMinutes" : "13", "isStarter" : "1", "participated" : "1", "shirtNumber" : "34", "playingPosition" : "FORWARD", "sFreeThrowsAttempted" : "2", "sFreeThrowsMade" : "2" } ]
In order to trigger the match to be included and run into Competition statistics, the following call needs to be made. This can be done in bulk with many matches included.
{ "competitionId" : "1", "matchId" : "3" }
Team | Position | Games Played | Round Number | Won | Lost | Byes | Points For |
---|---|---|---|---|---|---|---|
Dragonfield | 1 | 2 | 2 | 1 | 1 | 0 | 90 |
Greenfield | 2 | 2 | 2 | 1 | 0 | 1 | 88 |
Summerloch | 3 | 2 | 2 | 0 | 2 | 1 | 80 |
[ { "teamId" : "1", "position" : "1", "roundNumber" : "2", "played" : "2", "won" : "2", "lost" : "1", "byes" : "0", "scoredFor" : "90" }, { "teamId" : "3", "position" : "2", "roundNumber" : "2", "played" : "2", "won" : "1", "lost" : "0", "byes" : "1", "scoredFor" : "88" }, { "teamId" : "4", "position" : "3", "roundNumber" : "2", "played" : "2", "won" : "0", "lost" : "2", "byes" : "0", "scoredFor" : "80" } ]