Skip to content

Migrating from the legacy API

The legacy Beyond Pricing API at https://api.beyondpricing.com/api (documented at https://api-docs.beyondpricing.com) is being replaced by this Developers API v1. This guide maps each legacy endpoint to its v1 equivalent and flags features that are not yet available.

If you are starting from scratch, follow For Personal Users — it is the full end-to-end setup walkthrough.

Why the new API

  • Stable, versioned contract — URL-based versioning with a clear deprecation policy. See Versioning.
  • Standard request, response, and error format — JSON:API v1.1 with consistent envelopes and typed errors. See JSON:API Format and Error Handling.
  • Built-in pagination on every list endpoint. See JSON:API Format.
  • Transparent rate limiting via X-RateLimit-* response headers and Retry-After on 429s. See Rate Limiting.
  • Safer authentication — PATs are hashed at rest (the cleartext secret exists only on your machine), are scoped to a single Beyond credential instead of the whole user, and can be given an explicit expiry date.
  • Token per credential, not per user — finer-grained permission control. A PAT inherits its credential's listing access and can be revoked without affecting your other automations. See Authentication → Personal Access Token.
  • Live Swagger UI for browsing and testing endpoints from the browser: /api/v1/docs/.
  • First-class AI-assisted client development — point your tooling at the OpenAPI schema and the full markdown documentation in one place.

Authentication

The legacy API used a single Token header per Beyond user, created from User Settings. The v1 equivalent is a personal access token (PAT), a Bearer token prefixed with bpat_ that you create from the Beyond dashboard and bind to a single credential.

Base URL and response format

Legacy v1
Base URL https://api.beyondpricing.com/api https://developers.beyondpricing.com/api/v1/
Format Ad-hoc JSON JSON:API v1.1 (application/vnd.api+json)
Field names snake_case (e.g. base_price) dasherized (e.g. base-price)
Pagination None Page-based on every list endpoint

Endpoint mapping

Legacy v1 equivalent Notes
GET /listings/{id} GET /api/v1/listings/{id}/, plus Calendar and Listing Customizations Legacy bundled the listing record, embedded calendar, and pricing settings in one response. v1 splits them into composable endpoints.
POST /listings/{id} Listing Customizations (base-price, min-stays, min-max-prices, …) Mutations now go through per-setting customization endpoints.
POST /listings/{id}/calendar (per-date price_user / min_stay_user) Listing Customizations (base-price, min-stays, time-based-adjustments) The single per-date write was broken into typed customization endpoints.
GET /accounts GET /api/v1/users/{user_id}/accounts/ Accounts are now scoped per user.
POST /insights/market-stats GET /api/v1/listings/{id}/market-insights/ Deliberately different data. Legacy returned aggregates over connected properties in a market, and took a market as input. v1 is anchored to one of your listings and compares it, day by day, against the scraped benchmark for its own neighborhood — the comparison the Beyond app charts. See What changed.
POST /insights/account-stats GET /api/v1/listings/ and GET /api/v1/users/{user_id}/accounts/ No single equivalent. Enumerate accounts and listings, then read per-listing performance from the relevant endpoints.
POST /insights/listings_performance_revpan_user Compsets Per-listing performance is now exposed through the compset performance block.

Market insights: what changed

The legacy POST /insights/market-stats answered "how is this market doing?" from connected Beyond properties. The v1 Market Insights endpoint answers "how is my listing doing against its neighborhood?" — a different, more directly usable question. Three practical consequences when porting:

  • The input is a listing, not a market. You no longer name a market; the comparison cohort is derived from the listing itself. This also means you cannot query a market you have no listing in.
  • The benchmark is scraped, not connected. It is built from public OTA listing data for comparable properties near your listing, rather than from other Beyond customers' connected reservations — a broader and more representative sample of the neighborhood.
  • Both sides come back together. Each entry carries your listing's metric and the benchmark's for the same stay date, so no second call and no joining on your side.

Read the null semantics before charting the response: 0.0 is a real measurement and null means "not computable", and conflating them will distort your averages.

What's new in v1

Capabilities that did not exist in the legacy API:

Next steps