CurlOps publishes a read-only schedule feed that Curling Stadium Manager (CSM) polls every hour. CSM launches OBS for the right sheet, opens a YouTube broadcast, and ends the stream when the game finishes — no club-staff intervention.
One URL · One API key · Polled hourly · TLS required
CurlOps is the schedule source. CSM does the broadcasting. The contract between them is a single JSON endpoint.
CSM requests a 30-day forward window from your facility's feed — plus an on-demand sync whenever an operator clicks "Sync".
A clean array of scheduled games with sheet, start/end in ISO-8601, teams, event name, and a stable id for dedupe.
~60 seconds before start, CSM launches OBS for that sheet, opens a YouTube broadcast, and applies the overlay.
At the game's end time the stream stops and the recording lands in your YouTube archive. Fully unattended.
This is a real response from a CurlOps facility feed. Two top-level keys: facility metadata and the games array. Empty windows return "games": [] with 200 OK.
# Curling Stadium Manager polling a facility
curl "https://app.curlops.com/api/v1/integrations/\
csm/facilities/dumfries-ice-bowl/games\
?from=2026-06-15&to=2026-07-15" \
-H "X-API-Key: 4f8b3c9e…b0d3f6a" \
-H "Accept: application/json"
{
"facility": {
"slug": "dumfries-ice-bowl",
"name": "Dumfries Ice Bowl",
"timezone": "Europe/London"
},
"games": [
{
"id": "g_2026_06_20_A_1",
"sheet": "A",
"start": "2026-06-20T19:00:00+01:00",
"end": "2026-06-20T21:00:00+01:00",
"event_name": "Tuesday Mixed — Draw 5",
"team1": "Smith Rink",
"team2": "Jones Rink",
"notes": null,
"status": "scheduled"
},
{
"id": "g_2026_06_21_C_1",
"sheet": "C",
"start": "2026-06-21T10:00:00+01:00",
"end": "2026-06-21T12:00:00+01:00",
"event_name": "Saturday Senior — Draw 5",
"team1": "MacLeod Rink",
"team2": "Anderson Rink",
"notes": "Quarter-final",
"status": "scheduled"
}
]
}
All datetimes carry a timezone offset — never naive local times. The id is stable across polls so a reschedule is the same game with new times.
| Field | Type | Notes |
|---|---|---|
| slug | string | URL-safe facility identifier. |
| name | string | Human-readable; shown in CSM logs. |
| timezone | string | IANA zone for sanity-checking, e.g. Europe/London. |
| Field | Type | Notes |
|---|---|---|
| id | string | Stable & unique. Same on reschedule. |
| sheet | string | Sheet label, e.g. "A" or "1". Case-sensitive. |
| start | string | ISO-8601 with offset. |
| end | string | ISO-8601 with offset. |
| event_name | string | League / event for the broadcast title. |
| team1 · team2 | string? | Rink names; null for a placeholder. |
| notes | string? | Free text; admin display only. |
| status | enum | See mapping below. |
CSM only broadcasts scheduled games. Everything else is skipped on import or deactivated on the next poll. CurlOps maps its internal game states onto the CSM vocabulary:
A CurlOps admin issues a per-facility key; the CSM operator pastes the schedule URL and key into the facility. From then on, your league streams itself.
If your club runs CurlOps and Curling Stadium Manager, your schedule is already broadcast-ready.
Start your league →