Branding & widgets
Branding controls the look of a venue’s widgets and branded emails; widget
settings enable the embeddable flows and mint the public_id used in the embed
URL. Every endpoint is under /api/my-venues/:venueId/… and is operator
(client role, venue-scoped) - send an Authorization: Bearer token from the
Authentication flow. Image uploads are base64 data
URLs in a data field (multipart is rejected at the edge). For the operator-side
walkthrough see Widgets; to embed the resulting snippet see
the embed reference.
| Method | Path | Purpose | Auth |
|---|---|---|---|
| GET | /api/my-venues/:venueId/branding |
Get branding | operator |
| PUT | /api/my-venues/:venueId/branding |
Update branding colours/font | operator |
| POST | /api/my-venues/:venueId/branding-logo |
Upload brand logo | operator |
| POST | /api/my-venues/:venueId/cover-image |
Upload/remove cover image | operator |
| GET | /api/my-venues/:venueId/widget-settings |
List widget settings + theme | operator |
| PUT | /api/my-venues/:venueId/widget-settings/:type |
Enable/disable a widget | operator |
| PUT | /api/my-venues/:venueId/widget-theme |
Update widget presentation | operator |
| POST | /api/my-venues/:venueId/widget-logo |
Upload a widget logo | operator |
Branding
Section titled “Branding”GET /api/my-venues/:venueId/branding returns the brand record (or defaults).
PUT updates the colours and font: theme (preset name, e.g. classic),
accent_color, bg_color, text_color (hex) and font_key (serif, sans or
mono). The logo is set separately via branding-logo, not here.
Set branding colours
Section titled “Set branding colours”curl -X PUT "https://thesidedoor.co/api/my-venues/VENUE_ID/branding" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"theme":"midnight","accent_color":"#C0A060","bg_color":"#0A0806","text_color":"#F5F1E8","font_key":"serif"}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/branding", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ theme: "midnight", accent_color: "#C0A060", bg_color: "#0A0806", text_color: "#F5F1E8", font_key: "serif", }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/branding");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "theme" => "midnight", "accent_color" => "#C0A060", "bg_color" => "#0A0806", "text_color" => "#F5F1E8", "font_key" => "serif", ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true }Upload a brand logo or cover image
Section titled “Upload a brand logo or cover image”POST /api/my-venues/:venueId/branding-logo stores a logo (max 2 MB) on the brand
record; POST /api/my-venues/:venueId/cover-image stores a cover photo (max
3 MB) on the venue, or removes it with { "remove": true }. Both return the
stored url.
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/branding-logo" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"data":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..."}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/branding-logo", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", }), },);const { url } = await res.json();$dataUrl = "data:image/png;base64," . base64_encode(file_get_contents("logo.png"));$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/branding-logo");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode(["data" => $dataUrl]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "url": "/assets/branding/VENUE_ID.png" }Widget settings
Section titled “Widget settings”GET /api/my-venues/:venueId/widget-settings returns per-type settings keyed by
widget type (bookings, events, vouchers, combo), a global theme object
and vouchers_enabled. It lazily mints a stable public_id for every type, so
each always has a shareable id.
curl "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN"const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings", { headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}` } },);const { data, theme, vouchers_enabled } = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings");curl_setopt_array($ch, [ CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => ["Authorization: Bearer {$token}"],]);$data = json_decode(curl_exec($ch), true);{ "data": { "bookings": { "widget_type": "bookings", "enabled": 0, "public_id": "3f2a9c7e-..." }, "events": { "widget_type": "events", "enabled": 0, "public_id": "8b1d..." }, "vouchers": { "widget_type": "vouchers", "enabled": 0, "public_id": "a4c9..." }, "combo": { "widget_type": "combo", "enabled": 0, "public_id": "d7e2..." } }, "theme": { "accent_color": "#C0A060", "width": "medium", "theme_mode": "detailed" }, "vouchers_enabled": false}Enable a widget
Section titled “Enable a widget”PUT /api/my-venues/:venueId/widget-settings/:type where :type is one of
bookings, events, vouchers, combo. Send { enabled: true }; you may also
pass width (narrow/medium/wide) and custom_css, which write through to
the global theme. The response returns the stable public_id - embed the widget
at https://thesidedoor.co/widget/<public_id>. Enabling vouchers requires gift
vouchers to be switched on first, otherwise you get a 400.
curl -X PUT "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings/bookings" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"enabled":true,"width":"medium"}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings/bookings", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ enabled: true, width: "medium" }), },);const { public_id } = await res.json();$ch = curl_init( "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-settings/bookings");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode(["enabled" => true, "width" => "medium"]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "public_id": "3f2a9c7e-1b8d-4c2a-9f11-6a0e5d3b2c47" }Update the widget theme
Section titled “Update the widget theme”PUT /api/my-venues/:venueId/widget-theme sets global presentation shared by all
widgets: width (narrow/medium/wide), theme_mode (minimal/detailed),
custom_css (max 20000 chars) and the show_map, show_about, show_tandc,
show_info_card, show_contact toggles. It deliberately leaves colours, logo and
font untouched (those are on branding).
curl -X PUT "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-theme" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"width":"wide","theme_mode":"detailed","show_map":true,"show_about":true,"show_tandc":true,"show_info_card":true,"show_contact":false}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-theme", { method: "PUT", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ width: "wide", theme_mode: "detailed", show_map: true, show_about: true, show_tandc: true, show_info_card: true, show_contact: false, }), },);const data = await res.json();$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/widget-theme");curl_setopt_array($ch, [ CURLOPT_CUSTOMREQUEST => "PUT", CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode([ "width" => "wide", "theme_mode" => "detailed", "show_map" => true, "show_about" => true, "show_tandc" => true, "show_info_card" => true, "show_contact" => false, ]),]);$data = json_decode(curl_exec($ch), true);{ "success": true }Upload a widget logo
Section titled “Upload a widget logo”POST /api/my-venues/:venueId/widget-logo stores a per-type widget logo (max
2 MB); pass data (base64 data URL) and type (defaults to bookings). It
returns the url only - save it where you need it.
curl -X POST "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-logo" \ -H "Authorization: Bearer $SIDEDOOR_TOKEN" \ -H "Content-Type: application/json" \ -d '{"data":"data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...","type":"bookings"}'const res = await fetch( "https://thesidedoor.co/api/my-venues/VENUE_ID/widget-logo", { method: "POST", headers: { Authorization: `Bearer ${process.env.SIDEDOOR_TOKEN}`, "Content-Type": "application/json", }, body: JSON.stringify({ data: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...", type: "bookings", }), },);const { url } = await res.json();$dataUrl = "data:image/png;base64," . base64_encode(file_get_contents("wlogo.png"));$ch = curl_init("https://thesidedoor.co/api/my-venues/VENUE_ID/widget-logo");curl_setopt_array($ch, [ CURLOPT_POST => true, CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => [ "Authorization: Bearer {$token}", "Content-Type: application/json", ], CURLOPT_POSTFIELDS => json_encode(["data" => $dataUrl, "type" => "bookings"]),]);$data = json_decode(curl_exec($ch), true);{ "success": true, "url": "/assets/widget-logos/VENUE_ID/bookings.png" }