Skip to content
Anmelden
Veridien Docs

Konventionen

Jeder Endpunkt folgt denselben Konventionen für Statuscodes, Fehler, Wiederholungen und Paginierung. Einmal gelernt, gelten sie überall.

StatusBedeutung
200Erfolg.
201Eine Ressource wurde angelegt (ein Gast, ein Hold oder eine Gebühr).
400Ungültige Anfrage: fehlerhaftes JSON oder ein Parameter, der die Validierung nicht bestanden hat.
401Authentifizierung fehlgeschlagen: fehlender oder ungültiger API-Schlüssel.
403Der Schlüssel ist gültig, hat aber nicht den nötigen Scope.
404Die Route oder Ressource existiert nicht (oder gehört nicht Ihnen).
405Der Pfad existiert, aber nicht für diese HTTP-Methode.
409Konflikt: keine Verfügbarkeit, ein wiederverwendeter Idempotency-Key oder ein zu geringer Punktestand.
429Rate Limit erreicht. Wiederholen Sie nach dem Retry-After-Header.
500Interner Serverfehler.
503Wartung. Die Plattform ist vorübergehend nicht verfügbar. Wiederholen Sie nach dem Retry-After-Header.

Jeder Fehlschlag liefert den passenden Status und ein einzelnes error-Objekt:

{
  "error": {
    "type": "permission",
    "code": "insufficient_scope",
    "message": "Missing required scope: reservations:write.",
    "request_id": "req_a1b2c3d4e5"
  }
}
  • type: die Kategorie: invalid_request, authentication, permission, not_found, conflict, rate_limit oder server.
  • code: eine stabile, maschinenlesbare Kennung. Verzweigen Sie hierauf, nicht auf message.
  • message: eine für Menschen lesbare Erklärung. Zum Loggen geeignet, nicht zum Parsen.
  • param: das Feld der Anfrage, das den Fehler ausgelöst hat. Nur bei Feldvalidierungsfehlern mit 400 vorhanden, sonst weggelassen.
  • estimated_end: ein ISO-Zeitstempel für das voraussichtliche Ende eines Wartungsfensters. Nur bei 503 vorhanden und nur dann, wenn ein Endzeitpunkt gesetzt wurde. Er ist genauer als der Retry-After-Header, der daraus abgeleitet wird, nutzen Sie ihn also bevorzugt, wenn Sie einen Zustand „wieder verfügbar ab“ anzeigen.
  • request_id: identifiziert die Anfrage eindeutig. Geben Sie sie an, wenn Sie den Support kontaktieren.

Code statt Meldung

Der Text von message kann sich ändern, code nicht. Verzweigen Sie Ihre Fehlerbehandlung über error.code (zum Beispiel no_availability, rate_plan_not_found, insufficient_points).

Häufige Codes, denen Sie begegnen werden:

CodeTypWann
missing_api_key / invalid_api_keyauthenticationDer Authorization-Header fehlt, oder der Schlüssel ist unbekannt, deaktiviert oder abgelaufen.
insufficient_scopepermissionDem Schlüssel fehlt der Scope des Endpunkts.
invalid_parameters / invalid_jsoninvalid_requestEin Feld hat die Validierung nicht bestanden, oder der Body war kein gültiges JSON.
unknown_routenot_foundKein Endpunkt passt zu diesem Pfad.
no_availabilityconflictDer Zimmertyp ist für den angefragten Zeitraum ausgebucht.
idempotency_key_reuseconflictEin Idempotency-Key wurde mit einem anderen Anfrage-Body wiederverwendet.
idempotency_in_progressconflictEine frühere Anfrage mit demselben Idempotency-Key läuft noch. Wiederholen Sie es kurz darauf.
insufficient_pointsconflictEine Einlösung von Treuepunkten übersteigt den verfügbaren Punktestand.
rate_limitedrate_limitDas Anfragelimit pro Schlüssel wurde überschritten.
maintenance_modeserverDie Plattform befindet sich in einem Wartungsfenster. Wiederholen Sie nach dem Retry-After-Header.

Alle Ressourcen-IDs in Veridien sind UUIDs, zum Beispiel 7d5dc2ea-1f4e-4bfa-9a52-6c3f08b41e27. Die Buchungsreferenz für den Gast ist davon getrennt: confirmation_code ist ein kurzer, gut lesbarer Code (zum Beispiel B7XKQ4M2NZ), der Gästen und Personal angezeigt wird und nie als Ressourcen-ID dient. Request-IDs tragen das Präfix req_. Felder, die Sie selbst liefern, etwa payment_reference, sind für Veridien undurchsichtig und behalten das Format, das Ihr System verwendet.

POST- und PATCH-Anfragen sind die, die den Zustand ändern: einen Gast anlegen, Bestand blockieren, eine Reservierung bestätigen, Punkte einlösen, eine Gebühr buchen. Damit Wiederholungen sicher sind, senden Sie einen Idempotency-Key-Header mit einem eindeutigen Wert (eine UUID eignet sich gut):

