v1 Stand: September 2026

Schankpilot API

REST/JSON API für POS-Apps, Küchen-Display-Systeme und Runner-Apps. Authentifizierung via Laravel Sanctum (Bearer Token). Alle Endpunkte erfordern den Header X-Location-ID, um den Standort zu identifizieren.

Base URL https://schankpilot.at/api/v1

Authentifizierung

Die API verwendet Laravel Sanctum (Token-basierte Authentifizierung). Nach dem Login wird ein Bearer Token zurückgegeben, der bei allen weiteren Requests im Authorization-Header mitgegeben werden muss.

E-Mail-Login

Für Account-Inhaber und Manager. Token ist 30 Tage gültig und erlaubt den Zugriff auf alle zugeordneten Standorte.

  • E-Mail + Passwort
  • Gibt Liste aller Standorte zurück
  • Token-Ablauf: 30 Tage

PIN-Login

Für managed Staff (Kellner, Koch, Runner). Token ist 12 Stunden gültig, enthält eine Location-Ability und ist an einen Standort gebunden.

  • user_id + PIN (4-stellig) + location_id
  • Ability: location:{id}
  • Token-Ablauf: 12 Stunden
Request
Authorization: Bearer 1|bx3dG6HQP0zefSkTQpXnJyCmVwR5uDsAl...
Content-Type: application/json
Accept: application/json
X-Location-ID: 3

Headers

Header Pflicht Beschreibung
Authorization Ja* Bearer {token} — bei allen geschützten Endpunkten
X-Location-ID Ja* ID des aktiven Standorts — bei allen standortbezogenen Endpunkten
Content-Type Empfohlen application/json bei allen POST/PATCH-Requests
Accept Empfohlen application/json — stellt sicher, dass Fehler als JSON zurückkommen

* Nicht erforderlich bei öffentlichen Endpunkten wie POST /auth/login, POST /auth/pin und GET /auth/staff/{id}.

Fehlerbehandlung

Alle Fehler werden als JSON zurückgegeben. Das Feld message enthält eine lesbare Fehlermeldung. Bei Validierungsfehlern (422) enthält errors ein Objekt mit feldspezifischen Fehlern.

HTTP-Code Bedeutung
200OK
201Ressource erstellt
401Nicht authentifiziert
403Kein Zugriff
404Nicht gefunden
422Validierungsfehler
429Rate Limit überschritten
500Serverfehler

Beispiel: Validierungsfehler (422)

{
  "message": "The given data was invalid.",
  "errors": {
    "email": [
      "Die eingegebenen Anmeldedaten sind nicht korrekt."
    ],
    "items.0.quantity": [
      "The quantity field must be at least 1."
    ]
  }
}

Beispiel: Allgemeiner Fehler (403)

{
  "message": "You do not have access to this location."
}

Rate Limiting

API-Requests sind auf 60 Requests pro Minute pro Token begrenzt (Laravel-Standard). Der PIN-Login ist zusätzlich auf 5 Versuche pro Minute pro User-ID + IP gedrosselt.

Response-Header Beschreibung
X-RateLimit-Limit Maximale Anzahl erlaubter Requests pro Fenster
X-RateLimit-Remaining Verbleibende Requests im aktuellen Fenster
Retry-After Sekunden bis zum Zurücksetzen (nur bei 429)

Auth

Authentifizierung und Token-Verwaltung. Keine Authorization-Header erforderlich außer bei logout und me.

POST /api/v1/auth/login
Öffentlich

E-Mail-Login — Authentifiziert einen Account-Inhaber oder Manager via E-Mail und Passwort. Gibt ein Token und die Liste aller zugänglichen Standorte zurück.

Request Body

