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 andRetry-Afteron 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.
- Create your PAT — see For Personal Users → Step 2.
- Send it as
Authorization: Bearer <token>on every request. - For full PAT rules and credential scoping, see Authentication → Personal Access Token.
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. See Reading a listing. |
POST /listings/{id} |
PATCH /api/v1/listings/{id}/activation/ |
Takes enabled, base-price, and min-price, the same three fields a legacy call usually sent. Change any other setting through Listing Customizations. |
POST /listings/{id}/calendar |
Listing Customizations: min-max-prices, min-stays, manual-overrides |
Per-date values become one-day ranges. See Per-date writes. |
POST /pricing/listings/{id}/edit-overrides |
Listing Customizations: min-max-prices, min-stays, checkin-checkout-days, manual-overrides |
Read the customization, edit its seasonal list, and send the list back. See Per-date writes. |
GET/POST /pricing/listings/{id}/customize/min-stays |
GET/PATCH .../customizations/min-stays/ |
Same settings, v1 field names. See Customize endpoints. |
GET/POST /pricing/listings/{id}/customize/checkin-checkout-days |
GET/PATCH .../customizations/checkin-checkout-days/ |
Same settings, v1 field names. |
GET/POST /pricing/listings/{id}/customize/occupancy-based-pricing |
GET/PATCH .../customizations/occupancy-based-pricing/ |
Same settings, v1 field names. |
GET/POST /pricing/listings/{id}/customize/time-based-adjustments |
GET/PATCH .../customizations/time-based-adjustments/ |
Percentages and directions use new values. See Customize 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 |
GET /api/v1/listings/{id}/market-insights/, listing side |
Per-day values, one call per listing. See Listing performance. |
All v1 customization paths are under /api/v1/listings/{id}/customizations/.
Reading a listing¶
Legacy GET /listings/{id} data |
Where it is in v1 |
|---|---|
Listing settings (base_price, min_price, enabled, …) |
Listing attributes, and Listing Customizations for the full rule set |
syncing, last_scrape_stamp |
sync-status on the listing |
| Booked dates | Calendar availability (booked) |
| Modeled and final price, price floor and ceiling, pricing factors | Calendar price, price-posted, effective-min-price, effective-max-price, price-override-type, and factors |
price_user, percentage_user_override |
manual-overrides |
min_price_user, max_price_user |
min-max-prices → seasonal-prices |
monthly_min_price_user, monthly_max_price_user |
min-max-prices → seasonal-monthly-prices |
min_stay_user, min_stay_user_locked |
min-stays → seasonal-min-stays |
| Per-date check-in and check-out days | checkin-checkout-days → seasonal-checkin-checkout-days |
account_valid |
Account valid |
health_score, booked_thirty, booked_ninety |
Compset source.health-score and source.metrics (thirty-day-booked, ninety-day-booked), for listings that have a compset |
Per-date writes¶
Legacy POST /listings/{id}/calendar and edit-overrides set values date by
date. In v1 each value belongs to a customization:
Legacy field (edit-overrides key) |
v1 customization | v1 field |
|---|---|---|
min_price_user, max_price_user (seasonal_min_max_prices) |
min-max-prices |
seasonal-prices: min-price, max-price |
seasonal_monthly_min_max_prices |
min-max-prices |
seasonal-monthly-prices: monthly-min-price, monthly-max-price |
min_stay_user, min_stay_user_locked (seasonal_min_stays) |
min-stays |
seasonal-min-stays: min-stay, min-stay-locked |
price_user, percentage_user_override (manual_overrides) |
manual-overrides |
overrides: price, percentage-adjustment |
seasonal_checkin_checkout_days |
checkin-checkout-days |
seasonal-checkin-checkout-days: checkin-days, checkout-days |
The write semantics change for the seasonal lists:
- A seasonal list replaces the whole list. Legacy merged each write into
the dates it named. In v1, a
PATCHthat sendsseasonal-prices,seasonal-monthly-prices,seasonal-min-stays, orseasonal-checkin-checkout-daysreplaces the listing's whole list, including seasons set in the Beyond app. Send the full desired state per listing: onePATCHtomin-max-pricesand one tomin-stayscan replace a whole batch of legacy per-date calls. - A date is a one-day range. Set
start-dateandend-dateto the same date, or send consecutive dates with the same value as one range. Ranges in one list must not overlap. - To change a few dates, read first.
GETthe customization, edit its list, andPATCHit back; aGETbody can be sent back unchanged. To change a date inside an existing range, split that range around it.
manual-overrides keeps the legacy behavior: a PATCH merges, and dates you
do not send keep their override. percentage-adjustment is a whole-number
percent (10), where legacy percentage_user_override was a fraction (0.1).
Past dates are rejected rather than ignored.
Customize endpoints¶
The v1 customization endpoints take the same settings as the legacy
customize endpoints, under the dasherized field names on
Listing Customizations. Two value
formats change:
- Time-based adjustments. Legacy
percentagewas a fraction where a positive value was a discount (0.1= 10% off). v1percentageis a whole-number percent where a negative value is a discount (-10= 10% off). Legacy directionoutis nowwithin, andinis nowafter. - Time-based minimum stays. Legacy direction
inis nowwithin, andoutis nowafter. Inlast-minute-min-stays, legacymin_daysis nowmin-stay.
Listing performance¶
POST /insights/listings_performance_revpan_user returned revenue, ADR,
occupancy, and RevPAN per listing for a stay window. In v1, use
Market Insights and read the listing side of each
entry:
- Each stay date carries the listing's
occupancy,adj-occupancy,average-booked-rate, andaverage-posted-rate. Aggregate the dates in your window to get revenue, ADR, occupancy, and RevPAN. - One request covers up to 731 days, past or future. For last year's numbers, request the same window shifted back one year.
- Rates are in
meta.currency, the listing owner's billing currency.
Compsets also has a performance block, but it
needs a compset, covers at most 180 days, and has no revenue.
Not available in v1:
- "Year-ago" pacing: what was on the books as of the same date last year.
- Owner-stay counts.
- A single call for the whole portfolio. Market Insights takes one call per listing and is rate limited to 30 requests per minute.
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:
- Webhooks — Beyond pushes signed events to your endpoint instead of you polling: a new listing is ready, a base price changes, a listing's calendar becomes available or unavailable.
- Comp sets — your listing's performance compared with the peer listings in its comp set.
- Recommendations — read pricing suggestions per listing.
- Listing refresh — queue a reservations refresh for a listing.
- Credentials — list the Beyond credentials your token can reach.
Next steps¶
- Walk through For Personal Users to get a PAT and make your first call.