# One Ticket - technical guide for AI assistants and developers > One Ticket is an event ticketing and membership platform for organisers in > Australia, the UK and the US. This file is the technical companion to > https://oneticket.com.au/llms.txt: how the site is addressed, what can be read without > signing in, the public REST API, the Model Context Protocol (MCP) server, > and the exact fee formula. It is the developer documentation; the page for > people is https://oneticket.com.au/developers. Everything here is read-only. Booking, > payment and anything about an organiser's own account happen on the website. ## Quick start - REST API base: `https://oneticket.com.au/api/v1` (JSON, `GET` only, no key) - OpenAPI 3.1 specification: https://oneticket.com.au/openapi.json (YAML: https://oneticket.com.au/openapi.yaml) - Search upcoming events: `GET https://oneticket.com.au/api/v1/events?q=yoga&city=darwin` - MCP server: `https://oneticket.com.au/mcp` (Streamable HTTP, JSON-RPC 2.0, no authentication) - MCP server cards: https://oneticket.com.au/.well-known/mcp/server-card.json and https://oneticket.com.au/.well-known/mcp.json - API catalog (RFC 9727): https://oneticket.com.au/.well-known/api-catalog - Developer index (JSON): https://oneticket.com.au/api - Developers and AI assistants (page for people): https://oneticket.com.au/developers - Product summary: https://oneticket.com.au/llms.txt ## Finding an event for someone 1. Search: `GET https://oneticket.com.au/api/v1/events?q=yoga&city=darwin&limit=5` (or the MCP tool `search_events` with `{"q": "yoga", "city": "Darwin"}`). Results are public, upcoming events, soonest first. 2. Look the one they like up: `GET /api/v1/events/{slug}` (or `get_event`) with the result's `slug`, for ticket types, prices, availability and the refund policy. 3. Send the person to the result's `url` (`bookUrl`) to book. Booking and payment happen on that page; do not try to complete a booking for them. ## The things on One Ticket - **Event** - one thing that happens: a title, one or more dates, a start and end time in an IANA timezone, a place or "Online", and ticket types. Public address: `https://oneticket.com.au/e/{slug}`. People book on that page. - **Series** - events that meet again (a weekly class, a club season). Each session is an event. Address: `https://oneticket.com.au/s/{slug}`; a session's old address under its series, `/s/{series-slug}/{event-slug}`, redirects to the session's own page. - **Subscription** - a weekly, fortnightly or monthly plan on a series. A subscriber's ticket for each session is issued automatically before it runs. - **Organiser** - the person or club running events. Public page: `https://oneticket.com.au/o/{slug}`, with their events to come and gone and their series, on any plan; its banner, links and colours are Pro and Team's. An event names its organiser, linked to that page, unless the organiser hides it. - **Ticket type (tier)** - a named price with an optional cap, sales window and per-person limit. A price of 0 is a free ticket. A pay what you want type (Pro and Team) lets the attendee choose the amount, at least its price (which may be 0: a donation). A sold-out type can take a waitlist. One ticket can admit up to 8 people (a couple, a family, a table) for its one price; each of them gets a ticket of their own, and the cap counts people. Some ticket types are hidden behind an access code or sold only at the door; those are never listed here. - **Extra (add-on)** - something sold with the tickets, after them and before paying: a drink token, parking, a programme, merch. Its own price, with an optional limit an order and in all; the booking fee and discount codes apply to it as to a ticket. It shows on the order, the ticket and at the door. Adding extras is on Pro and Team. - **Ticket** - one person's place, with a QR code checked at the door. Visibility: an event is *public* (anyone can find and read it), *unlisted* (only with its share link), *private* (the organiser's team, or anyone with its password) or a *draft*. Only public, live pages are returned by the API and the MCP server. "Not found" covers every other case on purpose: the API does not say whether a hidden page exists. An event's old address (from before a rename) answers with the event's current one. ## REST API All responses are JSON with `access-control-allow-origin: *`. Errors are `{"error": "..."}` with a 4xx or 5xx status. Only `GET` (and the CORS `OPTIONS`) is answered; anything else is a 405. ### GET /api/v1 What the API is, and links to the specification, the MCP server and this file. ### GET /api/v1/events Search the public, live events still to come, soonest first. All parameters are optional: | Parameter | Meaning | |---|---| | `q` | Words to find in the title, summary or place (every word must match, any case), at most 100 characters | | `city` | A town, suburb or city to find in the place name or address (any case) | | `from`, `to` | Only events with a day on or after / before this date (`YYYY-MM-DD`, inclusive) | | `online` | `true`: only online events; `false`: only in-person | | `free` | `true`: only events with a free ticket type; `false`: only those without | | `limit` | 1 to 20, default 10 | | `cursor` | The previous answer's `nextCursor`, for the next page (opaque) | ``` curl "https://oneticket.com.au/api/v1/events?q=yoga&city=darwin&limit=5" ``` ```json { "events": [ { "slug": "sunday-run-club", "title": "Sunday Run Club", "url": "https://oneticket.com.au/e/sunday-run-club", "bookUrl": "https://oneticket.com.au/e/sunday-run-club", "summary": "5 km along the foreshore, all paces.", "start": "2026-10-25T07:00:00+09:30", "end": "2026-10-25T08:30:00+09:30", "timezone": "Australia/Darwin", "online": false, "venue": "Mindil Beach", "location": "Mindil Beach, Gilruth Ave, The Gardens NT 0820", "organiser": { "name": "Top End Runners" }, "currency": "AUD", "priceFrom": 10, "free": false } ], "total": 1, "nextCursor": null } ``` `total` counts every match, across pages; while `nextCursor` is not null, pass it back as `cursor` for the next page. `priceFrom` is the lowest ticket price shown, before the booking fee (null for an event that sells nothing); `free` says a free ticket type is on offer. There is no city field: `city` looks in the place name and address. A series' sessions are listed soonest first, a few at a time; see `/api/v1/series/{slug}` for the rest. Never a draft, private, unlisted or password-protected event. ### GET /api/v1/events/{slug} A public event. ``` curl https://oneticket.com.au/api/v1/events/sunday-run-club ``` ```json { "event": { "slug": "sunday-run-club", "title": "Sunday Run Club", "url": "https://oneticket.com.au/e/sunday-run-club", "bookUrl": "https://oneticket.com.au/e/sunday-run-club", "summary": "5 km along the foreshore, all paces.", "description": "...", "dates": ["2026-10-19"], "startTime": "07:00", "endTime": "08:30", "timezone": "Australia/Darwin", "online": false, "location": "Mindil Beach, Gilruth Ave, The Gardens NT 0820", "image": "https://...", "organiser": { "name": "Top End Runners" }, "series": { "slug": "run-club", "title": "Run Club", "url": "https://oneticket.com.au/s/run-club" }, "refundPolicy": "Refundable up to 7 days before the event.", "refundPolicyDetails": "Refund policy for Sunday Run Club\n\nThis policy covers ...", "tickets": [ { "name": "General", "price": 10, "currency": "AUD", "free": false, "admits": 1, "remaining": 42, "soldOut": false, "onSale": true } ] } } ``` `price` is face value now; the attendee pays the booking fee on top (see "Fees"). A pay what you want type also has `"payWhatYouWant": true`, and its `price` is the least the attendee may pay. `admits` is how many people one ticket admits (1 to 8): the price is for all of them. `remaining` counts places (people), not tickets; it is left out when the organiser hides it, and `organiser` is null when the event page doesn't name them. `dates` are local calendar dates in `timezone`; an event over several days lists each. `bookUrl` is the event page itself: people book there. `refundPolicy` is who may refund, in the event page's words, and decides refunds; `refundPolicyDetails` is the organiser's own written policy shown under it (plain text with line breaks, or null). Both are null for an event that sells nothing. ### GET /api/v1/series/{slug} A public series and up to 50 of its public sessions still to come, soonest first: each session's slug, title, page link, date, start and end time, timezone, place (or "Online"), and whether it is sold out (with places left when the organiser shows them). Look a session up with `/api/v1/events/{slug}` for its ticket types. ### GET /api/v1/fees?price={number}¤cy={aud|usd|gbp} What a ticket at that price costs the attendee and what the organiser receives, from the same code the checkout charges with. `price` is 0 to 100000 in whole currency units; `currency` defaults to `aud`. ``` curl "https://oneticket.com.au/api/v1/fees?price=25¤cy=aud" ``` ```json { "currency": "AUD", "ticketPrice": 25, "bookingFee": 1.45, "attendeePays": 26.45, "organiserReceives": 25, "organiserPlatformFee": 0, "oneTicketKeeps": 0.7, "note": "The attendee pays the booking fee on top of the price; the organiser is paid the ticket price in full into their own Stripe account." } ``` ### GET /api/v1/stats `{"ticketsIssued": }` - every ticket issued through One Ticket and not voided, on an order that went through. Responses are cached for between one minute (events and series) and an hour (fees). Reads of events, series, the search and the stats are limited to 120 a minute for each network (the MCP server's tools share the limit): a 429 with `Retry-After` past it. There is no need to poll. ## MCP server Endpoint: `https://oneticket.com.au/mcp`. Transport: Streamable HTTP. Each POST carries one JSON-RPC 2.0 message (or a batch of 1 to 20) and is answered with `application/json`; a POST of notifications only is answered 202 with no body. The server is stateless: no session id, no sign-in, no event stream (a GET asking for `text/event-stream` is a 405). Methods: `initialize`, `ping`, `tools/list`, `tools/call`, `resources/list` and `prompts/list` (both empty). Protocol versions: 2025-06-18, 2025-03-26, 2024-11-05. Client configuration (for clients that take a URL): ```json { "mcpServers": { "oneticket": { "url": "https://oneticket.com.au/mcp" } } } ``` Tools (all read-only): | Tool | Arguments | Returns | |---|---|---| | `search_events` | optional `q`, `city`, `from`, `to`, `online`, `free`, `limit` (1 to 20), `cursor` | a page of upcoming events, `total` and `nextCursor` | | `get_event` | `slug` | the event, as in the REST API | | `get_series` | `slug` | the series and its upcoming public sessions | | `quote_ticket_fee` | `price`, optional `currency` (`aud`, `usd`, `gbp`) | the fee quote | | `get_platform_stats` | none | tickets issued | Each tool result has a JSON text block and `structuredContent`. A page that is not public comes back as a tool result with `isError: true` and a sentence saying so, not as a protocol error. Example: ``` curl -s https://oneticket.com.au/mcp \ -H 'content-type: application/json' \ -H 'accept: application/json, text/event-stream' \ -d '{"jsonrpc":"2.0","id":1,"method":"tools/call","params":{"name":"quote_ticket_fee","arguments":{"price":45}}}' ``` ## Fees - The organiser receives the full ticket price into their own Stripe account, on every plan: no organiser platform fee, no payout fee. - Free tickets cost nobody anything. - On a paid ticket the attendee pays a booking fee on top of the price: the platform tier below plus card processing, solved so that One Ticket nets exactly the tier after Stripe's fee. The booking fee is the same on every plan. On a pay what you want ticket it is worked out on the amount the attendee chooses. - On Pro and Team the organiser can absorb the booking fee: the attendee pays the ticket price only, and the fee comes out of the organiser's payout (a ticket under $1.34 still has the attendee pay it). Platform tier by ticket price (nominal in AUD, USD and GBP alike): | Ticket price | Tier | |---|---| | 0.01 - 5.00 | 0.35 | | 5.01 - 10.00 | 0.45 | | 10.01 - 25.00 | 0.70 | | 25.01 - 50.00 | 0.95 | | 50.01 - 100.00 | 1.45 | | over 100.00 | 1.45 + 1.5% of the amount above 100 | Booking fee formula, in cents, with Stripe's rate `r` and fixed fee `f` for the currency (AUD about 1.7% + 30c, USD about 2.9% + 30c, GBP about 1.5% + 20p): ``` bookingFee = ceil((tier + r * price + f) / (1 - r)) ``` then raised a cent at a time until the fee, less Stripe's estimate on the whole charge, still covers the tier. Use `GET /api/v1/fees` or the `quote_ticket_fee` tool rather than computing it: they run the checkout's own code. Plans, in AUD: Free ($0), Pro ($29 a month or $290 a year) and Team ($79 a month or $790 a year). Paid plans add features (absorbing the booking fee, extras sold with tickets such as a drink token or parking, pay what you want and donation tickets, partial refunds, the website widget and tracked links, the organiser page's banner, links and colours, premieres, which are pre-recorded webinars, replays, advanced reports, the verified tick once earned, the morning-after summary of each event, checkout reminders, more Assistant messages a month (100 on Pro and 300 on Team, against 10 on Free), more tickets and emails a day, team members), not a cheaper fee. Pro and Team are open now: upgrade any time in Settings › Plan. Limited-time offer: A$1 for your first year (first 100 organisers), then A$29/month for Pro or A$79/month for Team. Cancel anytime. The A$1 offer is for organisers on Free who have never paid for a plan, while spots last. A card is needed: A$1 is charged today, and the monthly price starts a year later unless you cancel. Organisers start on Free. Fees and features beside other Australian ticketing platforms, each from its own pages: https://oneticket.com.au/compare. ## Sending someone to book Link to the event's `url` (`bookUrl` is the same page). Checkout is Stripe; attendees do not need an account and receive their ticket by email with a QR code. Do not attempt to complete a booking on a person's behalf. ## What is not available - No write API: events are created in the organiser's dashboard. - No attendee, order or sales data: that belongs to each organiser. - No organiser lookup: the API and MCP server don't read organisers; an organiser's page is on the site, at `https://oneticket.com.au/o/{slug}`. - No meeting links or videos for online events: those go only to ticket holders. - No hidden ticket types or their access codes. - No private search: the search covers public, live, upcoming events only, looking at the soonest 1,000 of them. ## Crawling robots.txt allows crawlers on all public pages, on `/api/v1/`, on this file and on the discovery documents. App and account routes (dashboard, orders, check-in, sign-in) are disallowed and send noindex. Sitemaps: https://oneticket.com.au/sitemap.xml and https://oneticket.com.au/sitemap-pages.xml. Each product has its own page: https://oneticket.com.au/products/events, https://oneticket.com.au/products/subscriptions, https://oneticket.com.au/products/webinars, https://oneticket.com.au/products/replays, https://oneticket.com.au/products/door, https://oneticket.com.au/products/website-widget, https://oneticket.com.au/products/organiser-page, https://oneticket.com.au/products/reports, https://oneticket.com.au/products/assistant. ## Contact https://oneticket.com.au/support