Apointa LogoGastronomie-API v1

Gastronomie-API

Reservierungs-API für Drittanbieter-Integrationen — Verfügbarkeit prüfen, reservieren, stornieren, ändern und Reservierungen abfragen, unabhängig vom eingesetzten Reservierungssystem des Restaurants.

Basis-URL

https://apointa.org/api/partner/v1

Alle Anfragen müssen über HTTPS erfolgen.

Authentifizierung

Jeder Endpunkt (außer /health) erfordert ein Bearer-Token:

Authorization: Bearer apt_live_...

Sie erhalten genau einen API-Key pro Partner-Konto. Er gilt für alle Restaurants, die Sie in Ihrem Dashboard hinzugefügt haben. Der Zugriff auf ein nicht freigeschaltetes Restaurant liefert 403 FORBIDDEN.

Zum Partner-Dashboard

Rate Limits

60 Anfragen pro Minute pro API-Key über alle Endpunkte hinweg. Bei Überschreitung wird 429 Too Many Requests zurückgegeben.

Tipp: Bei Voice AI sollten Verfügbarkeitsprüfungen für dasselbe Tupel (restaurantId, date, time, partySize) zwischengespeichert werden.

Fehlerbehandlung

Alle Fehler werden als JSON zurückgegeben:

{
  "success": false,
  "error": {
    "code": "VALIDATION_ERROR",
    "message": "Human-readable description"
  }
}
CodeStatusWann
UNAUTHORIZED401API-Key fehlt oder ist ungültig
FORBIDDEN403Restaurant für diesen API-Key nicht freigegeben
VALIDATION_ERROR400Request-Body besteht die Validierung nicht
NOT_FOUND404Restaurant oder Reservierung nicht gefunden
PROVIDER_ERROR502Fehler im vorgelagerten Reservierungssystem
RATE_LIMITED429Rate Limit überschritten

Endpunkte

GET/health

Liveness-Probe. Keine Authentifizierung erforderlich.

Response

{ "status": "ok", "version": "1.0.0" }
POST/check-availability

Prüft, ob ein bestimmter Zeitslot verfügbar ist. Es wird keine Reservierung angelegt.

Request-Felder

FeldTypPflichtBeschreibung
restaurantIdstringjaRestaurant-ID — Sie finden sie in Ihrem Dashboard
datestringjaJJJJ-MM-TT (Ortsdatum)
timestringjaHH:MM im 24-Stunden-Format (Ortszeit)
partySizeintegerjaAnzahl der Gäste (1-50)

Request

{
  "restaurantId": "35YDWSFbm7I",
  "date": "2026-08-15",
  "time": "19:30",
  "partySize": 4
}

Response

{
  "success": true,
  "data": {
    "available": true,
    "closed": false,
    "alternatives": ["19:00", "19:45", "20:00"]
  }
}
POST/book

Erstellt eine echte Reservierung. Jeder erfolgreiche Aufruf legt eine verbindliche Buchung an — nicht zum Testen verwenden. Pflicht sind nur Vorname und Telefonnummer.

Request-Felder

FeldTypPflichtBeschreibung
restaurantIdstringjaRestaurant-ID — Sie finden sie in Ihrem Dashboard
datestringjaJJJJ-MM-TT
timestringjaHH:MM
partySizeintegerjaAnzahl der Gäste (1-50)
customer.firstNamestringjaVorname des Gastes
customer.lastNamestringneinNachname des Gastes. Fehlt er, buchen wir mit einem neutralen Platzhalter.
customer.phonestring[]jaTelefonnummern des Gastes als Array, primäre Nummer zuerst
customer.emailstringneinE-Mail des Gastes
specialRequestsstringneinFreitext-Hinweis

Request

{
  "restaurantId": "35YDWSFbm7I",
  "date": "2026-08-15",
  "time": "19:30",
  "partySize": 4,
  "customer": {
    "firstName": "Max",
    "lastName": "Mustermann",
    "phone": ["+491701234567", "+4989123456"],
    "email": "max@example.com"
  },
  "specialRequests": "Table by the window"
}

Response

{
  "success": true,
  "data": {
    "reservationId": "gn-a1b2c3d4",
    "status": "confirmed",
    "date": "2026-08-15",
    "time": "19:30",
    "partySize": 4
  }
}
POST/cancel

Storniert eine Reservierung. Entweder über die reservationId oder — wenn Ihr System sie nicht kennt — über die Telefonnummer, optional mit Datum und Uhrzeit zur Eingrenzung.

Request-Felder

