Anmelden um den Slug und den veröffentlichbaren Schlüssel Ihrer Location in jedem Beispiel zu sehen.
Ihr Konto hat noch keine Location, die Beispiele behalten daher ihre Platzhalter. Abmelden
Angemeldet als · . Legen Sie in der Konsole einen veröffentlichbaren Schlüssel an und laden Sie die Seite neu, um ihn hier zu sehen. Abmelden
Angemeldet als · . Die Beispiele zeigen den veröffentlichbaren Schlüssel Ihrer Location. Abmelden
Entwicklerdokumentation
Venue
Profil, Geschäftsdaten, Öffnungszeiten, Speisekarten, buchbare Ressourcen und Raumplan der Location lesen – die sechs GETs, mit denen jede Integration beginnt.
Sechs Lesezugriffe beschreiben eine Location vollständig. Sie sind günstig, auf Ihrer Seite cachebar und ändern sich nur, wenn der Betreiber etwas in der Konsole bearbeitet. Alle nehmen den Slug der Location im Pfad, brauchen einen Schlüssel (Schlüssel und Header) und antworten mit 404 und einem Problem-Body, wenn keine Location diesen Slug hat.
Endpunkte
GET /api/venues/{venueSlug}
Das öffentliche Profil der Location: Name, Beschreibung, Ort, Zeitzone, welche Ressourcentypen sie anbietet und – sofern vom Betreiber eingerichtet – kostenpflichtige Extras und die Buchungsdauern, die ein Gast je Ressourcentyp wählen darf.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug |
string | Der Bezeichner, den Sie in der URL verwendet haben |
name, tagline, description |
string | Anzeigetexte in der Sprache der Location |
city, country |
string | Ort, wie Gäste ihn sehen |
timezone |
string | IANA-Zeitzone, in der jedes Datum und jede Uhrzeit dieser Location liegt |
resourceTypes |
string[] | Die Typen, die diese Location anbietet: RestaurantTable, BilliardTable, DartBoard, Shuffleboard, BowlingLane, EventArea |
extras |
object[] oder null | Kostenpflichtige Zusatzleistungen: id, name, description, price, currency, basis (PerPerson oder PerBooking), appliesTo (Ressourcentypen) |
bookingDurations |
object[] oder null | Je Typ: type, defaultMinutes, minMinutes, maxMinutes, stepMinutes, guestSelectable, options (die wählbaren Minuten, fertig für eine Auswahl) |
{
"slug": "demo-sportsbar",
"name": "The Neon Tap",
"tagline": "Sports bar, kitchen & game house",
"description": "A neighbourhood sports bar where guests come to dine, drink, watch the match, and play. Reserve a table for the big game, book a billiard table or dart board by the hour, or take the whole mezzanine for a private event.",
"city": "Berlin",
"country": "Germany",
"timezone": "Europe/Berlin",
"resourceTypes": [
"RestaurantTable",
"BilliardTable",
"DartBoard"
],
"extras": null,
"bookingDurations": [
{
"type": "RestaurantTable",
"defaultMinutes": 120,
"minMinutes": 60,
"maxMinutes": 240,
"stepMinutes": 30,
"guestSelectable": false,
"options": [
120
]
},
{
"type": "BilliardTable",
"defaultMinutes": 60,
"minMinutes": 60,
"maxMinutes": 240,
"stepMinutes": 30,
"guestSelectable": true,
"options": [
60,
90,
120
]
},
{
"type": "DartBoard",
"defaultMinutes": 60,
"minMinutes": 60,
"maxMinutes": 240,
"stepMinutes": 30,
"guestSelectable": true,
"options": [
60,
90,
120
]
}
]
}Listen im Beispiel sind auf drei Einträge gekürzt.
Fehler – 404 keine Location mit diesem Slug; Schlüsselprobleme wie unter Fehler.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const response = await fetch('https://api.bookdineplay.com/api/venues/your-venue', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
});
const venue = await response.json();
console.log(venue.name, venue.resourceTypes);C#
var venue = await client.GetVenueAsync("your-venue", cancellationToken);
if (venue is null) { /* keine Location mit diesem Slug */ }GET /api/venues/{venueSlug}/business-info
Firmenname, Postanschrift und Kontaktdaten – was ein Impressum, ein Kartenlink oder eine Bestätigungs-E-Mail braucht.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug |
string | Die Location |
legalName |
string | Das Betreiberunternehmen, wie es auf Belegen steht |
addressLine1, addressLine2, city, postalCode, country |
string (addressLine2 nullable) |
Postanschrift |
phone, email, website |
string (website nullable) |
Kontaktdaten, die die Location veröffentlicht |
timezone |
string | Dieselbe IANA-Zone wie im Profil |
{
"slug": "demo-sportsbar",
"legalName": "Neon Tap Hospitality GmbH",
"addressLine1": "Boxhagener Straße 42",
"addressLine2": null,
"city": "Berlin",
"postalCode": "10245",
"country": "Germany",
"phone": "+49 30 5555 0142",
"email": "hey@theneontap.example",
"website": "https://theneontap.example",
"timezone": "Europe/Berlin"
}Fehler – 404 keine Location mit diesem Slug.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/business-info" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const info = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/business-info', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
})).json();
console.log(`${info.legalName}, ${info.addressLine1}, ${info.postalCode} ${info.city}`);C#
var info = await client.GetBusinessInfoAsync("your-venue", cancellationToken);GET /api/venues/{venueSlug}/opening-hours
Der Wochenplan plus datumsbezogene Ausnahmen (Feiertage, Veranstaltungen, früherer Schluss). Die Verfügbarkeit wendet sie bereits an; lesen Sie sie, um Öffnungszeiten anzuzeigen, nicht um Slots zu berechnen.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug, timezone |
string | Die Location und die Zone, in der die Zeiten liegen |
regular |
object[] | Ein Eintrag je Wochentag: day (Monday…Sunday), isClosed, opens, closes (HH:mm, null wenn geschlossen) |
special |
object[] | Datumsausnahmen: date (yyyy-MM-dd), isClosed, opens, closes, note – ein Eintrag gewinnt an seinem Datum über den Wochentag |
Zeiten über Mitternacht hinweg (opens 18:00, closes 02:00) gehören zu dem Tag, an dem sie beginnen.
{
"slug": "demo-sportsbar",
"timezone": "Europe/Berlin",
"regular": [
{
"day": "Monday",
"isClosed": true,
"opens": null,
"closes": null
},
{
"day": "Tuesday",
"isClosed": false,
"opens": "16:00",
"closes": "23:00"
},
{
"day": "Wednesday",
"isClosed": false,
"opens": "16:00",
"closes": "23:00"
}
],
"special": [
{
"date": "2026-12-24",
"isClosed": true,
"opens": null,
"closes": null,
"note": "Christmas Eve — closed"
},
{
"date": "2026-12-31",
"isClosed": false,
"opens": "18:00",
"closes": "02:00",
"note": "New Year's Eve — late night"
}
]
}Fehler – 404 keine Location mit diesem Slug.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/opening-hours" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const hours = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/opening-hours', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
})).json();
for (const day of hours.regular) {
console.log(day.day, day.isClosed ? 'geschlossen' : `${day.opens}–${day.closes}`);
}C#
var hours = await client.GetOpeningHoursAsync("your-venue", cancellationToken);GET /api/venues/{venueSlug}/menus
Jede veröffentlichte Speisekarte mit Gruppen und Positionen, bepreist in der Währung der Location. Das ist die Anzeige-Karte; woraus ein sitzender Gast bestellen kann, sind die menus der Tischsitzung (QR-Codes und Tischsitzungen).
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug, currency |
string | Die Location und die ISO-4217-Währung jedes Preises darunter |
menus[] |
object[] | id, name, description, groups[] |
groups[] |
object[] | name, description (nullable), items[] |
items[] |
object[] | name, description, price (decimal), currency, tags (string[], z. B. Ernährungshinweise), imageUrl (nullable) |
{
"slug": "demo-sportsbar",
"currency": "EUR",
"menus": [
{
"id": "kitchen",
"name": "Kitchen",
"description": "Served from open until one hour before close.",
"groups": [
{
"name": "Small plates",
"description": null,
"items": [
{
"name": "Loaded nachos",
"description": "Melted cheese, jalapeños, lime crema",
"price": 9.50,
"currency": "EUR",
"tags": [
"vegetarian"
],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/nachos.webp"
},
{
"name": "Buffalo wings",
"description": "Blue-cheese dip, celery",
"price": 11.00,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/wings.webp"
},
{
"name": "Padrón peppers",
"description": "Sea salt, olive oil",
"price": 7.00,
"currency": "EUR",
"tags": [
"vegan",
"gluten-free"
],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/padron-peppers.webp"
}
]
},
{
"name": "Mains",
"description": null,
"items": [
{
"name": "Smash burger",
"description": "Double patty, house sauce, fries",
"price": 14.50,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/smash-burger.webp"
},
{
"name": "BBQ ribs",
"description": "Slow-cooked, slaw, fries",
"price": 19.00,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/bbq-ribs.webp"
},
{
"name": "Halloumi flatbread",
"description": "Grilled halloumi, harissa, greens",
"price": 13.00,
"currency": "EUR",
"tags": [
"vegetarian"
],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/halloumi-flatbread.webp"
}
]
},
{
"name": "Sweet",
"description": null,
"items": [
{
"name": "Churros",
"description": "Cinnamon sugar, chocolate",
"price": 7.00,
"currency": "EUR",
"tags": [
"vegetarian"
],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/churros.webp"
}
]
}
]
},
{
"id": "bar",
"name": "Bar",
"description": "Draft, cocktails and zero-proof.",
"groups": [
{
"name": "Draft beer",
"description": null,
"items": [
{
"name": "House lager 0.3L",
"description": "Crisp pilsner",
"price": 4.50,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/lager.webp"
},
{
"name": "Local IPA 0.5L",
"description": "Hoppy, citrus finish",
"price": 6.50,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/ipa.webp"
}
]
},
{
"name": "Cocktails",
"description": null,
"items": [
{
"name": "Old Fashioned",
"description": "Bourbon, bitters, orange",
"price": 11.00,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/old-fashioned.webp"
},
{
"name": "Spicy margarita",
"description": "Tequila, chilli, lime",
"price": 10.50,
"currency": "EUR",
"tags": [],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/margarita.webp"
}
]
},
{
"name": "Zero proof",
"description": null,
"items": [
{
"name": "Craft soda",
"description": "House-made, ask for today's flavour",
"price": 4.00,
"currency": "EUR",
"tags": [
"vegan"
],
"imageUrl": "_content/BookDinePlay.App.Shared/menu/craft-soda.webp"
}
]
}
]
}
]
}Fehler – 404 keine Location mit diesem Slug.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/menus" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const { menus, currency } = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/menus', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
})).json();
for (const menu of menus) for (const group of menu.groups) for (const item of group.items) {
console.log(menu.name, group.name, item.name, item.price, currency);
}C#
var menus = await client.GetMenusAsync("your-venue", cancellationToken);GET /api/venues/{venueSlug}/resources
Jede buchbare Ressource – Tische, Billardtische, Dartscheiben, Bahnen, Eventflächen – mit Kapazität, der für sie geltenden Buchungsdauer und ihrer Bepreisung.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug |
string | Die Location |
resources[] |
object[] | Eine je Ressource |
id, name, description |
string | id ist das, was resourceId überall sonst bedeutet |
type |
string | Einer der Ressourcentypen |
capacity |
integer | Plätze oder Spieler |
slotDurationMinutes |
integer | Die wirksame Buchungsdauer: die eigene Überschreibung der Ressource, sofern gesetzt, sonst der Standard der Location für den Typ |
slotDurationOverrideMinutes |
integer oder null | Nur die Überschreibung; null, wenn die Ressource den Standard erbt |
pricing |
object | model (Free, PerHour, PerGame, PerSession, FixedFee, Deposit, MinimumSpend), amount, currency, depositAmount (nullable), minimumSpend (nullable), unitLabel (z. B. „pro Stunde“) |
allowsFoodOrdering |
boolean | Ob ein sitzender Gast aus der Tischsitzung bestellen kann |
{
"slug": "demo-sportsbar",
"resources": [
{
"id": "table-2a",
"name": "Window table",
"type": "RestaurantTable",
"capacity": 2,
"description": "Seats up to 2. Reserved free of charge.",
"slotDurationMinutes": 120,
"pricing": {
"model": "Free",
"amount": 0,
"currency": "EUR",
"depositAmount": null,
"minimumSpend": null,
"unitLabel": "booking"
},
"allowsFoodOrdering": true,
"slotDurationOverrideMinutes": null
},
{
"id": "table-4a",
"name": "Table 4",
"type": "RestaurantTable",
"capacity": 4,
"description": "Seats up to 4. Reserved free of charge.",
"slotDurationMinutes": 120,
"pricing": {
"model": "Free",
"amount": 0,
"currency": "EUR",
"depositAmount": null,
"minimumSpend": null,
"unitLabel": "booking"
},
"allowsFoodOrdering": true,
"slotDurationOverrideMinutes": null
},
{
"id": "table-4b",
"name": "Table 7",
"type": "RestaurantTable",
"capacity": 4,
"description": "Seats up to 4. Reserved free of charge.",
"slotDurationMinutes": 120,
"pricing": {
"model": "Free",
"amount": 0,
"currency": "EUR",
"depositAmount": null,
"minimumSpend": null,
"unitLabel": "booking"
},
"allowsFoodOrdering": true,
"slotDurationOverrideMinutes": null
}
]
}Fehler – 404 keine Location mit diesem Slug.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/resources" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const { resources } = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/resources', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
})).json();
const lanes = resources.filter(r => r.type === 'BowlingLane');C#
var resources = await client.GetResourcesAsync("your-venue", cancellationToken);GET /api/venues/{venueSlug}/floor-plan
Zonen und platzierte Ressourcen mit normalisierter Geometrie, um eine „Tisch auswählen“-Ansicht zu zeichnen. Eine Location ohne Plan antwortet mit 200 und leeren Listen – prüfen Sie tables.length, bevor Sie Ihre Oberfläche auf den Raumplan umschalten.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
slug |
string | Die Location |
zones[] |
object[] | id (GUID), name, ordinal (Anzeigereihenfolge) |
tables[] |
object[] | resourceId, name, type, capacity, zoneId, x, y, width, height (alle 0–1, relativ zur Zone), shape (Rectangle oder Circle), rotation (Grad) |
{
"slug": "demo-sportsbar",
"zones": [],
"tables": []
}Fehler – 404 keine Location mit diesem Slug.
curl
curl "https://api.bookdineplay.com/api/venues/your-venue/floor-plan" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example"JavaScript
const plan = await (await fetch('https://api.bookdineplay.com/api/venues/your-venue/floor-plan', {
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key' }
})).json();
const hasPlan = plan.tables.length > 0;C#
var plan = await client.GetFloorPlanAsync("your-venue", cancellationToken);Caching
Keine dieser Antworten trägt einen Cache-Header, weil der Betreiber sie jederzeit ändern kann. Eine vernünftige Integration cacht sie Minuten, nicht Tage, und lädt bei 404 oder einem unbekannten Schema neu. Das Widget selbst liest Profil und Raumplan einmal pro Seitenaufruf und cacht nichts über Seitenaufrufe hinweg.
Nächste Schritte
- Verfügbarkeit – aus Ressourcentyp und Datum buchbare Slots machen.
- .NET-SDK – dieselben sechs Lesezugriffe als typisierte Methoden.