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
Reservierungen
Eine Reservierung für einen angebotenen Slot anlegen – Anfragefelder, die zurückgegebene Reservierung, Anzahlungen, Gruppenbuchungen und jede Ablehnung.
Ein Aufruf bucht einen Slot. Senden Sie Ressourcentyp, Datum und Beginn, die der Gast aus der Verfügbarkeit gewählt hat, die Gruppengröße und die Kontaktdaten des Gastes; zurück kommt eine Reservierung mit einer Referenz, die der Gast nennen kann, einem Status sowie Preis und Anzahlung, die gelten.
Endpunkte
POST /api/venues/{venueSlug}/reservations
Request-Header
| Header | Erforderlich | Bedeutung |
|---|---|---|
Idempotency-Key |
nein | Ein von Ihnen gewähltes, beliebiges Token (bis zu 200 Zeichen), gültig für diese Location UND für Ihr BookDinePlay-Konto, und 24 Stunden lang berücksichtigt. Jeder API-Key Ihres Kontos kann einen Key wiedergeben, den ein anderer Ihrer Keys angelegt hat – eine Key-Rotation mitten im Vorgang ist also unproblematisch. Alle Ihre eigenen Keys teilen bewusst einen Namensraum – sie gehören zu einem Konto –, erzeugen Sie also weiterhin einen Key pro Buchungsversuch, statt sich auf eine Trennung zwischen zwei Ihrer eigenen Integrationen zu verlassen; getrennt sind die Keys eines anderen Kontos sowie Buchungen, die für Ihre Location über die von BookDinePlay selbst gehosteten Seiten entstehen – diese können Ihre weder wiedergeben noch blockieren. Eine Wiederholung mit DEMSELBEN Key und DEMSELBEN Request-Body liefert die ORIGINAL-Reservierung zurück – dieselbe reference, derselbe cancelToken – statt eine zweite anzulegen. Hat ein Key bereits so eine Reservierung erzeugt, wird eine Wiederverwendung mit einem ANDEREN Body abgelehnt mit idempotency-key-reused, niemals still wiedergegeben oder still durchgelassen. Ein Key, dessen bisher einziger Versuch FEHLGESCHLAGEN ist (Validierung, kein Slot frei), hat noch nichts gespeichert – eine korrigierte Wiederholung unter demselben Key ist dann einfach ein normaler neuer Versuch, keine Abweichung. Weggelassen ändert sich nichts: Jeder Aufruf legt eine neue Reservierung an, genau wie bisher. |
Request-Body (Content-Type: application/json)
| Feld | Erforderlich | Bedeutung |
|---|---|---|
resourceType |
ja | Der Typ des Slots, z. B. RestaurantTable |
resourceId |
nein | Die resourceId des Slots, um genau diese Ressource zu bekommen. Weggelassen: die erste freie Ressource des Typs zu dieser Zeit |
date |
ja | Ortszeit yyyy-MM-dd |
start |
ja | Ortszeit HH:mm, ein start, den die Verfügbarkeit angeboten hat |
end |
nein | Ortszeit HH:mm; Standard ist start plus Buchungsdauer |
durationMinutes |
nein | 15–1440. Denselben Wert senden, mit dem Sie die Verfügbarkeit abgefragt haben, oder weglassen für den Standard der Location |
partySize |
ja | 1–200 |
games |
nein | 1–10, bei Ressourcen mit Preis pro Spiel; Standard 1 |
customerName |
ja | 2–120 Zeichen |
email |
ja | Eine gültige E-Mail-Adresse – dorthin geht die Bestätigung |
phone |
nein | 3–40 Zeichen, wenn angegeben; ein leerer Wert gilt als nicht angegeben |
notes |
nein | Bis 500 Zeichen, für die Location sichtbar |
depositOptIn |
nein | true, wenn der Gast einer Anzahlung zustimmt; wirkt nur, wenn die Location Anzahlungen aktiviert hat |
extras |
nein | [{ "extraId": "…", "quantity": 1 }] – Extras aus dem Profil der Location, die für diesen Ressourcentyp gelten, Menge 1–100 |
Antwort 201 Created – ohne Location-Header. Das Token im Body ist eine Zugangsberechtigung (siehe cancelToken unten); es in einem Header zu senden würde es in Zugriffsprotokolle, Proxy-Protokolle und Referer-Ketten bringen, sodass aus den Antwort-Headern nichts über die Reservierung ableitbar ist.
| Feld | Typ | Bedeutung |
|---|---|---|
id |
GUID | Interne Id |
reference |
string | BDP-XXXXXX – was der Gast nennt und worauf sich ein Payment Intent bezieht. Behandle sie als undurchsichtigen Wert: Buchungen aus der Zeit vor den sechsstelligen Referenzen tragen vier Zeichen (BDP-XXXX) und bleiben gültig |
status |
string | Confirmed, oder Pending, wenn eine Anzahlung nötig und noch nicht bezahlt ist; später Cancelled, Completed, NoShow |
venueSlug, resourceType, resourceName |
string | Wo |
date, start, end |
string | Wann, in Ortszeit |
partySize, customerName |
Wer | |
priceEstimate, currency |
decimal, string | Der Preis der Buchung nach dem Modell der Ressource |
depositRequired, depositAmount |
boolean, decimal oder null | Ob der Gast zur Bestätigung eine Anzahlung leisten muss, und wie viel |
createdAt |
ISO-8601-Zeitpunkt | Wann die Reservierung angelegt wurde |
groupReference, groupResources |
string oder null, object[] oder null | Bei einer Gruppenbuchung: die gemeinsame Referenz und jedes Mitglied (resourceId, resourceName, partyShare) |
games |
integer oder null | Bei Preis pro Spiel |
extras, extrasTotal |
object[] oder null, decimal oder null | Bepreiste Extra-Positionen (extraId, name, unitPrice, quantity, lineTotal, currency, basis) und ihre Summe |
cancelToken |
string oder null | Die eigene Zugangsberechtigung des Gasts für GET /api/reservations/{cancelToken} und die Storno-Route – aus Protokollen heraushalten. Bei einer Gruppenbuchung von jedem Mitglied geteilt. Nur bei einer Reservierung von vor Einführung dieses Felds null |
{
"id": "cad35696-0a75-45b6-b986-8bed7eb00ac5",
"reference": "BDP-KSQS7M",
"status": "Confirmed",
"venueSlug": "demo-sportsbar",
"resourceType": "RestaurantTable",
"resourceName": "Corner table",
"date": "2026-10-16",
"start": "15:00",
"end": "17:00",
"partySize": 4,
"customerName": "Ada Lovelace",
"priceEstimate": 0,
"currency": "EUR",
"depositRequired": false,
"depositAmount": null,
"createdAt": "2026-09-15T12:55:15.1526956+00:00",
"groupReference": null,
"groupResources": null,
"games": null,
"extras": null,
"extrasTotal": null,
"cancelToken": "dqN_AejenL2r7qXPdZuOxnLY9_BfVkTl"
}Fehler
| Status | Wann |
|---|---|
400 |
Ein Feld scheitert an der Validierung (errors nennt es); date/start fehlerhaft; die Location ist dann geschlossen; die Dauer ist keine, die die Location für diesen Typ anbietet; ein Extra gilt nicht |
404 |
Keine Location mit diesem Slug |
409 |
Keine Ressource dieses Typs ist zu dieser Zeit frei – sie wurde seit der Verfügbarkeitsabfrage vergeben. Neu abfragen und den nächsten Slot anbieten |
409 |
Ein gesendeter Idempotency-Key wurde bereits für einen Request mit anderem Body verwendet – siehe idempotency-key-reused |
curl
curl -X POST "https://api.bookdineplay.com/api/venues/your-venue/reservations" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example" \
-H "Content-Type: application/json" \
-d '{
"resourceType": "RestaurantTable",
"date": "2026-10-16",
"start": "19:00",
"partySize": 4,
"customerName": "Ada Lovelace",
"email": "ada@example.com",
"phone": "+49 30 1234567",
"notes": "Window seat if possible"
}'JavaScript
const response = await fetch('https://api.bookdineplay.com/api/venues/your-venue/reservations', {
method: 'POST',
headers: { 'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key', 'Content-Type': 'application/json' },
body: JSON.stringify({
resourceType: 'RestaurantTable', date: '2026-10-16', start: '19:00', partySize: 4,
customerName: 'Ada Lovelace', email: 'ada@example.com', phone: '+49 30 1234567',
notes: 'Window seat if possible'
})
});
if (response.status === 409) { /* Slot gerade vergeben – Verfügbarkeit neu abfragen */ }
const reservation = await response.json();
console.log(reservation.reference, reservation.status);C#
try
{
var reservation = await client.CreateReservationAsync("your-venue", new CreateReservationRequest
{
ResourceType = BookableResourceType.RestaurantTable,
Date = "2026-10-16",
Start = "19:00",
PartySize = 4,
CustomerName = "Ada Lovelace",
Email = "ada@example.com",
Phone = "+49 30 1234567",
Notes = "Window seat if possible"
}, cancellationToken);
Console.WriteLine($"{reservation.Reference} {reservation.Status}");
}
catch (BookDinePlayApiException ex) when (ex.StatusCode == HttpStatusCode.Conflict)
{
// Slot gerade vergeben – Verfügbarkeit neu abfragen
}Sicher wiederholen mit Idempotency-Key – den Key einmal pro Buchungsversuch erzeugen und für jede Wiederholung DESSELBEN Versuchs wiederverwenden:
curl
key="resv-$(uuidgen)"
curl -X POST "https://api.bookdineplay.com/api/venues/your-venue/reservations" \
-H "X-BookDinePlay-Key: bdp_pk_your_publishable_key" \
-H "Origin: https://www.your-venue.example" \
-H "Idempotency-Key: $key" \
-H "Content-Type: application/json" \
-d '{ "resourceType": "RestaurantTable", "date": "2026-10-16", "start": "19:00", "partySize": 4, "customerName": "Ada Lovelace", "email": "ada@example.com" }'
# Bei Timeout oder 502/504 den identischen Request mit DEMSELBEN $key wiederholen.JavaScript
const idempotencyKey = crypto.randomUUID();
async function reserve() {
const response = await fetch('https://api.bookdineplay.com/api/venues/your-venue/reservations', {
method: 'POST',
headers: {
'X-BookDinePlay-Key': 'bdp_pk_your_publishable_key',
'Content-Type': 'application/json',
'Idempotency-Key': idempotencyKey
},
body: JSON.stringify({
resourceType: 'RestaurantTable', date: '2026-10-16', start: '19:00', partySize: 4,
customerName: 'Ada Lovelace', email: 'ada@example.com'
})
});
return response.json();
}
// reserve() bei Timeout/502/504 erneut aufrufen – jedes Mal derselbe idempotencyKey.C#
var idempotencyKey = Guid.NewGuid().ToString();
var reservation = await client.CreateReservationAsync("your-venue", new CreateReservationRequest
{
ResourceType = BookableResourceType.RestaurantTable,
Date = "2026-10-16",
Start = "19:00",
PartySize = 4,
CustomerName = "Ada Lovelace",
Email = "ada@example.com"
}, idempotencyKey);
// Eine Wiederholung nach Timeout/502/504 übergibt DENSELBEN idempotencyKey und erhält DIESELBE Reservierung zurück.GET /api/reservations/{cancelToken}
Die eigene Buchungsübersicht eines Gasts anhand seines Storno-Tokens: was, wann, wo, Gruppengröße, Status, und ob der eigene Storno-Button des Gasts gerade angezeigt werden soll. Kein Schlüssel: Das Token in der URL ist selbst die Zugangsberechtigung, die die Bestätigungs-E-Mail enthielt – dieselbe Begründung wie bei den Ticket-/Anmelde-Routen für Events. Nicht tarifgebunden – der Gast hat gebucht, während der Tarif der Location es erlaubte. Eine Gruppenbuchung (mehrere Ressourcen mit gemeinsamem Token) wird als eine einzige Übersicht ausgegeben: partySize ist die gesamte Gruppe, und groupResources listet jedes Mitglied.
Antwort 200 OK
| Feld | Typ | Bedeutung |
|---|---|---|
reference |
string | Die eigene Referenz der Buchung (bei einer Gruppenbuchung das erste Mitglied) |
groupReference |
string oder null | Die gemeinsame Referenz, die Gästen bei einer Gruppenbuchung gezeigt wird |
venueSlug, venueName |
string | Wo |
status |
string | Confirmed, Pending, Cancelled, Completed oder NoShow |
resourceType, resourceName |
string | Die (erste) Ressource |
date, start, end |
string | Wann, in Ortszeit |
partySize |
integer | Die gesamte Gruppe über alle Mitglieder |
groupResources |
object[] oder null | Bei einer Gruppenbuchung: jedes Mitglied (resourceId, resourceName, partyShare) |
canCancel |
boolean | Ob der eigene Storno-Button des Gasts gerade funktionieren würde |
cancelNote |
string oder null | Warum nicht, wenn canCancel false ist: bereits storniert, von der Location abgeschlossen (No-Show oder abgeschlossener Besuch), eine bezahlte Anzahlung ohne bisherigen Online-Erstattungsweg, oder die Storno-Richtlinie der Location erlaubt es gerade nicht (abgeschaltet, oder die Frist ist abgelaufen) |
{
"reference": "BDP-KSQS7M",
"groupReference": null,
"venueSlug": "demo-sportsbar",
"venueName": "The Neon Tap",
"status": "Confirmed",
"resourceType": "RestaurantTable",
"resourceName": "Corner table",
"date": "2026-10-16",
"start": "15:00",
"end": "17:00",
"partySize": 4,
"groupResources": null,
"canCancel": true,
"cancelNote": null
}Fehler — 404 für ein unbekanntes oder ungültiges Token.
curl
curl "https://api.bookdineplay.com/api/reservations/dqN_AejenL2r7qXPdZuOxnLY9_BfVkTl"JavaScript
const booking = await (await fetch('https://api.bookdineplay.com/api/reservations/' + cancelToken)).json(); // sendet keinen SchlüsselC#
using var response = await http.GetAsync($"api/reservations/{cancelToken}", cancellationToken); // sendet keinen SchlüsselPOST /api/reservations/{cancelToken}/cancel
Storniert die Buchung hinter einem Storno-Link und gibt ihren Slot sofort frei – bei einer Gruppenbuchung alle Mitglieder auf einmal, da sie ein gemeinsames Token teilen. Kein Schlüssel: Das Token ist die Zugangsberechtigung. Idempotent – ein zweiter Aufruf nach erfolgreicher Stornierung antwortet erneut mit 200. Nicht tarifgebunden. Kein Request-Body.
Antwort 200 OK — reference, groupReference, status (Cancelled).
{
"reference": "BDP-KSQS7M",
"groupReference": null,
"status": "Cancelled"
}Fehler — 404 für ein unbekanntes Token; 409 reservation-cancellation-not-allowed, sobald die Storno-Richtlinie der Location eine Online-Stornierung nicht mehr erlaubt (komplett abgeschaltet, oder die Frist ist abgelaufen – beides steuert der Betreiber); 409 reservation-deposit-not-refundable für eine Buchung mit online bezahlter Anzahlung bei einer Location, die Anzahlungen lieber telefonisch klärt als über einen Storno-Link – die Buchung bleibt unverändert; und 502 reservation-refund-failed bei einer Location, die sehr wohl erstattet, wenn die Erstattung selbst nicht durchging – ebenfalls ohne Änderung an der Buchung, aber einen erneuten Versuch wert. Prüfen Sie in allen Fällen zuerst canCancel bei GET /api/reservations/{cancelToken}, um den Hin- und Rückweg zu vermeiden.
curl
curl -X POST "https://api.bookdineplay.com/api/reservations/<cancelToken>/cancel"JavaScript
const result = await client.cancelReservation(cancelToken); // sendet keinen SchlüsselC#
var result = await client.CancelReservationAsync(cancelToken, cancellationToken); // sendet keinen Schlüssel; null bei unbekanntem TokenAnzahlungen
Eine Reservierung braucht eine Anzahlung, wenn drei Dinge zutreffen: Der Gast hat depositOptIn: true gesendet, die Location hat Anzahlungen aktiviert, und die Ressource (oder der Standard der Location für Spielressourcen) trägt einen Anzahlungsbetrag. Dann ist depositRequired true, depositAmount nennt den Betrag, und status bleibt Pending, bis die Location die Buchung bestätigt. Legen Sie als Nächstes einen Payment Intent über diesen Betrag an. Ohne Anzahlung ist die Reservierung sofort Confirmed.
Gruppenbuchungen
Übersteigt partySize die Kapazität einer Ressource und hat die Verfügbarkeit einen Gruppen-Slot angeboten, erstreckt sich die Reservierung über mehrere Ressourcen: groupReference ist die gemeinsame Referenz, und groupResources listet jedes Mitglied mit seinem Anteil an der Gruppe. Extras werden einmal für die ganze Gruppe berechnet.
Nächste Schritte
- Payment Intents – die Anzahlung entgegennehmen.
- Verfügbarkeit – woher jeder
startkommt.