Skip to content
StayingAPI
Docs

API stability & versioning

What we guarantee within /v1, what can change additively, what counts as breaking, how we deprecate, and why the data source behind an endpoint never changes what your code sees.

StayingAPI is built to be wired into production workflows. This page is our contract for how the interface evolves: read it once and you can depend on /v1 without watching for surprises. It follows a semver-style split — additive changes ship in place, and anything that could break a well-behaved client goes to a new major version.

Versioning

The API is versioned in the URI path; the current major version is /v1. The version is always the first path segment — never a header or a query parameter, so the version you call is always explicit in the URL.

What we guarantee within /v1 (will not break)

As long as you read only documented fields and ignore anything you don’t recognise, none of these will change under /v1:

  • The envelope shapes. Success { data, meta }, async-accepted 202 { data, meta }, the async job poll (with a terminal data.status of completed or failed), and error { error }. A synchronous response never carries a top-level data and a top-level error together.
  • Documented fields. The names, types and meaning of every documented field in the unified schema (Property, Availability, Price, PriceCompare, Review) and in meta.
  • The error model. The type + code pair, where code is the stable sub-code (each with a permanent /docs/errors/{code} page). Every error object — top-level, the nested meta.platformResults[].error on a partial fan-out, and the data.error on a failed job — carries retryable.
  • Authentication format. Authorization: Bearer stay_live_… / stay_test_….
  • HTTP status semantics, opaque cursor pagination, and the X-Request-Id / rate-limit / Retry-After headers.

What can change at any time (additive — tolerate these)

Clients must tolerate unknown fields, enum values and error codes. The following ship in place under /v1 with no version bump:

  • New endpoints, new optional request parameters, new response fields, new enum values (platforms, amenities, property types), new error sub-codes, and new warnings[] codes.
  • Anything explicitly marked uncontracted or debug, opaque cursor internals, estimatedSeconds and other hints, and the exact wording of human message strings.
  • Which upstream source fulfils a request — see below.

The source behind an endpoint is invisible

Every endpoint normalizes to one unified schema before it returns. Which engine produced the data — one scraper, a different scraper, several with automatic fallback, or our own — is an implementation detail we change freely for reliability and coverage. A source swap never changes the shape of what your code sees: the response is validated against the same frozen schema regardless of which source answered. Build against the unified schema, not against any source-specific quirk, and a swap is a non-event for you.

What is breaking (goes to /v2)

Breaking changes are published under a new major version and run in parallel:

  • Removing or renaming a field, narrowing a type, or changing a field’s meaning.
  • Removing an endpoint or a request parameter, or removing an error code.
  • Changing the envelope structure or the authentication format.

Deprecation

Deprecated surfaces get at least six months’ notice, a Sunset response header, and a changelog entry before removal. When a new major version ships, /v2 runs alongside /v1 for the duration of any migration — your /v1 integration keeps working while you move.

Pricing changes

Credit costs are published per endpoint on the credits & pricing page. Any increase to the credit cost of an existing endpoint gets at least 30 days’ advance notice via the changelog and an account notification. Cost decreases, and the pricing of newly-added endpoints, can take effect immediately.

Your integration is safe if…