Launching soon.Get early access
Veridien Docs
API Reference

Reservations

A reservation is created in two steps: hold the inventory while the guest pays, then confirm the hold into a reservation. Splitting it this way means inventory is reserved the moment a guest commits, and the reservation is only finalized once payment succeeds.

The reservation lifecycle

POST /holds creates a tentative reservation that holds a room for 15 minutes. POST /holds/{id}/confirm turns it into a confirmed reservation and records the payment. Unconfirmed holds simply expire and release their inventory.


Hold inventory

POST /holds

Scope: reservations:write · supports Idempotency-Key

Creates a tentative reservation that holds a room type on a rate plan for the date range. The stay is priced (room nights + applicable taxes) onto a new folio. The hold counts against availability until it is confirmed or its 15-minute window lapses.

Body fieldRequiredNotes
room_type_idyesMust belong to this property.
rate_plan_idyesActive plan for the room type; its visibility rules are re-checked.
check_inyesYYYY-MM-DD.
check_outyesYYYY-MM-DD, after check_in; max 30 nights.
guest_idyesThe guest the hold is for.
adultsyesInteger 1–20; party must fit max_occupancy.
childrennoInteger 0–20, default 0.
promo_codenoRequired if the chosen rate plan is promo-gated.
curl -X POST "$VRDN_BASE/holds" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 6f1d2c9a-8b3e-4a17-9c2f-1e5b7d0a4c83" \
  -d '{
    "room_type_id": "rt_deluxe",
    "rate_plan_id": "rp_flex",
    "check_in": "2026-08-01",
    "check_out": "2026-08-04",
    "guest_id": "G7K2P9QX",
    "adults": 2
  }'
{
  "reservation_id": "RES4K9PA",
  "folio_id": "fl_2b7c",
  "hold_expires_at": "2026-06-19T08:45:00.000Z",
  "total": "1260.00",
  "currency": "USD",
  "status": "tentative"
}
ErrorWhen
409 no_availabilityThe room type is sold out for the range.
404 rate_plan_not_foundThe plan is inactive, or its visibility rules exclude this guest/context.
400 party_too_largeadults + children exceeds the room type's max_occupancy.

Confirm a hold

POST /holds/{id}/confirm

Scope: reservations:write · supports Idempotency-Key

Take payment in your own flow, then confirm the hold with a payment_reference. Veridien re-checks availability (excluding the hold itself), marks the reservation and its accommodation confirmed, records the payment on the folio, and — for USD stays — awards loyalty points for the room revenue.

Method 1 is a trusted assertion model — read this

This endpoint is trust-based. Your payment_reference is an assertion that you captured the money — a claim, never proof. Veridien does not verify the payment moved: your hotel is the merchant of record, and you own the funds, disputes, and refunds. Because of that:

  • Send a real, unique reference for each booking. Never reuse or mutate a payment id across reservations.
  • Every confirm is audit-logged as a payment assertion (who asserted, the reference, the amount).
  • Confirm-time guards reject obviously-wrong input, but they cannot validate that money actually changed hands.

If you want Veridien to verify payment itself (Stripe-hosted, platform-verified capture), that is the hosted booking engine (Method 2), not this API.

Body fieldRequiredNotes
payment_referenceyesYour payment identifier — an unverified assertion you captured payment. Confirmation is idempotent on this value.
payment_currencynoOptional ISO-4217 currency you assert you charged. Rejected if it differs from the reservation currency.
payment_amountnoOptional amount you assert you captured. Rejected if it differs from the folio total.
curl -X POST "$VRDN_BASE/holds/RES4K9PA/confirm" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 9a2e7c10-4b3f-4d28-8c1f-2e6b8d0a5d94" \
  -d '{ "payment_reference": "pay_abc123", "payment_currency": "USD", "payment_amount": 1260.00 }'
{
  "reservation_id": "RES4K9PA",
  "status": "confirmed",
  "check_in_date": "2026-08-01",
  "check_out_date": "2026-08-04",
  "currency": "USD",
  "folio_balance": "0.00",
  "already_confirmed": false
}
ErrorWhen
409 hold_expiredThe hold's 15-minute payment window lapsed before you confirmed. Create a fresh hold.
409 no_availabilityThe hold lost its inventory between hold and confirm.
409 not_confirmableThe reservation is not a confirmable tentative hold (e.g. already cancelled).
400 currency_mismatchpayment_currency differs from the reservation currency.
400 amount_mismatchpayment_amount differs from the folio total.

Idempotent two ways

Re-confirming an already-confirmed reservation, or replaying the same payment_reference, returns the existing confirmed result with "already_confirmed": true — no second payment, no second reservation (a unique (folio, reference) index makes this race-safe). Combined with an Idempotency-Key, confirmation is safe to retry.

Loyalty is USD-denominated

Loyalty points are earned on USD room revenue. A non-USD stay does not silently earn zero — the skipped earn is recorded for reconciliation until multi-currency earning ships.


List reservations

GET /reservations

Scope: reservations:read

Reservations for the property, newest stays first, with each one's outstanding folio balance.

Query parameterNotes
guest_idFilter to one guest.
statusFilter by status: tentative, confirmed, checked_in, checked_out, cancelled.
limitPage size, default 25, max 100.
offsetRecords to skip.
curl "$VRDN_BASE/reservations?guest_id=G7K2P9QX&limit=10" -H "Authorization: Bearer $VRDN_KEY"
{
  "has_more": false,
  "data": [
    {
      "id": "RES4K9PA",
      "status": "confirmed",
      "guest_id": "G7K2P9QX",
      "check_in_date": "2026-08-01",
      "check_out_date": "2026-08-04",
      "room_type_id": "rt_deluxe",
      "room_type_name": "Deluxe Ocean Villa",
      "nightly_rate": "420.00",
      "currency": "USD",
      "folio_balance": "0.00"
    }
  ]
}

See Conventions for paging through results.


Get a reservation

GET /reservations/{id}

Scope: reservations:read

A single reservation with its accommodations (the per-room legs of the stay) and folio balance.

curl "$VRDN_BASE/reservations/RES4K9PA" -H "Authorization: Bearer $VRDN_KEY"
{
  "id": "RES4K9PA",
  "status": "confirmed",
  "guest_id": "G7K2P9QX",
  "check_in_date": "2026-08-01",
  "check_out_date": "2026-08-04",
  "room_type_id": "rt_deluxe",
  "room_type_name": "Deluxe Ocean Villa",
  "nightly_rate": "420.00",
  "currency": "USD",
  "adults": 2,
  "children": 0,
  "number_of_guests": 2,
  "booking_source": "direct_web",
  "special_notes": null,
  "folio_id": "fl_2b7c",
  "folio_balance": "0.00",
  "accommodations": [
    {
      "id": "ACC2M5QT",
      "room_id": null,
      "room_type_id": "rt_deluxe",
      "check_in_date": "2026-08-01",
      "check_out_date": "2026-08-04",
      "status": "confirmed",
      "nightly_rate": "420.00"
    }
  ]
}

Cancel a reservation

POST /reservations/{id}/cancel

Scope: reservations:write

Cancels a tentative or confirmed reservation and frees its inventory. Reservations that are already checked in, checked out, or cancelled cannot be cancelled through the API (409 not_cancellable).

Body fieldRequiredNotes
reasonnoStored as the cancellation reason.
curl -X POST "$VRDN_BASE/reservations/RES4K9PA/cancel" \
  -H "Authorization: Bearer $VRDN_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "reason": "Guest changed plans" }'
{ "reservation_id": "RES4K9PA", "status": "cancelled" }