Webhooks notify your endpoint when an event, division, team, or game, bout, race, match is created, updated, or deleted. Instead of polling the API, a POST request containing the changed records is sent to a url you provide.
Setup
Webhooks are configured per organization under Organizations on the director dashboard. Open the organization, expand the Webhook section, and provide the following.
- Webhook Url
- The https url that receives the POST request. This is an endpoint on your server, not a website address.
- Webhook Events
- The event types you want to receive. Only the selected types are sent. If none are selected nothing is sent.
Changes to any event owned by the organization are sent to the url. Hidden events and event templates never send webhooks, and divisions that are not visible are excluded.
Request
Each delivery is a POST request with a JSON body. The request is made from our servers with the following headers.
POST /your/webhook/url
Host: your-server.com
Content-Type: application/json
User-Agent: Exposure Events
Payload
The body of every request uses the same envelope. Property names are camel case and properties with a null value are removed.
- version
- The payload version. Currently 1.
- type
- The event type that caused the request, for example game.updated.
- timestamp
- The UTC date and time the request was sent in ISO 8601 format.
- data
- The list of changed records. Every record is the same object the API returns for that resource, so an event.updated record matches the event response, a team record matches the team response, and so on.
- Records are grouped by event type and event, so a single request only contains records of one type that belong to one event.
- A request contains at most 50 records. Larger changes are split across multiple requests.
- Records reflect the current state of the data at the time the request is sent, not the state at the time of the change.
- Deleted records only contain the id, and a deleted game, bout, race, match also contains the event id it belonged to.
- If a created or updated record is deleted before the request is sent, the record is skipped.
Event Types
The following event types can be selected for an organization. Click a type to see the payload it sends on the resource page.
| Type | Trigger |
|---|---|
| event.updated | The event details or settings are saved, or the event is published. |
| division.created | A division is added or copied to the event. |
| division.updated | The division details or settings are saved, the event settings are saved, or the event is published. |
| division.deleted | A division is removed from the event. |
| team.created | A team is added to a division by registration, store checkout, import, integration, the API, or a director. |
| team.updated | The team details, division, or roster are saved by a director, coach, or the API. |
| team.deleted | A team is removed from the event or moved to another event. |
| game.created | A game, bout, race, match is added to the schedule or a bracket, or the schedule is published. |
| game.updated | A score or result is entered, the game, bout, race, match is rescheduled, or standings and brackets are processed. |
| game.deleted | A game, bout, race, match is removed from the schedule, a pool, a bracket, or the standings. |
Deliveries and Retries
Changes are queued and sent by a job that runs every few minutes, so a request arrives shortly after the change rather than immediately. Your endpoint must respond within 30 seconds with an http status of 200 OK. Any other status, a timeout, or a connection error is treated as a failed delivery.
A failed delivery is retried on the following schedule after the previous attempt. Once the schedule is exhausted the delivery is marked failed and is not retried.
- 1 minute
- 5 minutes
- 15 minutes
- 1 hour
- 4 hours
Directors can review every delivery, its status, and the number of retries left under Webhooks on the organization or event dashboard, and can resend a delivery at any time. Because a delivery can be sent more than once, your endpoint should handle a record it has already received.
Hidden Schedules
Game, Bout, Race, Match webhooks are held while the event schedule, or the division schedule, is hidden from the public. When the schedule is published every scheduled game, bout, race, match is sent as game.created, and later changes are sent as they occur.
Sample
A request containing a single game, bout, race, match for each game, bout, race, match event type. Deleted records only contain the ids needed to locate the record on your side.
{
"version": 1,
"type": "game.created",
"timestamp": "2026-10-15T04:29:39.5446437Z",
"data": [
{
"Id": 64,
"Type": 1,
"Date": "10/15/2026",
"Time": "12:29 AM",
"Division": {
"Id": 120,
"Name": "17",
"Event": {
"Id": 30,
"Name": "Exposure Events"
}
},
"VenueCourt": {
"Id": 0,
"Court": {
"Id": 0,
"Name": "Main",
"Abbr": "MN"
},
"Venue": {
"Id": 68,
"Name": "Exposure High School",
"Abbr": "EHS",
"Address": {
"Location": "Exposure High School",
"StreetAddress": "3934 E Battala Avenue",
"ExtendedAddress": "Suite 144",
"City": "Gilbert",
"StateRegion": "Arizona",
"PostalCode": "85297",
"Latitude": 36.1849073,
"Longitude": -115.1230314
}
}
},
"AwayTeam": {
"Name": "Away Team",
"Pool": "A",
"PoolNumber": 1,
"Score": 57.0,
"TeamId": 1487,
"TeamPoolId": 55555,
"BracketName": "Gold",
"BracketId": 100,
"DivisionSeed": 4,
"Seed": 2,
"DivisionId": 100,
"DivisionName": "16",
"WonBy": 7,
"Color": "000000"
},
"HomeTeam": {
"Name": "Home Team",
"Pool": "A",
"PoolNumber": 2,
"Score": 58.0,
"TeamId": 1488,
"TeamPoolId": 45464,
"PoolSeed": 2,
"Exhibition": true,
"Color": "FF0000"
},
"BracketName": "Championship",
"Round": 2
}
]
}
{
"version": 1,
"type": "game.updated",
"timestamp": "2026-10-15T04:29:39.5446437Z",
"data": [
{
"Id": 64,
"Type": 1,
"Date": "10/15/2026",
"Time": "12:29 AM",
"Division": {
"Id": 120,
"Name": "17",
"Event": {
"Id": 30,
"Name": "Exposure Events"
}
},
"VenueCourt": {
"Id": 0,
"Court": {
"Id": 0,
"Name": "Main",
"Abbr": "MN"
},
"Venue": {
"Id": 68,
"Name": "Exposure High School",
"Abbr": "EHS",
"Address": {
"Location": "Exposure High School",
"StreetAddress": "3934 E Battala Avenue",
"ExtendedAddress": "Suite 144",
"City": "Gilbert",
"StateRegion": "Arizona",
"PostalCode": "85297",
"Latitude": 36.1849073,
"Longitude": -115.1230314
}
}
},
"AwayTeam": {
"Name": "Away Team",
"Pool": "A",
"PoolNumber": 1,
"Score": 57.0,
"TeamId": 1487,
"TeamPoolId": 55555,
"BracketName": "Gold",
"BracketId": 100,
"DivisionSeed": 4,
"Seed": 2,
"DivisionId": 100,
"DivisionName": "16",
"WonBy": 7,
"Color": "000000"
},
"HomeTeam": {
"Name": "Home Team",
"Pool": "A",
"PoolNumber": 2,
"Score": 58.0,
"TeamId": 1488,
"TeamPoolId": 45464,
"PoolSeed": 2,
"Exhibition": true,
"Color": "FF0000"
},
"BracketName": "Championship",
"Round": 2
}
]
}
{
"version": 1,
"type": "game.deleted",
"timestamp": "2026-10-15T04:29:39.5446437Z",
"data": [
{
"Id": 64,
"Division": {
"Id": 0,
"Event": {
"Id": 30
}
}
}
]
}