Events
Operator endpoints for running events: create and edit an event, move it
through its lifecycle, request an app listing, read stats and the door list, and
manage the event’s ticket types. All routes require the
operator role (client); stats, bookings
and conflict-check also accept an organiser.
Endpoints
Section titled “Endpoints”| Method | Path | Purpose | Auth |
|---|---|---|---|
| GET | /api/my-events |
List events across your venues | operator |
| GET | /api/my-venues/:id/events |
List events for one venue | operator |
| POST | /api/my-events |
Create an event | operator |
| PUT | /api/my-events/:id |
Update an event | operator |
| PATCH | /api/my-events/:id/status |
Set status (approved/draft/cancelled/rejected) | operator |
| POST | /api/my-events/:id/approve |
Approve a pending/rejected event | operator |
| POST | /api/my-events/:id/reject |
Reject an event | operator |
| POST | /api/my-events/:id/request-listing |
Request the in-app listing | operator |
| POST | /api/my-events/:id/withdraw-listing |
Withdraw a pending listing | operator |
| DELETE | /api/my-events/:id |
Delete an event (no bookings) | operator |
| GET | /api/my-events/:id/stats |
Aggregate stats for an event | operator |
| GET | /api/my-events/:id/bookings |
Bookings/door list for an event | operator |
| GET | /api/events/conflict-check |
Check for a same-day event clash | operator |
| POST | /api/my-events/image |
Upload a cover image | operator |
| POST | /api/my-events/generate-image |
Generate a cover image (Unsplash) | operator |
| GET | /api/my-events/:eventId/ticket-types |
List ticket types | operator |
| POST | /api/my-events/:eventId/ticket-types |
Create a ticket type | operator |
| PUT | /api/my-events/:eventId/ticket-types/:ticketId |
Update a ticket type | operator |
| DELETE | /api/my-events/:eventId/ticket-types/:ticketId |
Delete a ticket type | operator |
List events
Section titled “List events”Fetch events across every venue you can access (paginated), or scope to one
venue with /api/my-venues/:id/events.
curl "https://thesidedoor.co/api/my-events?page=1&limit=50" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-events?page=1&limit=50", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events?page=1&limit=50");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": [ { "id": "evt_9f2", "name": "Friday Rooftop Sessions", "event_date": "2026-07-17", "start_time": "21:00", "end_time": "03:00", "event_type": "club_night", "status": "approved", "visibility": "public", "guest_list_capacity": 300, "committed_guests": 128, "venue_id": "ven_123", "venue_name": "The Attic" } ], "total": 1, "limit": 50, "offset": 0, "has_more": false}Create an event
Section titled “Create an event”Create a ticketed event on one of your venues. venue_id, name and
event_date are required; the venue is fixed once created. Set
status: "approved" to publish immediately, otherwise it is saved as a
draft. event_mode is always ticketed and visibility is always public.
curl -X POST "https://thesidedoor.co/api/my-events" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{ "venue_id": "VENUE_ID", "name": "Friday Rooftop Sessions", "event_date": "2026-07-17", "start_time": "21:00", "end_time": "03:00", "last_entry_time": "01:00", "event_type": "club_night", "event_genre": "house", "description": "Resident DJs on the rooftop.", "guest_list_capacity": 300, "status": "approved" }'const res = await fetch("https://thesidedoor.co/api/my-events", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ venue_id: "VENUE_ID", name: "Friday Rooftop Sessions", event_date: "2026-07-17", start_time: "21:00", end_time: "03:00", last_entry_time: "01:00", event_type: "club_night", event_genre: "house", description: "Resident DJs on the rooftop.", guest_list_capacity: 300, status: "approved", }),});const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "venue_id" => "VENUE_ID", "name" => "Friday Rooftop Sessions", "event_date" => "2026-07-17", "start_time" => "21:00", "end_time" => "03:00", "last_entry_time" => "01:00", "event_type" => "club_night", "event_genre" => "house", "description" => "Resident DJs on the rooftop.", "guest_list_capacity" => 300, "status" => "approved", ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "id": "evt_9f2", "cancelled_bookings": 0 }If an approved or pending event already exists on that venue and date the call
returns 409 with { "error": "...", "conflict": { "event_id": "evt_1", "name": "..." } }.
Update an event
Section titled “Update an event”Same fields as create, minus venue_id. Date/time changes are blocked once
bookings exist, capacity cannot drop below the committed count, and a live event
with committed guests cannot be flipped back to draft.
curl -X PUT "https://thesidedoor.co/api/my-events/EVENT_ID" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Rooftop Sessions - Summer Finale","guest_list_capacity":350}'const res = await fetch("https://thesidedoor.co/api/my-events/EVENT_ID", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Rooftop Sessions - Summer Finale", guest_list_capacity: 350, }),});const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "name" => "Rooftop Sessions - Summer Finale", "guest_list_capacity" => 350, ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true }Change status
Section titled “Change status”Set an event’s status directly. Valid values are approved, draft,
cancelled and rejected. Changing status while active bookings exist returns
409; cancelled cascades to cancel and refund every attached booking.
curl -X PATCH "https://thesidedoor.co/api/my-events/EVENT_ID/status" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"status":"cancelled"}'const res = await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/status", { method: "PATCH", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ status: "cancelled" }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/status");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PATCH", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode(["status" => "cancelled"]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "status": "cancelled" }Approve or reject
Section titled “Approve or reject”When an event was submitted by a promoter it arrives as
pending_venue_approval. Approve it to publish, or reject it. Neither call
takes a body.
curl -X POST "https://thesidedoor.co/api/my-events/EVENT_ID/approve" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"
curl -X POST "https://thesidedoor.co/api/my-events/EVENT_ID/reject" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"await fetch("https://thesidedoor.co/api/my-events/EVENT_ID/approve", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` },});$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/approve");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "success": true, "cancelled_bookings": 0 }Request or withdraw the in-app listing
Section titled “Request or withdraw the in-app listing”An approved event can request a listing in the Sidedoor guest app. Withdraw
removes a listing while it is still pending.
curl -X POST "https://thesidedoor.co/api/my-events/EVENT_ID/request-listing" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/request-listing", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/request-listing");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "app_listing_status": "pending" }Delete an event
Section titled “Delete an event”Deletes a draft or unpublished event. Blocked with 409 if any bookings exist.
curl -X DELETE "https://thesidedoor.co/api/my-events/EVENT_ID" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch("https://thesidedoor.co/api/my-events/EVENT_ID", { method: "DELETE", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` },});const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "DELETE", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "success": true }Stats and bookings
Section titled “Stats and bookings”GET /api/my-events/:id/stats returns aggregate counts and revenue;
GET /api/my-events/:id/bookings returns the event’s booking/door list.
curl "https://thesidedoor.co/api/my-events/EVENT_ID/stats" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/stats", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/stats");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "capacity": 300, "event_mode": "ticketed", "total_bookings": 142, "active_bookings": 128, "approved": 120, "pending": 8, "checked_in": 96, "cancelled": 10, "committed_guests": 128, "revenue": 384000, "timeline": [{ "date": "2026-07-10", "count": 24 }], "recent": [ { "id": "bkg_a1", "status": "approved", "guest_count": 4, "user_name": "Sam Lee" } ]}Conflict check
Section titled “Conflict check”Before scheduling, check whether an event already occupies a venue on a date.
Pass exclude_event_id when editing an existing event.
curl "https://thesidedoor.co/api/events/conflict-check?venue_id=VENUE_ID&date=2026-07-17" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/events/conflict-check?venue_id=VENUE_ID&date=2026-07-17", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/events/conflict-check?venue_id=VENUE_ID&date=2026-07-17");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "has_event_conflict": true, "events": [{ "id": "evt_1", "name": "Jazz Night", "status": "approved" }], "affected_bookings": 3, "affected_guests": 11}Cover image
Section titled “Cover image”Upload a base64 data-URL (max 2 MB) with POST /api/my-events/image, or
generate one from Unsplash with POST /api/my-events/generate-image. Put the
returned url into the event’s image_url.
curl -X POST "https://thesidedoor.co/api/my-events/generate-image" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Friday Rooftop Sessions","event_type":"club_night"}'const res = await fetch( "https://thesidedoor.co/api/my-events/generate-image", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Friday Rooftop Sessions", event_type: "club_night", }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/generate-image");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "name" => "Friday Rooftop Sessions", "event_type" => "club_night", ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "url": "https://images.unsplash.com/photo-...", "attribution": { "photographer": "Jane Doe", "photographer_url": "https://unsplash.com/@janedoe", "unsplash_url": "https://unsplash.com/photos/..." }}Ticket types
Section titled “Ticket types”Each ticketed event has one or more ticket types. Prices are in pence; a null
capacity means unlimited. admission_rule_group_id and ticket_profile_id
link a ticket to admission rules and an access profile.
List ticket types
Section titled “List ticket types”curl "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": [ { "id": "tkt_a1", "event_id": "evt_9f2", "name": "General Admission", "price_pence": 1500, "capacity": 200, "sort_order": 0 } ]}Create a ticket type
Section titled “Create a ticket type”name is required; everything else is optional.
curl -X POST "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"General Admission","price_pence":1500,"capacity":200,"sort_order":0}'const res = await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "General Admission", price_pence: 1500, capacity: 200, sort_order: 0, }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "name" => "General Admission", "price_pence" => 1500, "capacity" => 200, "sort_order" => 0, ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "id": "tkt_a1" }Update or delete a ticket type
Section titled “Update or delete a ticket type”PUT takes the same body as create (name required); DELETE takes no body.
curl -X PUT "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types/TICKET_ID" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Early Bird","price_pence":1000,"capacity":50}'
curl -X DELETE "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types/TICKET_ID" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"await fetch( "https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types/TICKET_ID", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Early Bird", price_pence: 1000, capacity: 50 }), },);$ch = curl_init("https://thesidedoor.co/api/my-events/EVENT_ID/ticket-types/TICKET_ID");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "name" => "Early Bird", "price_pence" => 1000, "capacity" => 50, ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true }