Feld Typ Pflicht Beschreibung
email string Ja E-Mail-Adresse des Benutzers
password string Ja Passwort
device string Nein Gerätename zur Identifikation des Tokens (z. B. „POS-iPad-1")

Request

{
  "email": "chef@restaurant.at",
  "password": "geheim1234",
  "device": "manager-macbook"
}

Response 200 OK

{
  "token": "1|bx3dG6HQP0zef...",
  "token_type": "Bearer",
  "expires_at": "2026-05-15T14:00:00Z",
  "user": {
    "id": 1,
    "name": "Max Mustermann",
    "email": "chef@restaurant.at",
    "is_managed": false
  },
  "locations": [
    {
      "id": 3,
      "name": "Restaurant Zum Goldenen Hirsch",
      "tenant_name": "Hirsch Gastronomie GmbH",
      "role": "manager"
    }
  ]
}
POST /api/v1/auth/pin
Öffentlich

PIN-Login (Personal) — Authentifiziert einen managed Staff-Account (Kellner, Koch, Runner) via user_id, PIN und location_id. Das zurückgegebene Token ist auf 12 Stunden und einen Standort begrenzt.

Request Body

Feld Typ Pflicht Beschreibung
location_id integer Ja ID des Standorts, an dem die Person arbeitet
user_id integer Ja ID des Staff-Mitglieds
pin string Ja 4-stellige PIN
device string Nein Gerätename

Request

{
  "location_id": 3,
  "user_id": 12,
  "pin": "4812",
  "device": "pos-ipad-1"
}

Response 200 OK

{
  "token": "2|Xk9pLqR7mNvY...",
  "token_type": "Bearer",
  "expires_at": "2026-04-16T08:00:00Z",
  "user": {
    "id": 12,
    "name": "Anna Kellner",
    "is_managed": true,
    "role": "waiter_cashier"
  },
  "location": {
    "id": 3,
    "name": "Restaurant Zum Goldenen Hirsch"
  }
}
GET /api/v1/auth/staff/{locationId}
Öffentlich

Personal einer Location abrufen — Gibt alle managed Staff-Mitglieder eines Standorts zurück. Wird vom PIN-Login-Screen verwendet, um die Auswahlliste zu befüllen. Kein Token erforderlich.

Request

GET /api/v1/auth/staff/3

Response 200 OK

{
  "location": { "id": 3, "name": "Restaurant Zum Goldenen Hirsch" },
  "staff": [
    { "id": 12, "name": "Anna Kellner" },
    { "id": 15, "name": "Bernd Koch" }
  ]
}
DELETE /api/v1/auth/logout
Auth X-Location-ID

Logout — Widerruft das aktuelle Access Token. Nach dem Logout sind alle weiteren Requests mit diesem Token ungültig.

Request

DELETE /api/v1/auth/logout
Authorization: Bearer {token}

Response 200 OK

{
  "message": "Abgemeldet."
}
GET /api/v1/auth/me
Auth X-Location-ID

Aktueller Benutzer — Gibt die Daten des aktuell authentifizierten Benutzers und seine zugänglichen Standorte zurück.

Request

GET /api/v1/auth/me
Authorization: Bearer {token}

Response 200 OK

{
  "id": 1,
  "name": "Max Mustermann",
  "email": "chef@restaurant.at",
  "is_managed": false,
  "locations": [
    {
      "id": 3,
      "name": "Restaurant Zum Goldenen Hirsch",
      "tenant_name": "Hirsch Gastronomie GmbH",
      "role": "manager"
    }
  ]
}

Tables

Tische des Standorts mit ihrem aktuellen Status. Das Feld active_order_id verweist auf die laufende Bestellung des Tisches, sofern vorhanden.

GET /api/v1/tables
Auth X-Location-ID

Alle Tische — Gibt alle Tische des Standorts zurück, sortiert nach Name. Enthält die ID der aktiven Bestellung, falls der Tisch besetzt ist.

Request

GET /api/v1/tables
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": [
    {
      "id": 1,
      "name": "Tisch 1",
      "capacity": 4,
      "status": "free",
      "is_reservable": true,
      "active_order_id": null
    },
    {
      "id": 2,
      "name": "Tisch 2",
      "capacity": 2,
      "status": "occupied",
      "is_reservable": true,
      "active_order_id": 117
    }
  ]
}
GET /api/v1/tables/{id}
Auth X-Location-ID