curl -X POST https://veridien.app/api/v1/holds \
  -H "Authorization: Bearer vrdn_live_..." \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1d2c9a-8b3e-4a17-9c2f-1e5b7d0a4c83" \
  -d '{ "room_type_id": "9b2f6c3e-8d1a-4f5b-a7c9-4e0d2b8f1a63", "rate_plan_id": "5c1e8f4a-2b7d-4a9c-8e6f-1d3b9a5c7e02", "check_in": "2026-08-01", "check_out": "2026-08-04", "guest_id": "3f8a2c1b-9d4e-4c6a-8b7f-5e2d1a9c0b34", "adults": 2 }'
  • Die erste Anfrage mit einem bestimmten Schlüssel läuft normal, und ihre Antwort wird gespeichert.
  • Eine Wiederholung mit demselben Schlüssel und demselben Body spielt die gespeicherte Antwort ab: kein zweiter Hold, keine zweite Gebühr.
  • Denselben Schlüssel mit einem anderen Body zu verwenden, liefert 409 idempotency_key_reuse.
  • Denselben Schlüssel gleichzeitig zu senden, bevor die erste Anfrage fertig ist, liefert 409 idempotency_in_progress. Wiederholen Sie es einen Moment später, dann erhalten Sie die gespeicherte Antwort. Der Schlüssel wird beansprucht, bevor die Operation läuft, die zweite Anfrage führt sie also nie aus.
  • Eine Anfrage, die fehlschlägt, gibt ihren Schlüssel frei, sodass eine ehrliche Wiederholung erneut läuft, statt den Fehlschlag abzuspielen. Nur erfolgreiche Antworten werden gespeichert: Ein 409 no_availability wegen einer kurzzeitigen Ausbuchung wird nicht für immer wiederholt, sobald das Zimmer wieder frei ist.

Die Schlüssel gelten je API-Schlüssel. Verwenden Sie pro logischer Operation einen frischen Idempotency-Key.

Die Bestätigung ist doppelt idempotent

Einen Hold zu bestätigen (POST /holds/{id}/confirm) ist zusätzlich idempotent auf seine payment_reference: Eine bereits bestätigte Reservierung erneut zu bestätigen oder dieselbe Zahlungsreferenz noch einmal zu senden, liefert das vorhandene bestätigte Ergebnis mit "already_confirmed": true, statt erneut zu belasten.

GET /reservations blättert mit limit und offset. Andere Listen-Endpunkte (/room-types, /services, /rate-plans) liefern den vollständigen Satz der Unterkunft und blättern nicht.

ParameterStandardMaxBedeutung
limit25100Wie viele Datensätze zurückgegeben werden.
offset010000Wie viele Datensätze übersprungen werden.

Die Antwort verpackt die Ergebnisse in data und meldet, ob noch weitere folgen:

{
  "has_more": true,
  "data": [ /* ... */ ]
}

Für die nächste Seite addieren Sie limit auf Ihren bisherigen offset. Hören Sie auf, sobald has_more den Wert false hat.

Jeder Geldbetrag ist eine Dezimalzeichenkette, nie ein Float: "1310.40", nicht 1310.4. Parsen Sie ihn mit einem Dezimaltyp, nicht mit einem binären Fließkommatyp.

Eine Unterkunft hat eine Basiswährung, und ein Gastkonto kann gleichzeitig Zeilen in mehreren Währungen tragen (eine Zimmerrechnung in USD mit einer Restaurantzeile in MVR ist normal). Daraus folgen zwei Regeln:

Beträge in verschiedenen Währungen werden nie addiert. Überall, wo ein Saldo ausgewiesen wird, liefert ein balances-Array die tatsächlichen Werte je Währung, und das ist die Zahl, der Sie trauen sollten:

"balances": [
  { "currency": "USD", "charges": "1310.40", "payments": "0.00", "balance": "1310.40" },
  { "currency": "MVR", "charges": "1500.00", "payments": "1500.00", "balance": "0.00" }
]

Ein Gastkonto ist nur dann settled, wenn in keiner Währung etwas offen ist. Eine Schuld in USD wird nie durch ein Guthaben in MVR ausgeglichen.

Pauschale Summen sind eine Bewertung und können null sein. Felder wie balance, total_charges und folio_balance sind Komfortwerte in der Basiswährung der Unterkunft, gebildet aus dem Wechselkurs, der beim Schreiben auf jeder Zeile eingefroren wurde. Weil der Kurs eingefroren ist, ändert eine spätere Kursanpassung nie den ausgewiesenen Wert einer bestehenden Gebühr. Steht eine Zeile in einer Währung, für die die Unterkunft keinen Kurs hinterlegt hat, lässt sie sich nicht bewerten, und diese Felder sind null statt einer falschen Zahl. Behandeln Sie null, bevor Sie damit rechnen.

Rate Limits arbeiten mit einem Leaky Bucket (Token Bucket), je API-Schlüssel. Ihr Eimer fasst bis zu 600 Token und füllt sich konstant mit 10 Token pro Sekunde wieder auf (600 pro Minute). Jede Anfrage verbraucht ein Token:

  • Ein Burst kann den ganzen Eimer auf einmal ausschöpfen, bis zu 600 Anfragen hintereinander.
  • Der Dauerdurchsatz entspricht der Nachfüllrate, 10 Anfragen pro Sekunde.

Ist der Eimer leer, liefern Anfragen 429 mit einem Retry-After-Header. Warten Sie mindestens die angegebene Anzahl Sekunden und wiederholen Sie dann. Cachen Sie Leseanfragen bevorzugt (/property, /room-types und /services tragen ein kurzes Cache-Control; /availability und /rates sind Live-Bestand und bewusst ungecacht, cachen Sie sie also auch nicht selbst) und vermeiden Sie enge Polling-Schleifen.

Zu jeder Antwort, ob Erfolg oder Fehler, gehört eine request_id (sie wird auch in Fehler-Bodies und von /me zurückgegeben). Loggen Sie sie. Wenn Sie ein Problem melden, kann der Support anhand der Request-ID genau diesen Aufruf nachverfolgen.