Publish a match to the system action by action as the match is in progress.
This method instantiates a long running call, which will remain open as long as data is being sent.
There are two different ways to establish a publish connection to the system a HTTP method or a RAW method. These two different ways exists to enable the client to potentially work around any port or proxy problems present at in venue areas. Connections can also be sent over one of two different ports, 80 or 5522
The same data, parameters and format is used in both methods, only the startup of the connection differs.
Note: This call makes use of the streaming API endpoint which differs from the standard API endpoint.
POST /v2/{sport}/publish
In the RAW method, a socket is opened to the streaming API endpoint and the request string is sent, followed by two carriage returns (\n\n
) or two carriage return line feeds (\r\n\r\n
). To initiate RAW mode the nohttp parameter must be present and set in the request string.
/v2/{sport}/publish
Parameter Name | Value | Description |
---|---|---|
Required Parameters | ||
streamKey |
string |
The unique authorisation key that allows the streaming of the match |
timestamp |
integer |
The UNIX timestamp for the current date and time indicating the number of seconds since January 1st 1970 at UTC. The client timestamp must be within 60 seconds of the correct time or else the connection will be refused. |
Optional Parameters | ||
nohttp |
integer |
If set to one then the connection will operate in RAW mode. If this parameter is not present and set to the value of 1, then the connection will operate in HTTP mode regardless of what connection string is sent. |
mode |
string |
The mode of the connection:
|
format |
string |
The format the data is being sent in. Options are
|
sendAcks |
integer |
If set to 1, then each message received will generate an acknowledgement message. |
POST /v2/basketball/publish?streamKey=TESTSTREAMKEY×tamp=1412987153 HTTP/1.1 Host: localhost:8000 Connection: keep-aliveExample - RAW
/v2/basketball/publish?nohttp=1&streamKey=TESTSTREAMKEY×tamp=1412987153
The body of the request should be a series of messages (defined below). Each message must be delimited by a carriage return/line-feed \r\n
series of characters (in hex, 0x0D 0x0A). Consequently this series of characters must not appear in any message content.
The content if each message may be sent in a compressed format to reduce the size of the data being transferred. The message data should be compressed using a gzip/deflate algorithm (http://www.faqs.org/rfcs/rfc1951.html)and then Base64 encoded. Instead of the normal data being the value of the message
key, the compressed data should be the value of a compressedMessage
key.
{ "message": { "type": "master", "format": "json" } }Example - Compressed
{ "compressedMessage": "q1YqqSxIVbJSyk0sLkktUtJRSssvyk0sAYpkFefnKdUCAA==" }
To maintain the open connection at least one message must be sent every 20 seconds. A keepalive
message may be sent if no other message needs to be sent.
The session will be closed automatically if it has been open for more than 4 hours, whether data is being sent or not.
For redundancy purposes the system supports multiple connections for the same match from different clients. There can only be one connection in master
mode, all the others must be in backup
mode. If a second connection is made in master
mode, or a connection changed to master
mode then the first master
connection is disconnected.
To monitor the latency of the entire streaming process as well as the connection between the client and the warehouse the latency of the connection is measured. This process involves the sending of a latencyrequest
message from the warehouse to the client. The client should immediately respond with a latencyresponse
message containing the information sent by the warehouse.
Each message from the message category 'match' must include a messageId
parameter. The messageId
MUST be a unique and sequential integer. Numbers cannot be skipped. If the system detects that a messageId has been skipped then an error will be generated indicating which messageId is missing. The client should interpret this message and resend all messages from (and including) the missing Id. Processing will not be resumed until the missing message is processed.
Messages should be sent as soon as possible after some kind of action occurs.
For example these are the sections you would send for particular events:
action (Foul), action (PossessionChange)
action(3pt)
action(substitution in)
status (inprogress), periodstatus (started), game (start), period (start), clock (start)
periodstatus (started), period (start), clock (start)
For detailed information about the size and types of the field values, please check the corresponding resource description in the Warehouse API documentation.
This message type has information about the how the match will be run.
This message type must be sent at least once before the beginning of the match.
The fields for this message type differ by sport. The fields are listed below, by sport.
message |
|||
type |
setup |
||
messageId |
Unique message identifier (see main description) | ||
periods |
|||
number |
The number of periods | ||
length |
The length of the periods | ||
extraTime |
Is extra time available | ||
extraTimeLength |
The length of the extra time periods | ||
breakPeriod |
The length (in minutes) between periods | ||
breakHalftime |
The length (in minutes) at half time | ||
shotClock |
The length of time (in seconds) for the shotClock | ||
foulsPersonal |
The maximum number of fouls (personal) allowed | ||
foulsTechnical |
The maximum number of fouls (technical) allowed | ||
foulsBeforeBonus |
The number of fouls allowed before a bonus is given | ||
customEfficiencyFormula |
A string giving the formula to calculate a custom efficiency value. The formula can use simple mathematical constructs * + - / () and contain a number of variables. Each variable must be the name of a valid Team Match Statistic. e.g.(sPoints + sAssists + sBlocks + sSteals + sFoulsOn + sReboundsTotal) - (sTurnovers + sBlocksReceived + sFoulsPersonal + sFoulsTechnical + (sTwoPointersAttempted - sTwoPointersMade) + (sThreePointersAttempted - sThreePointersMade)) . For a complete list of allowed statistic names and further formula examples click here. |
||
timeouts |
|||
style |
How are timeouts counted, by period or half | ||
period1 |
The maximum number of timeouts allowed in period 1 | ||
period2 |
The maximum number of timeouts allowed in period 2 | ||
period3 |
The maximum number of timeouts allowed in period 3 | ||
period4 |
The maximum number of timeouts allowed in period 4 | ||
half1 |
The maximum number of timeouts allowed in the first half | ||
half2 |
The maximum number of timeouts allowed in the second half | ||
extraTime |
The maximum number of timeouts allowed in extraTime |
message |
|||
type |
setup |
||
messageId |
Unique message identifier (see main description) | ||
shotClock |
The length of time (in seconds) for the shotClock | ||
foulsPersonal |
The maximum number of fouls (personal) allowed | ||
foulsTechnical |
The maximum number of fouls (technical) allowed | ||
foulsBeforeBonus |
The number of fouls allowed before a bonus is given | ||
foulsBeforeDoubleBonus |
The number of fouls allowed before a double bonus is given | ||
foulsBeforeTechnical |
The number of fouls allowed before a technical foul is given | ||
winningScore |
The score that a team must reach within regulation time to win. | ||
customEfficiencyFormula |
A string giving the formula to calculate a custom efficiency value. The formula can use simple mathematical constructs * + - / () and contain a number of variables. Each variable must be the name of a valid Team Match Statistic. e.g.(sPoints + sAssists + sBlocks + sSteals + sFoulsOn + sReboundsTotal) - (sTurnovers + sBlocksReceived + sFoulsPersonal + sFoulsTechnical + (sTwoPointersAttempted - sTwoPointersMade) + (sOnePointersAttempted - sOnePointersMade)) . For a complete list of allowed statistic names and further formula examples click here. |
||
timeouts |
|||
period1 |
The maximum number of timeouts allowed in period 1 | ||
extraTime |
The maximum number of timeouts allowed in extraTime |
{ "message": { "type": "setup", "messageId" : 6, "periods": { "number":2, "length" : 20, "lengthOvertime" : 5, "breakPeriod" : 2, "breakHalftime" : 2, "overtime : 1 }, "maxFoulsPersonal": "5", "maxFoulsTechnical": "5", "shotClock": "25", "timeouts" : { "style": "period", "half1": "2", "half2": "3", "period1": "2", "period2": "2", "period3": "2", "period4": "2", "extraTime": "1" } } }
This message type defines the teams and players for the match.
It is compulsory to send at least one of these messages.
message |
||||
type |
teams |
|||
messageId |
Unique message identifier (see main description) | |||
teams |
An array of team records | |||
teamNumber |
The number of the team in the match, 1 or 2. | |||
detail |
||||
teamName |
||||
teamId |
Unique identifier for the team (generated by the warehouse system) | |||
teamNickname |
||||
teamCode |
||||
players |
A list of players | |||
pno |
The number of the player in the match. This is a sequence number not a jumper number. | |||
firstName |
||||
familyName |
||||
personId |
Unique identifier for the person (generated by the warehouse system) | |||
shirtNumber |
||||
playingPosition |
||||
height |
||||
active |
Is this player currently active? 1 = yes, 0 = no | |||
captain |
Is this player the captain? 1 = yes, 0 = no | |||
starter |
Is this player a starter? 1 = yes, 0 = no | |||
coach |
||||
personId |
Unique identifier for the person (generated by the warehouse system) | |||
firstName |
||||
familyName |
||||
assistcoach1 |
||||
personId |
Unique identifier for the person (generated by the warehouse system) | |||
firstName |
||||
familyName |
||||
assistcoach2 |
||||
personId |
Unique identifier for the person (generated by the warehouse system) | |||
firstName |
||||
familyName |
{ "message": { "type": "teams", "messageId" : 6, "teams": [ { "teamNumber": 1, "detail": { "teamName": "Rotherberg Raiders", "teamId": 2065, "teamNickname": "Raiders", "teamCode": "RRD" }, "players": [ { "pno": 1, "firstName": "John", "familyName": "Smith", "personId": 3456, "captain": 1, "active": 1, "starter": 1 }, { "pno": 2, "firstName": "Aaron", "familyName": "Person", "personId": 57564, "captain": 0, "active": 1, "starter": 0 } ], "coach": { "personId": 57564 } }, { "teamNumber": 2, "detail": { "teamName": "Sackville Hawks", "teamId": 2066, "teamNickname": "Hawks", "teamCode": "SVH" }, "players": [ { "pno": 1, "firstName": "Martin", "familyName": "Mann", "personId": 3458, "captain": 1, "active": 1, "starter": 1 }, { "pno": 2, "firstName": "Archie", "familyName": "Person", "personId": 57544, "captain": 0, "active": 1, "starter": 0 } ], "coach": { "personId": 564 } } ] } }
This message type contains the information about the match officials assigned to the match.
This message type is only needed it there is information about match officials that needs to be sent.
message |
|||
type |
officials |
||
messageId |
Unique message identifier (see main description) | ||
commissioner |
|||
personId |
Unique identifier for the person acting as Commissioner (generated by the warehouse system) | ||
firstName |
First name of person acting as Commissioner | ||
familyName |
Family name of person acting as Commissioner | ||
externalId |
ExternalId of person acting as Commissioner | ||
referee1 |
|||
personId |
Unique identifier for the person acting as Referee 1 (generated by the warehouse system) | ||
firstName |
First name of person acting as Referee 1 | ||
familyName |
Family name of person acting as Referee 1 | ||
externalId |
ExternalId of person acting as Referee 1 | ||
referee2 |
|||
personId |
Unique identifier for the person acting as Referee 2 (generated by the warehouse system) | ||
firstName |
First name of person acting as Referee 2 | ||
familyName |
Family name of person acting as Referee 2 | ||
externalId |
ExternalId of person acting as Referee 2 | ||
referee3 |
|||
personId |
Unique identifier for the person acting as Referee 3 (generated by the warehouse system) | ||
firstName |
First name of person acting as Referee 3 | ||
familyName |
Family name of person acting as Referee 3 | ||
externalId |
ExternalId of person acting as Referee 3 | ||
statisticians |
An array of statistician records | ||
statisticianId |
Unique identifier for the statistician. Obtained from the SportingPulse Statistician's network | ||
firstName |
First name of the person | ||
familyName |
Family name of the person | ||
statisticianType |
The type of statistician.
|
{ "message": { "type": "officials", "messageId" : 3, "commissioner" : { "personId" : 2345, "firstName" : "John", "familyName" : "Smith", "externalId" : "HY3434" }, "referee1" : { "personId" : 34, "firstName" : "Angus", "familyName" : "Smythe", "externalId" : "56" }, "referee2" : { "personId" : 987, "firstName" : "Mary", "familyName" : "Richardson", "externalId" : "MR8" } } }
This message type contains one specific action in the match.
Actions come in two types, adminstrative
or sport
. A sport type action is related to the sport aspect of the match, eg substitution or foul. An administrative type action is related to the process or publishing the game eg. period confirmed. Only sport type actions are given an actionNumber. The action number is a sequential integer that should uniquely refer to that action. The actionNumber
is repeated to indicate an edit or delete on the original action.
message |
||||
type |
action |
|||
messageId |
Unique message identifier (see main description) | |||
actionNumber |
The unique sequence number given to this action. See above | |||
clock |
The current time on the clock. Format MM:SS:CC | |||
shotClock |
The current time on the shot clock. Format MM:SS:CC | |||
timeActual |
The actual time for this action in UTC. Format YYYY-MM-DD HH:MM:SS | |||
period |
The period number. Overtime periods start at 1 | |||
periodType |
The type of period.
|
|||
teamNumber |
The team this action relates to. 1 or 2. 0 for not team related actions, eg start gane | |||
pno |
The player this action relates to. The player's number inside the team, not their playing number | |||
actionType |
A code representating the action taken. Defined by sport: | |||
subType |
The subType of action occurring. Defined by sport: | |||
qualifiers |
An semi-colon ';' delimited string of qualifiers to the action. Defined by sport: | |||
value |
A text field. Some action types require a value. This is where that value needs to be placed. | |||
score1 |
The current score for team number 1. Even if this action is an edit for a previous period, this should be the current score. | |||
score2 |
The current score for team number 2. Even if this action is an edit for a previous period, this should be the current score. | |||
previousAction |
If this action is the result of another action. This field should hold the number of the previous action. | |||
success |
This action was completed successfully. 1 = yes, 0 = no. Generally all actions except shots are successful. | |||
officialId |
The unique identifier for the official that called this action. | |||
area |
The area on the playing surface where the action occurred. Defined in Playing Surface Definition. | |||
x |
The x coordinate for where the action occurred on the playing surface. Defined in Playing Surface Definition. | |||
y |
The y coordinate for where the action occurred on the playing surface. Defined in Playing Surface Definition. | |||
side |
The side of the playing surface, left or right. Defined in Playing Surface Definition. | |||
edited |
If the action has been edited (after being initially sent) this field should contain the last time it was edited (in UTC). The time should be in the following format (in UTC). Format YYYY-MM-DD HH:MM:SS. If the action has not been edited, then this field is not required. | |||
inserted |
If the action has been inserted (added out of sequence) this field should contain the time it was inserted (in UTC). The time should be in the following format (in UTC). Format YYYY-MM-DD HH:MM:SS. If the action has not been inserted, then this field should not be present. | |||
deleted |
If the action has been deleted (after being initially sent) this field should contain the time it was deleted (in UTC). The time should be in the following format (in UTC). Format YYYY-MM-DD HH:MM:SS. If the action has not been deleted, then this field is not required. | |||
system |
If this value is set to 1 then it indicates that this action was automatically generated by the system and not explicitly performed by the user (value = 0). eg. A start period automatically creating a start clock action. | |||
underReview |
1 = yes, 0 = no. The action is not official as yet, it is being review by match officials or the organisation. This may occur in disputed actions or actions being checked by some kind of video. | |||
sendDelay |
Optional. If present, this floating point number represents the number of seconds that have elapsed (at the time of sending the message) since the action occurred. | |||
completionDelay |
Optional. If present, this floating point number represents the number of seconds that elapse between the user beginning the action and the action being completed. |
{ "message": { "type": "action", "messageId": 5, "actionNumber": 1, "period": 1, "periodType": "REGULAR", "clock": "10:00:00", "timeActual": "2013-08-13 15:56:00", "shotClock": "00:20", "teamNumber": 1, "pno": 1, "score1": "0", "score2": "0", "actionType": "substitution", "subType": "in", "previousAction": 0 } }
This message type has information about the how the match was run.
This message type is optional, but if sent, it must be sent before the match status is sent as completed.
message |
|||
type |
summary |
||
messageId |
Unique message identifier (see main description) | ||
timeActual |
The actual start time of the match YYYY-MM-DD HH:MM:SS (local time) | ||
timeEndActual |
The actual end time of the match YYYY-MM-DD HH:MM:SS (local time) | ||
durationActual |
The actual duration of the match (mins) including timeouts and period breaks | ||
temperature |
The temperature during the match (Degrees Celsius) | ||
attendance |
Attendance of the match | ||
duration |
The duration (in minutes) of the match - including overtime - excluding breaks and timeouts |
{ "message": { "type": "summary", "messageId" : 456, "timeActual": "2015-06-04 18:00:00", "timeEndActual": "2015-06-04 21:04:00", "durationActual": 184, "temperature": 25, "attendance": 250, "duration": 48 } }
This message type changes the mode of the connection from backup
to master
. Any other master
connections will be disconnected.
This message type is only required if the client is making multiple simultaneous connections to the server.
message |
|||
type |
master |
||
format |
The format the data is being sent in. Options are
|
{ "message": { "type": "master", "format": "json" } }
This message type is sent to keep the connection to the server alive. This message is not required, but may be used to maintain an open connection. It is the only message type that does not require a messageId
message |
|||
type |
keepalive |
{ "message": { "type": "keepalive" } }
The client should send this message type in response to a latencyrequest
message.
message |
||||
type |
latencyresponse |
|||
number |
The number provided in the latencyrequest message. |
|||
timestamp |
The UNIX timestamp for the current date and time indicating the number of seconds since January 1st 1970 at UTC. | |||
readDelay |
Optional. The number of seconds the client takes to read information from the connection. Used if the client introduces a delay in reading responses from the server. eg. Only checks the socket every 2 seconds for requests/responses. |
{ "message": { "type": "latencyresponse", "number": 1394569858.9497 } }
The client should send this message to the server when it ends its connection.
message |
||||
type |
disconnection |
|||
reason |
The reason for the disconnection. The options available are:
|
|||
description |
An optional text description giving more information about the reason. |
{ "message": { "type": "disconnect", "reason": "USER_INITIATED", "description" : "User pressed disconnect" } }
While the publish call is primarily about streaming data to the warehouse, the connection is bi-directional and messages will also be sent from the warehouse.
The message type is returned from the warehouse on successful authentication. Included in this message is the messageId
of the last successfully processed message. If the connection is a reconnection then the client should sent all messages with an Id after this one.
{ "message": { "type": "authenticated", "lastMessageId": 45 } }
The message type is returned from the warehouse on any type of error.
{ "message": { "type": "error", "error": "[message.clockRunning] is missing and it is required" } }
The message type is sent from the warehouse to measure latency for the connection. The client should immediately respond with a lantencyresponse
message.
message |
||||
type |
latencyrequest |
|||
number |
A unique number. This should be immediately returned by the client in a latencyresponse message. |
The message type is sent in response to a message from the client. Only sent when the sendAcks
parameter is set on connection.
The message contains the messageId
of the sent message and actionNumber
(if sent).
message |
||||
type |
ack |
|||
acktype |
The type of the message being responded to. | |||
messageId |
The messageId of the message being responded to. |
|||
actionNumber |
The action number (if present) of the message being responded to. |
{ "message": { "type": "ack", "acktype": "action", "actionNumber": 783, "messageId": 1041 } }
In some circumstances the server will send an action message to the client. The client should interpret this message and action it as if the user had requested this action. It should then be sent back to the server as a normal action. If this is the case the server will send the action message with a messageId of 0.