Developers
Event API reference
Public event feeds and authenticated Event Publisher endpoints, schemas, and examples.
The Q2Tix Event API has two deliberately separate surfaces:
- a public, read-only event feed for websites, mobile apps, calendars, and AI tools; and
- an authenticated Event Publisher API for trusted integrations that create and update an account's events and ticket types.
The API is versioned at /api/v1. The canonical base URL is the configured
API_URL, currently https://api.q2tix.com.
Public Event Feed
The public feed requires no key and only returns live events. It does not provide checkout, attendee, customer, order, payment, or account data.
List events
GET /api/v1/events
Query parameters:
| Parameter | Values | Default | Notes |
|---|---|---|---|
organiser_id |
organizer ID | none | Limits results to one organizer. |
filter |
upcoming, past, all |
upcoming |
upcoming includes events whose end time has not passed. |
per_page |
1 to 100 |
25 |
Standard Laravel pagination is returned in links and meta. |
Example:
curl 'https://api.q2tix.com/api/v1/events?organiser_id=1&filter=upcoming&per_page=25'
Retrieve an event
GET /api/v1/events/{event_id}
Example:
curl 'https://api.q2tix.com/api/v1/events/42'
Both endpoints return a data object. The list endpoint additionally includes
Laravel pagination links and meta objects.
Public event schema
Every event has api_version: "v1" and type: "event". Fields may be null
when an organizer has not supplied that optional detail.
event.performers is an optional lineup, returned as [] when empty. Each
entry has a public/stage name and a type: Person (individual) or
PerformingGroup (group/band). The Event Publisher API accepts the same
performers array on event create/update; send [] to clear the lineup.
Names are limited to 200 characters and lineups to 50 performers. The lineup
is displayed in event details and included in Google Event JSON-LD.
{
"data": {
"api_version": "v1",
"id": 42,
"type": "event",
"seo": {
"title": "Example Event",
"description": "A concise public description.",
"canonical_url": "https://tickets.example.com/e/42/example-event"
},
"event": {
"title": "Example Event",
"subtitle": "One night only",
"description": "Public event description.",
"short_description": "A concise public description.",
"category": "Music",
"genre": "House",
"performers": [{"name": "Example DJ", "type": "Person"}],
"age_restriction": "21+",
"is_featured": false
},
"schedule": {
"starts_at": "2026-11-14T20:00:00-06:00",
"ends_at": "2026-11-14T23:00:00-06:00",
"doors_at": "2026-11-14T19:00:00-06:00",
"display": "Saturday, November 14, 2026"
},
"status": {
"is_live": true,
"publication_status": "published",
"visibility": "public"
},
"organizer": {
"id": 1,
"name": "Example Presents",
"url": "https://tickets.example.com/o/example-presents"
},
"venue": {
"id": 8,
"name": "Example Venue",
"address": {
"line_1": "100 Main Street",
"line_2": null,
"city": "Des Moines",
"state": "IA",
"postal_code": "50309",
"country": "United States",
"country_code": "US"
},
"geo": {
"latitude": 41.5868,
"longitude": -93.625
}
},
"offers": {
"currency": "USD",
"price_min": "15.00",
"price_max": "35.00",
"has_free_tickets": false,
"available_for_purchase": true,
"ticket_count": 2
},
"images": {
"original": { "url": "https://…", "path": "event_images/…" },
"variants": {
"open_graph": {
"label": "Open Graph",
"width": 1200,
"height": 630,
"mime_type": "image/webp",
"url": "https://…",
"generated": true
}
}
},
"links": {
"canonical": "https://tickets.example.com/e/42/example-event",
"event_page": "https://tickets.example.com/e/42/example-event",
"ticket_purchase": "https://tickets.example.com/e/42/example-event#tickets",
"calendar_ics": "https://tickets.example.com/event/42/calendar.ics",
"api": "https://api.q2tix.com/api/v1/events/42"
},
"platform_ids": {}
}
}
images.variants provides the named image targets Q2Tix generated for the
event. A target is present even when no image is available; use its url only
when generated is true. platform_ids is an object keyed by external
platform name and is empty when the event has no platform identifiers.
Use links.ticket_purchase for a buyer-facing deep link. Q2Tix intentionally
does not offer a raw purchase API.
Event Publisher API
The Event Publisher API is for trusted account automation, including the Q2Tix remote MCP integration. It may manage events, locations, organizers, and ticket types, but it cannot access attendees, customers, orders, payments, refunds, or account settings.
Authentication
Create an Integration Key from Organizer Menu > Account Settings > Integrations. The secret is shown once, stored hashed, and may be rotated or revoked. Send it as a bearer token:
Authorization: Bearer qst_your_integration_key
Accept: application/json
Content-Type: application/json
Do not put an Integration Key in source control, a public client, or an
application .env file. A key is scoped to its account and the Event Publisher
capability. Expired or revoked keys return 401 Unauthorized.
Connection and account setup data
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/management/connection |
Confirm the authenticated account and Event Publisher capability. |
GET |
/api/v1/management/organisers |
List organizers in the account. |
GET |
/api/v1/management/locations |
List reusable locations in the account. |
Call connection before making changes. It returns the account and principal
context without exposing credentials.
Events
| Method | Path | Purpose |
|---|---|---|
GET |
/api/v1/management/events |
List events available to the authenticated principal. |
POST |
/api/v1/management/events |
Create an event. |
GET |
/api/v1/management/events/{event_id} |
Retrieve an event. |
PATCH |
/api/v1/management/events/{event_id} |
Update supplied event fields. |
PUT |
/api/v1/management/events/{event_id}/live |
Set publication state. |
POST |
/api/v1/management/events/{event_id}/copy-images |
Copy an event's images to a separate event. |
The list endpoint accepts organiser_id, search, status (live or
draft), and per_page (1 to 100). Event Publisher users with limited
event access receive only their assigned events.
Create a draft event:
curl -X POST 'https://api.q2tix.com/api/v1/management/events' \
-H 'Authorization: Bearer qst_your_integration_key' \
-H 'Content-Type: application/json' \
-d '{
"title": "Friday Late Set",
"description": "A late-night music event.",
"organiser_id": 1,
"location_id": 8,
"start_at": "2026-11-14T20:00:00-06:00",
"end_at": "2026-11-14T23:00:00-06:00",
"subtitle": "House and disco after dark",
"genre": "House",
"doors_at": "2026-11-14T19:00:00-06:00"
}'
Required create fields are title, description, organiser_id,
location_id, start_at, and end_at. Dates use ISO 8601 values with a
timezone offset. end_at must be after start_at; doors_at, when supplied,
must be before start_at.
Optional event fields are on_sale_at, is_live, subtitle, seo_title,
seo_description (up to 500 characters), category, genre,
age_restriction, doors_at, and is_featured. A newly created event copies
the account's default terms and conditions.
Also supported: performers, visibility (public, unlisted, private),
sale_notifications_enabled (boolean), and terms_and_conditions (nullable,
up to 50,000 characters). PATCH changes only supplied fields. Notifications use
the existing availability checks and scheduler; changing the switch does not
directly send mail. Event responses include these settings plus add_ons,
access_codes, and primary/variant images URLs. Publication responses now
include performers, visibility, publication status, and is_featured.
Publishing is separately guarded. Eligible new accounts can publish up to five
free events before connecting Stripe. Paid events and additional free-event
publications require the account's connected Stripe account to have charges and
payouts enabled before setting is_live to true succeeds.
curl -X PUT 'https://api.q2tix.com/api/v1/management/events/42/live' \
-H 'Authorization: Bearer qst_your_integration_key' \
-H 'Content-Type: application/json' \
-d '{"is_live":true}'
Copy images into a target event. By default Q2Tix refuses to overwrite target
images; use replace_existing: true only when that replacement is intended.
Copied primary images and variants are independent files.
curl -X POST 'https://api.q2tix.com/api/v1/management/events/42/copy-images' \
-H 'Authorization: Bearer qst_your_integration_key' \
-H 'Content-Type: application/json' \
-d '{"target_event_id":43,"replace_existing":false}'
Ticket types
| Method | Path | Purpose |
|---|---|---|
POST |
/api/v1/management/events/{event_id}/tickets |
Create a ticket type. |
PATCH |
/api/v1/management/events/{event_id}/tickets/{ticket_id} |
Update supplied ticket fields. |
Create a ticket type:
curl -X POST 'https://api.q2tix.com/api/v1/management/events/42/tickets' \
-H 'Authorization: Bearer qst_your_integration_key' \
-H 'Content-Type: application/json' \
-d '{
"title": "General Admission",
"price": 20,
"quantity_available": 150,
"min_per_person": 1,
"max_per_person": 8
}'
Required fields are title and price. Optional fields are description,
quantity_available, start_sale_at, end_sale_at, min_per_person,
max_per_person, is_hidden, and is_paused. end_sale_at must be after
start_sale_at when both are set.
Ticket create/update also supports sort_order (nonnegative integer, lower
first) and access_code_ids (array of nondeleted codes belonging to this event).
An explicit empty array clears code assignments. On multi-showtime events,
creation requires showtime_id; an existing ticket cannot be moved between
performances. Partial date edits validate against the current stored boundary.
Add-ons, showtimes, and unlock codes
All paths below are relative to /api/v1/management and require the same
Event Publisher credentials and account/event access as event editing.
| Method | Path | Purpose |
|---|---|---|
GET |
/events/{event}/add-ons |
List active/inactive items, prices, artwork URLs, and ticket restrictions. |
POST |
/events/{event}/add-ons |
Create a paid add-on. |
PATCH |
/events/{event}/add-ons/{addOn} |
Edit supplied fields; is_active:false stops sales. |
POST |
/events/{event}/copy-add-ons |
Copy source items into a target event. |
POST |
/events/{event}/showtimes |
Create/enable a performance using the portal scheduling service. |
PATCH |
/events/{event}/showtimes/{showtime} |
Edit supplied schedule fields, label, doors, or availability. |
POST |
/events/{event}/access-codes |
Create a unique, uppercased event unlock code. |
Add-on creation requires title and price (positive, at most 999999, up to
two decimal places). Optional fields: description (nullable, 5000 characters),
is_active (default true), all_ticket_types, and ticket_ids (same event).
Omitted restrictions on create mean all tickets; omitted fields on PATCH retain
existing values. all_ticket_types:false requires a nonempty eligible ticket
list. To remove restrictions, explicitly set all_ticket_types:true.
Copying requires target_event_id; optional add_on_ids selects a source subset
(otherwise all). Ticket-restricted items require ticket_mappings, for example
[{"source_ticket_id":12,"target_ticket_id":34}]. All referenced source tickets
must map into the target event. Images are independent files on the configured
add-on disk. Sales/order items are never copied. A nonempty target requires
append:true; this adds copies and never replaces existing items. Repeating an
append request is not idempotent. Inspect the target before retrying a request
whose outcome is unknown.
Showtime creation requires start_at and end_at (ISO 8601 with offset).
Optional label (nullable, 100 characters), doors_at (nullable, no later than
start), and is_active (default true) are also patchable. Values normalize to the
account timezone, and responses include the matching offset. The first showtime
adopts existing tickets; later ones copy ticket types without sales. Existing
orders/reservations block first-time activation. Master event dates cannot be
updated directly once showtimes exist.
Unlock-code creation accepts code (1-255 characters after trimming), rejects
event-level duplicates case-insensitively, and returns its ID. Assign it through
ticket access_code_ids; code creation alone does not hide a ticket.
See MCP publisher capability audit for the remaining portal-only operations and security boundary.
Error handling and compatibility
401: the bearer key is missing, expired, revoked, or invalid.404: the requested record does not exist in the authenticated account or is not assigned to the authenticated Event Publisher.422: validation or a publishing precondition failed. Laravel returns field errors undererrors, for exampleerrors.doors_at.429: respect rate-limit responses if they are enabled by the host.5xx: treat as transient; do not blindly retry non-idempotent creates.
v1 is the stable contract. Q2Tix may add optional fields within v1, but a
breaking change will use a new versioned path. Clients should ignore fields
they do not use and should not treat unknown fields as errors.
Related integration surfaces
- MCP: trusted AI agents can use
https://q2tix.com/mcpwith the same Integration Key. See MCP Server Guide. - Public calendar: each public event includes an
.icslink atlinks.calendar_ics. - Buyer pages: use
links.event_pageandlinks.ticket_purchase; do not attempt to recreate checkout through the API.