Hospitality Commerce API
Concepts

How does idempotency work?

Holds and bookings use client-chosen idempotency keys. Retries return cached responses — including sealed business errors.

Which endpoints are idempotent?

EndpointIdempotentKey required
POST /v1/holdsYesYes
POST /v1/bookingsYesYes
All GET endpointsYes (safe)No
POST /v1/search, POST /v1/quotesNoNo

How it works

Send a client-chosen key via the Idempotency-Key HTTP header or idempotency_key body field.

curl -X POST https://api.agenthotel.dev/v1/holds \
  -H "Idempotency-Key: hold_user123_quote456" \
  -H "Content-Type: application/json" \
  -d '{ "quote_id": "q_456" }'

Cached by (tenant, scope, key, body_hash). Retries with same key + body return the exact cached response.

Sealed errors

Business errors on idempotent paths (like payment_failed) are sealed:

  • First attempt executes logic and caches the result
  • Retries return the cached error — payment provider NOT called again
  • Response carries Idempotent-Replayed: true

Best practices

  1. Generate deterministic keys from the logical intent: hold_{user}_{quote}_{attempt}
  2. Retry with the same key on network errors
  3. Use a new key when the intent changes
  4. Don't retry with a new key after payment_failed unless you want to re-run payment

On this page