Competition Management Guide

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.

Overview of the Warehouse

Describing the data warehouse

League

Competition

Teams

Clubs

Matches

Venue

Competitors

Standings

Persons

Configuration Hint

Match Staff

Match Actions

Setup

ID Management

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).

Process order

Based on the requirement to know IDs and make it easier for the API calls, best to pass CREATES through in this order:

Implementation Suggestions

Working log

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
    

Storing IDs from 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.

Bulk/First time load

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.

Example competition

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

Add the Venues

POST /v1/basketball/leagues/1/venues?ak=TESTAPIKEY&minimumResponse=1
        {
            "venueName" : "Eastern Basketball Centre",
            "status" : "ACTIVE",
            "latitude" : "-37.811784",
            "longitude" : "145.316557",
            "timezone" : "Australia/Melbourne",
            "countryCode" : "AU",
            "externalId" : "65"
        }
        
Response
        {
            "venueId" : 1,
            "externalId" : "65"
        }
        

Add the Teams

POST /v1/basketball/leagues/1/teams?ak=TESTAPIKEY&bulk=1&minimumResponse=1
        [
            {
                "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"
        }
        

Add the People (Person records)

POST /v1/basketball/leagues/1/persons?ak=TESTAPIKEY&bulk=1&minimumResponse=1
        [
            {
                "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"
        }
        

Add the Competitions

POST /v1/basketball/leagues/1/competitions?ak=TESTAPIKEY&minimumResponse=1
        {
            "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"
        }
        

Link the players to teams

POST /v1/basketball/leagues/1/playerdefaults?ak=TESTAPIKEY&minimumResponse=1&bulk=1
        [
            {
                "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
            }
        ]
        

Add the Matches

POST /v1/basketball/competitions/1/matches?ak=TESTAPIKEY&bulk=1&minimumResponse=1
        [
            {
                "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"
        }
        

Add Players to the match

Players can be added to the match prior to the match starting, or once the match is completed

POST /v1/basketball/leagues/1/matches/players?ak=TESTAPIKEY&minimumResponse=1&bulk=1
        [
            {
                "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 Match Completion

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

Update the Matches

PUT /v1/basketball/matches/3?ak=TESTAPIKEY&minimumResponse=1
        {
            "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"
                }
            ]
        }
        

PUT /v1/basketball/matches/4?ak=TESTAPIKEY&minimumResponse=1
        {
            "competitors": [
                {
                  "teamId": 3,
                  "resultPlacing" : 1,
                  "completionStatus": "COMPLETE"
                }
            ]
        }
        

POST /v1/basketball/matches/5?ak=TESTAPIKEY&minimumResponse=1
        {
            "competitors": [
                {
                  "teamId": 3,
                  "resultPlacing" : 1,
                  "completionStatus": "COMPLETE"
                }
            ]
        }
        

Update the Team Period Scores

POST /v1/basketball/leagues/1/statistics/teammatch?ak=TESTAPIKEY&minimumResponse=1&bulk=1
        [
            {
                "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",
            }
        ]
        

Update the Person Period Scores

POST /v1/basketball/leagues/1/statistics/personmatch?ak=TESTAPIKEY&minimumResponse=1&bulk=1
        [
            {
                "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"
            }
        ]
        

Building the match statistics

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.

POST /v1/basketball/leagues/1/statistics/matches/build?ak=TESTAPIKEY
        {
            "competitionId" : "1",
            "matchId" : "3"
        }
        

Standings

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
POST /v1/basketball/competitions/1/standings?ak=TESTAPIKEY&minimumResponse=1&bulk=1
        [
            {
                "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"
            }
         ]