Guests
The guests CRM endpoints expose your operator guest roster: search across everyone who has booked with your venues, drill into a single guest’s history, billing and social network, apply tags, and create lightweight walk-in guests. All guests-CRM routes require the operator role and are scoped to your own account and venues.
Endpoints
Section titled “Endpoints”| Method | Path | Purpose | Auth |
|---|---|---|---|
| GET | /api/my-guests |
Guest roster (paginated) | operator |
| GET | /api/my-guests/search |
Search the roster | operator |
| GET | /api/my-guests/network |
Full operator guest graph | operator |
| GET | /api/my-guests/:id |
One guest with bookings, stats, tags | operator |
| GET | /api/my-guests/:id/billing |
Guest billing ledger | operator |
| GET | /api/my-guests/:id/activity |
Recent activity (last 10) | operator |
| GET | /api/my-guests/:id/bookings |
All of a guest’s bookings | operator |
| GET | /api/my-guests/:id/network |
1-hop network around a guest | operator |
| PUT | /api/my-guests/:id/tags |
Replace a guest’s tags at a scope | operator |
| GET | /api/my-venues/:venueId/guests/search |
Venue-scoped guest search | operator |
| POST | /api/my-venues/:venueId/guests/walk-in |
Create a walk-in guest | operator |
Search guests
Section titled “Search guests”Roster search matches name, email or phone (minimum 2 characters, capped at 50
results). Use /api/my-guests with pagination to page the whole roster.
curl "https://thesidedoor.co/api/my-guests/search?q=sam" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-guests/search?q=sam", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-guests/search?q=sam");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": [ { "id": "usr_abc", "name": "Sam Lee", "email": "sam@example.com", "phone": "+44...", "membership_tier": "black", "loyalty_points": 240, "successful_visits": 12, "venue_ids": "ven_123,ven_456" } ]}Fetch a guest
Section titled “Fetch a guest”GET /api/my-guests/:id returns the guest with their recent bookings, aggregate
stats and tags (global and per-venue).
curl "https://thesidedoor.co/api/my-guests/usr_abc" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch("https://thesidedoor.co/api/my-guests/usr_abc", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` },});const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-guests/usr_abc");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "guest": { "id": "usr_abc", "name": "Sam Lee", "email": "sam@example.com", "membership_tier": "black", "phone": "+44..." }, "bookings": [ { "id": "bkg_9a1", "status": "checked_in", "guest_count": 4, "booking_date": "2026-06-20", "venue_name": "The Attic" } ], "stats": { "loyalty_points": 240, "confirmed_visits": 12, "door_rejections": 0, "total_bookings": 15, "keys_spent": 30 }, "is_connection": false, "tags": { "global": ["vip"], "per_venue": [{ "venue_id": "ven_123", "venue_name": "The Attic", "tags": ["regular"] }] }}The related reads - GET /api/my-guests/:id/billing, /activity, /bookings
and /network - follow the same auth and path shape:
curl "https://thesidedoor.co/api/my-guests/usr_abc/billing" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-guests/usr_abc/billing", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-guests/usr_abc/billing");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": [ { "id": "led_1", "type": "spend", "delta": -5000, "note": "Table deposit", "booking_id": "bkg_9a1", "created_at": "2026-06-20T20:00:00Z" } ]}Tag a guest
Section titled “Tag a guest”Replace a guest’s tags at a scope. scope is global (default) or venue;
when venue, pass the venue_id. Tags are sent as an array and fully replace
the existing set at that scope.
curl -X PUT "https://thesidedoor.co/api/my-guests/usr_abc/tags" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"scope":"venue","venue_id":"VENUE_ID","tags":["regular","big-spender"]}'const res = await fetch( "https://thesidedoor.co/api/my-guests/usr_abc/tags", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ scope: "venue", venue_id: "VENUE_ID", tags: ["regular", "big-spender"], }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-guests/usr_abc/tags");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "scope" => "venue", "venue_id" => "VENUE_ID", "tags" => ["regular", "big-spender"], ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true }Guest network graph
Section titled “Guest network graph”GET /api/my-guests/network returns the whole operator guest graph; /:id/network
returns a one-hop graph centred on a guest.
curl "https://thesidedoor.co/api/my-guests/usr_abc/network" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-guests/usr_abc/network", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-guests/usr_abc/network");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "nodes": [ { "id": "usr_abc", "name": "Sam Lee", "degree": 3, "followers": 1200, "verified": true, "tier": "black", "centre": true }, { "id": "usr_def", "name": "Alex Ray", "degree": 5, "followers": 340, "verified": false, "tier": "gold" } ], "edges": [{ "source": "usr_abc", "target": "usr_def" }], "centre_id": "usr_abc"}Venue-scoped search
Section titled “Venue-scoped search”GET /api/my-venues/:venueId/guests/search is a compact search (min 2 chars,
12 results) for picking a guest when creating a booking at a specific venue.
curl "https://thesidedoor.co/api/my-venues/VENUE_ID/guests/search?q=sam" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/guests/search?q=sam", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/guests/search?q=sam");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": [ { "id": "usr_abc", "name": "Sam Lee", "email": "sam@example.com", "phone": "+44...", "profile_image_url": null } ]}Create a walk-in guest
Section titled “Create a walk-in guest”Create a lightweight guest for someone booking on the night. Only name is
required; a missing email is synthesised. Use the returned id as the user_id
when creating a staff booking.
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/guests/walk-in" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"name":"Jordan Fox","phone":"+44..."}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/guests/walk-in", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ name: "Jordan Fox", phone: "+44..." }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/guests/walk-in");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode(["name" => "Jordan Fox", "phone" => "+44..."]),]);$data = json_decode(curl_exec($ch), true);{ "id": "usr_walkin1", "name": "Jordan Fox", "email": "walkin-1a2b3c4d@local", "phone": "+44..." }A guest’s Sidedoor score and its breakdown are included in the guest detail
(GET /api/my-guests/:id) for guests at your own venues.