TouricalDevelopers

Changelog

API and webhook changes by date. Backwards-compatible by default — breaking changes get a version bump.

The Tourical API follows a few rules around change:

  • We never rename a field, scope, event type, or webhook header once shipped. Deprecated names continue to work through at least one major release window.
  • Additive changes (new field, new endpoint, new event type) ship without a version bump. Verifiers must ignore unknown fields.
  • Breaking changes ship under a new path version (/v2/) and run in parallel with the previous version for at least six months.
  • Every change shows up here. If something visibly changes and we forgot to log it, that's a bug — write to us.

Deprecation and sunset policy

When an endpoint, field, or event is deprecated:

  1. It is marked deprecated here and in /openapi.json (deprecated: true) on the day the replacement ships.
  2. Responses from a deprecated route carry Deprecation: true, a Sunset header with the removal date (RFC 8594), and a Link: <…>; rel="successor-version" header pointing at the replacement.
  3. The sunset date is at least six months after the deprecation notice for /v1/*.
  4. We measure traffic to deprecated routes and contact integrators who are still calling them before the sunset date.

Currently deprecated:

RouteReplacementSunset
/client/quotes/*, /client/bookings/* (legacy recipient pages)/dossier/*, /dossier/bookings/*2026-10-31
/api/client/quotes/*, /api/client/bookings/*/api/dossier/*, /api/dossier/bookings/*2026-10-31

These legacy recipient routes were never part of the /v1/* contract; they answer with a redirect plus the headers above until the sunset date, then 404.

2026-09-05 — v1.1: contracts, delivery inspection, idempotency

Endpoints

  • GET /v1/me — token introspection.
  • POST /v1/webhooks/{id}/rotate-key — signing-key rotation with a 24h dual-key overlap.
  • GET /v1/webhooks/{id}/deliveries — delivery history, cursor-paginated, filter by status.
  • POST /v1/webhooks/{id}/deliveries/{deliveryId}/redeliver — queue a fresh delivery of the same event (same Tourical-Event-Id).
  • GET /v1/openapi.json — the OpenAPI 3.1 document, generated from the runtime; a contract test keeps the two in step.

Webhooks

  • Every event in the catalog now has an emitter. booking.cancelled, booking.refunded, dispute.closed, trip.published, trip.unpublished and client.created (from the dashboard, the API, checkout, and date requests) fire in production.
  • Payloads are validated against the published JSON Schema at emit time; the examples in the event catalog are generated from the same schema.
  • New headers on every delivery: Tourical-Request-Id (<deliveryId>.<attempt>) and Tourical-Delivery-Attempt.
  • Retry cascade starts at 1 minute (6 attempts total) as documented; the first retry had previously waited 5 minutes.
  • Auto-pause keeps queued deliveries in pending (nothing is dead-lettered by a pause) and notifies the tenant's owners/admins.
  • POST /v1/webhooks/test no longer requires webhook.test in a subscription's events list and no longer modifies the subscription; subscriptionId outside your tenant returns 404.
  • Deleting a subscription in the dashboard is now a soft delete, like the API: delivery history is kept.

Idempotency

  • Idempotency-Key is honoured on every /v1/* write; 24h window, tenant-scoped, 409 on body mismatch or in-flight replay. 5xx responses are never cached.

Rate limits

  • The pre-authentication per-IP guard is now 2,000 requests/minute (was 120) and answers 429 with X-RateLimit-Scope: ip. Per-token quotas are unchanged.

Removed

  • Two never-documented internal routes (/api/exchange-rates, /api/ratehawk/search) were deleted. They were not part of /v1/*.

2026-05-26 — v1 public launch

Initial public release of the v1 API and webhook system.

Endpoints

  • GET / POST / PATCH /v1/trips
  • GET /v1/bookings, POST /v1/bookings (501 — checkout via storefront)
  • GET / POST /v1/clients
  • GET /v1/payments
  • GET /v1/libraries/{hotels,activities,vehicles,guides}
  • GET / POST / DELETE /v1/webhooks, POST /v1/webhooks/test

Webhook events

booking.confirmed, booking.cancelled, booking.refunded, payment.succeeded, payment.failed, dispute.opened, dispute.closed, trip.published, trip.unpublished, client.created, webhook.test.

Auth

Bearer tokens, format tk_<live|test>_<26 chars>. Ten scopes covering reads and writes per resource.

Rate limits

60 req/sec burst, 600 req/min sustained, per token.

Roadmap

These are planned but not yet shipped. Subscribe to the changelog (or watch this page) — we won't surprise-ship anything that breaks an integrator.

  • Postman collection and generated client SDKs for Node and Python, built from /openapi.json.
  • POST /v1/bookings (today 501; checkout runs through the storefront).

On this page