OpenTeeSheet open data format
Your venue's data is yours. Every venue, bay, booking, door grant and bay session on OpenTeeSheet has a published JSON Schema (draft 2020-12), the API returns those records, and one command exports all of them as a single document. Free on every plan, at any time, with no request to support and no fee. Anyone may implement the format.
Export everything in one command
From a terminal (the key is created on your account page, Agent access):
npx openteesheet login # paste the key from Account -> Agent access
npx openteesheet export --out my-venue.jsonOr straight from the API, or ask your AI agent to call the MCP tool export_venue_data. All three return the same document:
curl -H "Authorization: Bearer $OPENTEESHEET_API_KEY" \
https://openteesheet.com/api/v1/venue/export > my-venue.json{
"format": "openteesheet.venue-export",
"version": 1,
"schema": "https://openteesheet.com/schemas/venue-export.schema.json",
"exported_at": "2026-11-02T12:00:00.000Z",
"venue": { "object": "venue", "id": "...", "name": "...", ... },
"bays": [ { "object": "bay", ... } ],
"bookings": [ { "object": "booking", ... } ],
"door_grants": [ { "object": "door_grant", ... } ],
"bay_sessions": [ { "object": "bay_session", ... } ],
"counts": { "bays": 4, "bookings": 1250, "door_grants": 1190, "bay_sessions": 980 }
}A door grant says which lock, which method, which window and whether it is live; the code itself is never exported. Times are UTC (RFC 3339) and the venue record carries its IANA time zone. Prices are in cents.
Golfers: your own sessions, every venue
A golfer's own session history at every OpenTeeSheet venue (venue, bay, launch monitor, how each session started, the bay's real start and stop where it reports them, minutes played, how it ended) downloads from the account page, or with npx openteesheet my-sessions --out my-sessions.json, GET /api/v1/me/sessions or the MCP tool export_my_sessions, as one document matching https://openteesheet.com/schemas/golfer-sessions.schema.json. Shot and round data is not in it: no launch-monitor maker shares shot data with OpenTeeSheet yet.
Schemas
Each object has its own file; the bundle /schema/openteesheet-v1.json holds all of them under $defs. Records never carry payment-processor ids or secrets.
| Object | Schema | What it is |
|---|---|---|
venue | https://openteesheet.com/schemas/venue.schema.json | A golf simulator studio or course on OpenTeeSheet. The full record is what GET /api/v1/venue and the venue export emit; the public GET /api/v1/venues/{slug} emits the public subset (no created_at, no active flag). Never carries payment-processor ids or secrets. |
bay | https://openteesheet.com/schemas/bay.schema.json | One bookable simulator bay (or tee sheet) at a venue. |
booking | https://openteesheet.com/schemas/booking.schema.json | One booking of one bay for one time window. The door code itself is not part of the format: credentials are door grants (door-grant.schema.json) and their secrets never leave OpenTeeSheet. |
door-grant | https://openteesheet.com/schemas/door-grant.schema.json | One door credential issued for one booking on one lock (keypad code, card, mobile key or remote unlock). The secret (the code itself) is never exported: a grant says which lock, which window and whether it is live. |
bay-session | https://openteesheet.com/schemas/bay-session.schema.json | A booking's simulator session on the bay: scheduled, armed when the door lets the golfer in, started and stopped as the bay agent (or the owner) reports, and reconciled after the booking ends with how it ended. |
league-season | https://openteesheet.com/schemas/league-season.schema.json | A league season at a sim studio: a weekly night on named bays for N weeks, teams of a fixed size, an entry fee per golfer and a league-only bay rate per team per night (whole dollars, in cents), and one of three scoring rules. Making a season reserves every league night on those bays as a real league booking. |
league-team | https://openteesheet.com/schemas/league-team.schema.json | A team in a league season and its roster: the golfers who paid (or pay at the venue). A golfer who deletes their account leaves every roster; the team's posted scores stay. |
league-standing | https://openteesheet.com/schemas/league-standing.schema.json | One team's line in a season's standings, computed from the posted weekly scores by the season's rule: match_play (2 for a win, 1 for a tie, lower score wins), field_rank (each night's best score earns one point per team that posted, ties share the higher) or low_total (fewest strokes over the weeks played; points is null). |
venue-export | https://openteesheet.com/schemas/venue-export.schema.json | Everything a venue owner's account holds about their venue in the open format: the venue, every bay, every booking, every door grant and every bay session. The same document from GET /api/v1/venue/export, `openteesheet export` and the MCP tool export_venue_data. Every record is complete (all fields present, null when unknown). |
golfer-sessions | https://openteesheet.com/schemas/golfer-sessions.schema.json | A golfer's OWN session history across every OpenTeeSheet venue: per session the venue, bay, launch-monitor brand, how the session started, the real start and stop from the bay where the bay reports them (else the booked time, and which), minutes played and how it ended, with per-venue and per-month totals. Shot and round data is NOT included: it stays with the launch-monitor maker (shot_data.included is always false). The same document from the account page's download, GET /api/v1/me/sessions, `openteesheet my-sessions` and the MCP tool export_my_sessions. |
Every job, three ways
The REST API is documented in /openapi.json (each operation declares its security: a bearer API key; read jobs take a read key, writes a write key). The MCP server is https://openteesheet.com/mcp and the CLI is npx openteesheet; setup for each is on Use with your AI agent. Destructive jobs (cancel, move a booking, re-issue a door code) answer what would happen first and act only on confirm. An owner can also move a booking to a new time or another bay through the API and the MCP tool reschedule_venue_booking; the price stays as booked and the golfer gets a new door code.
| Object | Job | REST | MCP tool | CLI |
|---|---|---|---|---|
venue | Create | POST /api/v1/venue | create_my_venue | openteesheet myvenue create |
venue | Read | GET /api/v1/venue | get_my_venue | openteesheet myvenue |
venue | Update | PATCH /api/v1/venue | update_my_venue | openteesheet myvenue set |
venue | Read (public view, any venue) | GET /api/v1/venues/{slug} | get_venue_info | openteesheet venue |
bay | Create | POST /api/v1/venue/bays | create_bay | openteesheet bays add |
bay | Read (all) | GET /api/v1/venue/bays | list_my_bays | openteesheet bays |
bay | Read (one) | GET /api/v1/venue/bays/{id} | list_my_bays | openteesheet bays |
bay | Update | PATCH /api/v1/venue/bays/{id} | update_bay | openteesheet bays set |
booking | Create | POST /api/v1/bookings | book_tee_time | openteesheet book |
booking | Read (venue's, all) | GET /api/v1/venue/bookings | list_venue_bookings | openteesheet venue-bookings |
booking | Read (venue's, one) | GET /api/v1/venue/bookings/{id} | get_venue_booking | openteesheet venue-booking |
booking | Update (cancel, venue's) | PATCH /api/v1/venue/bookings/{id} | cancel_venue_booking | openteesheet venue-booking --cancel |
booking | Update (cancel, golfer's own) | DELETE /api/v1/bookings/{id} | cancel_booking | openteesheet cancel |
door-grant | Read | GET /api/v1/venue/door-grants | list_door_grants | openteesheet grants |
door-grant | Create / update (re-issue: revoke current, issue new) | POST /api/v1/venue/door-grants | reissue_door_grant | openteesheet grants reissue |
bay-session | Read | GET /api/v1/venue/bay-sessions | list_bay_sessions | openteesheet sessions |
bay-session | Create / update (record started / stopped / failed) | POST /api/v1/venue/bay-sessions | report_bay_session | openteesheet sessions report |
league-season | Create (reserves every league night on its bays) | POST /api/v1/venue/leagues | create_league_season | openteesheet leagues create |
league-season | Read (all) | GET /api/v1/venue/leagues | list_league_seasons | openteesheet leagues |
league-season | Update (close: sign-up stops, unplayed nights go back to the sheet; confirm first) | PATCH /api/v1/venue/leagues/{id} | close_league_season | openteesheet leagues close |
league-team | Read (a season's teams and rosters) | GET /api/v1/venue/leagues/{id} | get_league_season | openteesheet leagues show |
league-standing | Read (a season's standings) | GET /api/v1/venue/leagues/{id} | get_league_season | openteesheet leagues show |
venue-export | Export everything | GET /api/v1/venue/export | export_venue_data | openteesheet export |
golfer-sessions | Export (a golfer's own sessions, every venue) | GET /api/v1/me/sessions | export_my_sessions | openteesheet my-sessions |
Stability
Version 1. Fields are added only as optional; a field is never renamed or removed within a version, and the export names its schema URL so a reader can always check what it got. The API's responses for these objects are validated against these exact files in our test suite, so a field cannot drift without a test failing.