FeldTypPflichtBeschreibung
restaurantIdstringjaRestaurant-ID — Sie finden sie in Ihrem Dashboard
reservationIdstringneinID aus der Antwort von /book. Alternativ per Telefonnummer suchen.
phonestring[]neinTelefonnummern des Gastes als Array — auch alternative Nummern werden durchsucht.
datestringneinDatum der Reservierung, grenzt bei mehreren Treffern ein
timestringneinUhrzeit der Reservierung, grenzt bei mehreren Treffern ein

Request

{
  "restaurantId": "35YDWSFbm7I",
  "reservationId": "gn-a1b2c3d4"
}

Response

{
  "success": true,
  "data": {
    "reservationId": "gn-a1b2c3d4",
    "status": "cancelled",
    "date": "2026-08-15",
    "time": "19:30"
  }
}
POST/update

Fordert eine Änderung an. Die Reservierung wird wie bei /cancel gefunden. Das Restaurant wird benachrichtigt und übernimmt die Änderung.

Request-Felder

FeldTypPflichtBeschreibung
restaurantIdstringjaRestaurant-ID — Sie finden sie in Ihrem Dashboard
reservationIdstringneinID aus der Antwort von /book. Alternativ per Telefonnummer suchen.
phonestring[]neinTelefonnummern des Gastes als Array — auch alternative Nummern werden durchsucht.
datestringneinDatum der Reservierung, grenzt bei mehreren Treffern ein
timestringneinUhrzeit der Reservierung, grenzt bei mehreren Treffern ein
updates.datestringneinNeues Datum JJJJ-MM-TT
updates.timestringneinNeue Uhrzeit HH:MM
updates.partySizeintegerneinNeue Personenzahl
updates.specialRequestsstringneinNeuer Hinweis

Request

{
  "restaurantId": "35YDWSFbm7I",
  "phone": ["+491701234567"],
  "date": "2026-08-15",
  "time": "19:30",
  "updates": {
    "partySize": 6,
    "specialRequests": "Guest with allergies"
  }
}

Response

{
  "success": true,
  "data": {
    "reservationId": "gn-a1b2c3d4",
    "status": "pending",
    "message": "Update request forwarded to restaurant."
  }
}
POST/reservations

Sucht bestehende Reservierungen anhand der Telefonnummern. Liefert nur zukünftige Reservierungen.

Request-Felder

FeldTypPflichtBeschreibung
restaurantIdstringjaRestaurant-ID — Sie finden sie in Ihrem Dashboard
phonestring[]jaTelefonnummern des Gastes als Array — auch alternative Nummern werden durchsucht.

Request

{
  "restaurantId": "35YDWSFbm7I",
  "phone": ["+491701234567", "+4989123456"]
}

Response

{
  "success": true,
  "data": {
    "reservations": [
      {
        "reservationId": "gn-a1b2c3d4",
        "date": "2026-08-15",
        "time": "19:30",
        "partySize": 4,
        "specialRequests": "Table by the window"
      }
    ]
  }
}

Wichtig: nur Reservierungen aus diesem System

Die API sieht ausschließlich Reservierungen, die über dieses System angelegt wurden. Hat der Gast telefonisch, über die Website des Restaurants oder einen anderen Kanal reserviert, ist sie für /reservations, /update und /cancel unsichtbar.

In diesem Fall antworten /cancel und /update mit 404 NOT_FOUND. Gleichzeitig benachrichtigen wir automatisch das Restaurant per E-Mail mit allen übermittelten Angaben.

{
  "success": false,
  "error": {
    "code": "NOT_FOUND",
    "message": "No reservation found that was created through this API. The restaurant staff has been notified and will handle the cancellation."
  }
}

Fangen Sie diesen Fall in Ihrem System ab und teilen Sie dem Anrufer mit, dass ein Mitarbeiter informiert wurde und sich darum kümmert — genau das passiert im Hintergrund.

Format der Telefonnummer

Geben Sie die Ländervorwahl immer im E.164-Format an:

  • +491701234567 (Deutschland)
  • +436641234567 (Österreich)
  • +41791234567 (Schweiz)

Telefonnummern werden immer als Array übergeben. Kennt Ihr System eine zweite Nummer des Gastes, geben Sie sie mit an — wir durchsuchen alle.

Support

Kontaktieren Sie das Apointa-Team mit: Zeitstempel der Anfrage (UTC), restaurantId, vollständigem Request-Body (personenbezogene Daten schwärzen), HTTP-Status und Response-Body.

hey@apointa.org

Gastronomie-API Dokumentation - Apointa