Einzelner Tisch — Gibt einen einzelnen Tisch mit seiner aktiven Bestellung (inklusive Items) zurück.

Request

GET /api/v1/tables/2
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": {
    "id": 2,
    "name": "Tisch 2",
    "capacity": 2,
    "status": "occupied",
    "active_order_id": 117
  }
}

Orders

Bestellungen anlegen und verwalten. Standardmäßig werden nur aktive Bestellungen (pending, working, ready) zurückgegeben.

Status Bedeutung Farbe
pendingEingegangen, noch nicht in Bearbeitung
workingWird in der Küche/Bar zubereitet
readyBereit zur Ausgabe / Abholung
completedAbgeschlossen und verrechnet
cancelledStorniert
GET /api/v1/orders
Auth X-Location-ID

Bestellungen abrufen — Gibt aktive Bestellungen des Standorts zurück. Optional filterbar nach Status (einzelner Wert oder Array) und Tisch-ID.

Query-Parameter

Feld Typ Pflicht Beschreibung
status string|array Nein Filter: pending, working, ready, completed, cancelled (Standard: pending+working+ready)
table_id integer Nein Filter nach Tisch-ID

Request

GET /api/v1/orders?status[]=pending&status[]=working
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": [
    {
      "id": 117,
      "status": "working",
      "status_label": "In Zubereitung",
      "table_id": 2,
      "table_name": "Tisch 2",
      "pickup_number": null,
      "total_amount": 32.70,
      "note": null,
      "created_at": "2026-04-15T18:42:00Z",
      "items": [
        {
          "id": 301,
          "product_id": 42,
          "product_name": "Bruschetta",
          "quantity": 2,
          "price": 6.90,
          "total_price": 13.80,
          "options": { "Größe": "Groß" },
          "note": "Ohne Knoblauch",
          "course": "Vorspeise",
          "status": "working",
          "is_called": false,
          "production_station": { "id": 2, "name": "Küche" }
        }
      ]
    }
  ]
}
POST /api/v1/orders
Auth X-Location-ID

Bestellung erstellen — Erstellt eine neue Bestellung mit einem oder mehreren Positionen. Der Preis wird zum Zeitpunkt der Bestellung aus der Datenbank übernommen. Optionen werden als Key-Value-Objekt übergeben.

Request Body

Feld Typ Pflicht Beschreibung
table_id integer Nein Tisch-ID (null für Counter/Takeaway)
note string Nein Bestellnotiz (max. 500 Zeichen)
items array Ja Mindestens eine Bestellposition
items[].product_id integer Ja ID des Produkts
items[].quantity integer Ja Menge (min. 1)
items[].options object Nein Ausgewählte Optionen als { "OptionName": "Choice" }
items[].note string Nein Positionsnotiz (max. 255 Zeichen)
items[].course string Nein Kurs (Getränke, Vorspeise, Hauptspeise, …)

Request

POST /api/v1/orders
Authorization: Bearer {token}
X-Location-ID: 3
Content-Type: application/json

{
  "table_id": 2,
  "items": [
    {
      "product_id": 42,
      "quantity": 2,
      "options": { "Größe": "Groß" },
      "note": "Ohne Knoblauch"
    },
    {
      "product_id": 88,
      "quantity": 1
    }
  ]
}

Response 200 OK

{
  "data": {
    "id": 118,
    "status": "pending",
    "total_amount": 21.80,
    "table_id": 2,
    "items": [...]
  }
}
GET /api/v1/orders/{id}
Auth X-Location-ID

Einzelne Bestellung — Gibt eine einzelne Bestellung mit allen Items zurück.

Request

GET /api/v1/orders/117
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": { "id": 117, "status": "working", ... }
}
POST /api/v1/orders/{id}/items
Auth X-Location-ID

Positionen hinzufügen — Fügt einer bestehenden Bestellung neue Positionen hinzu. Nur möglich wenn die Bestellung im Status pending oder working ist.

Request Body

Feld Typ Pflicht Beschreibung
items array Ja Array von Bestellpositionen (gleiche Struktur wie beim Erstellen)

Request

POST /api/v1/orders/117/items
Authorization: Bearer {token}
X-Location-ID: 3

{
  "items": [
    { "product_id": 55, "quantity": 1 }
  ]
}

Response 200 OK

{
  "data": { "id": 117, "total_amount": 40.20, "items": [...] }
}
DELETE /api/v1/orders/{id}/items/{itemId}
Auth X-Location-ID

Position entfernen — Entfernt eine Bestellposition, solange sie noch nicht verrechnet ist (invoice_id ist null). Der Bestellbetrag wird entsprechend aktualisiert.

Request

DELETE /api/v1/orders/117/items/301
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": { "id": 117, "total_amount": 26.40, "items": [...] }
}
PATCH /api/v1/orders/{id}/status
Auth X-Location-ID

Bestellstatus aktualisieren — Ändert den Status einer Bestellung manuell. Wird vom Kellner verwendet, um z. B. eine Bestellung als abgeschlossen zu markieren.

Request Body

Feld Typ Pflicht Beschreibung
status string Ja Einer von: pending, working, ready, completed, cancelled

Request

PATCH /api/v1/orders/117/status
Authorization: Bearer {token}
X-Location-ID: 3

{ "status": "completed" }

Response 200 OK

{
  "data": { "id": 117, "status": "completed", ... }
}

Kitchen

Endpunkte für das Küchen-Display-System (KDS). Gibt aktive Bestellungen nach Produktionsstation gefiltert zurück und ermöglicht das Weiterrücken des Item-Status. Der KDS-Status-Workflow: pending → working → ready → served.

GET /api/v1/kitchen/orders
Auth X-Location-ID

Offene Bestellungen (KDS) — Gibt alle Bestellungen mit offenen Items zurück. Optional filterbar nach Produktionsstation. Zeigt nur Items im Status pending oder working.

Query-Parameter

Feld Typ Pflicht Beschreibung
station_id integer Nein Filter auf eine Produktionsstation (Küche, Bar, etc.)

Request

GET /api/v1/kitchen/orders?station_id=2
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": [
    {
      "id": 117,
      "status": "working",
      "table_name": "Tisch 2",
      "created_at": "2026-04-15T18:42:00Z",
      "items": [
        {
          "id": 301,
          "product_name": "Bruschetta",
          "quantity": 2,
          "status": "working",
          "note": "Ohne Knoblauch",
          "production_station": { "id": 2, "name": "Küche" }
        }
      ]
    }
  ]
}
GET /api/v1/kitchen/stations
Auth X-Location-ID

Produktionsstationen — Gibt alle Produktionsstationen des Tenants zurück (z. B. Küche, Bar, Ausgabe). Wird zum Initialisieren von Station-Filtern verwendet.

Request

GET /api/v1/kitchen/stations
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

[
  { "id": 1, "name": "Bar" },
  { "id": 2, "name": "Küche" },
  { "id": 3, "name": "Ausgabe" }
]
PATCH /api/v1/kitchen/items/{id}/status
Auth X-Location-ID

Item-Status aktualisieren — Ändert den Status einer einzelnen Bestellposition. Löst automatisch ein Status-Update auf der übergeordneten Order aus (z. B. working wenn erste Item gestartet, ready wenn alle Items ready/served sind).

Request Body

Feld Typ Pflicht Beschreibung
status string Ja Einer von: pending, working, ready, served

Request

PATCH /api/v1/kitchen/items/301/status
Authorization: Bearer {token}
X-Location-ID: 3

{ "status": "ready" }

Response 200 OK

{
  "item_id": 301,
  "status": "ready",
  "order": { "id": 117, "status": "ready", ... }
}
PATCH /api/v1/kitchen/orders/{id}/station-status
Auth X-Location-ID

Alle Items einer Station fertig melden — Setzt alle offenen Items einer Bestellung für eine bestimmte Station auf einen neuen Status. Nützlich für den „Alles fertig"-Button auf dem KDS-Display.

Request Body

Feld Typ Pflicht Beschreibung
status string Ja Einer von: working, ready, served
station_id integer Ja ID der Produktionsstation

Request

PATCH /api/v1/kitchen/orders/117/station-status
Authorization: Bearer {token}
X-Location-ID: 3

{
  "status": "ready",
  "station_id": 2
}

Response 200 OK

{
  "data": { "id": 117, "status": "ready", "items": [...] }
}

Runner

Aufgaben für das Ausgabe-Personal (Runner). Der Status-Workflow: pending → picked_up → completed. Beim Setzen auf picked_up wird der aktuelle Benutzer als Runner eingetragen.

GET /api/v1/runner/tasks
Auth X-Location-ID

Offene Runner-Aufgaben — Gibt offene Runner-Aufgaben für den Standort zurück. Standardmäßig nur pending und picked_up. Mit dem Parameter status kann auf andere Zustände gefiltert werden.

Query-Parameter

Feld Typ Pflicht Beschreibung
status string|array Nein Filter: pending, picked_up, completed (Standard: pending+picked_up)

Request

GET /api/v1/runner/tasks
Authorization: Bearer {token}
X-Location-ID: 3

Response 200 OK

{
  "data": [
    {
      "id": 45,
      "status": "pending",
      "table_name": "Tisch 2",
      "production_station": { "id": 2, "name": "Küche" },
      "items": [
        {
          "id": 301,
          "product_name": "Bruschetta",
          "quantity": 2,
          "course": "Vorspeise",
          "note": "Ohne Knoblauch"
        }
      ],
      "created_at": "2026-04-15T18:52:00Z"
    }
  ]
}
PATCH /api/v1/runner/tasks/{id}/status
Auth X-Location-ID

Aufgaben-Status aktualisieren — Ändert den Status einer Runner-Aufgabe. Beim Setzen auf picked_up wird der aktuell authentifizierte Benutzer als Runner eingetragen.

Request Body

Feld Typ Pflicht Beschreibung
status string Ja Einer von: pending, picked_up, completed

Request

PATCH /api/v1/runner/tasks/45/status
Authorization: Bearer {token}
X-Location-ID: 3

{ "status": "picked_up" }

Response 200 OK

{
  "data": {
    "id": 45,
    "status": "picked_up",
    "table_name": "Tisch 2",
    ...
  }
}

Status-Codes Referenz

Order-Status

  • pending
  • working
  • ready
  • completed
  • cancelled

OrderItem-Status (KDS)

  • pending
  • working
  • ready
  • served

RunnerTask-Status

  • pending
  • picked_up
  • completed

Datentypen

Typ Format Beispiel
Preis float (Dezimalzahl, 2 Stellen) 6.90
Datum/Zeit ISO 8601 UTC 2026-04-15T18:42:00Z
Optionen (OrderItem) JSON-Objekt { "Name": "Auswahl" } { "Größe": "Groß" }
Allergene Array von Buchstaben-Codes (EU-VO 1169/2011) ["A", "G", "L"]
Boolean true / false true

Changelog

2026-04-15
v1.0 Initiale Veröffentlichung: Auth, Menu, Tables, Orders, Kitchen, Runner

Cookies & Analyse

Wir nutzen Matomo, um anonymisierte Besuchsstatistiken zu erfassen und unser Angebot zu verbessern. Die Daten verbleiben auf unseren Servern in der EU. Datenschutzerklärung