Beyond Pricing Insights API

The Insights API from Beyond Pricing — 1 operation(s) for insights.

GitHub OpenAPI

Operations 1

GET /api/v1/listings/{listing_id}/market-insights/ Compare a listing with its market #

Work with this as data

Every API here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for apis

7 MCP tools reach this
  • find_apisBrowse and filter every API in the catalog.
  • get_api_artifactsOne API's artifacts, grouped by type.
  • get_openapiThe primary OpenAPI for this API.
  • find_similar_apisAPIs that look like this one.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This API
curl "https://apis.io/api/v1/apis/beyond-pricing:beyond-pricing-insights-api"
All apis
curl "https://apis.io/api/v1/apis?limit=25"

Calls without X-API-Key need no key. Calls with it need a paid plan — get a key.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.

OpenAPI Specification

beyond-pricing-insights-api-openapi.yml Raw ↑
openapi: 3.2.0
info:
  title: Beyond Insights API
  version: 2.0.0
  description: Bearer-protected API for third-party integrations. Supports OAuth2 client credentials and personal access tokens. Follows JSON:API specification.
tags:
- name: Insights
paths:
  /api/v1/listings/{listing_id}/market-insights/:
    get:
      operationId: get_listing_market_insights
      description: 'Compare a listing''s daily performance with its neighborhood.


        **Required scope:** `insights:read`


        Returns one entry per stay date. Each entry carries both sides of the

        comparison: `listing` is this listing, `benchmark` is built from

        scraped OTA data for the cohort the listing belongs to, narrowed to its

        bedroom count and to entire-home rentals. Studios and one-bedrooms

        share one cohort (`meta.cohort-bedrooms` is `["0", "1"]` for both). Which cohort that is follows

        `filter[compare-to]`.


        **`null` never means zero.** A metric is `null` when it could not be

        computed for that date -- no availability, no bookings, or no scrape

        coverage. A genuine zero is returned as `0.0`. This matters most for

        `average-booked-rate`, which is `null` on a date with no bookings; use

        `average-posted-rate` where you need a price on such dates.


        **Precision is not symmetric.** The `benchmark` side of every metric is

        aggregated across the cohort and rounded to a whole number upstream;

        the `listing` side is exact. Rates are in `meta.currency` and in major

        units -- `84.46` means 84.46, not 84 cents.


        **Entry ids** are `{listing-id}:{compare-to}:{stay-date}`. The

        benchmark half of a row depends on both, so neither can be left out of

        the identity.


        **Comparison scope:** `filter[compare-to]=cluster` (default) or

        `market`. Widen to `market` when the cluster cohort has no data

        (`meta.benchmark-data-available` is `false`).


        **Currency:** Derived from the listing owner''s billing configuration

        and echoed in `meta.currency`. There is no currency parameter. This is

        not the listing''s own currency, which is what calendar prices and the

        listing''s own price fields are quoted in; the two can differ.


        **Date range:** `filter[start-date]` and `filter[end-date]`

        (YYYY-MM-DD). Defaults to the current calendar year, which fits in a

        single page.


        **Pagination:** `page[number]` and `page[size]`.


        **Example:** `GET /api/v1/listings/123/market-insights/?filter[start-date]=2026-01-01&filter[end-date]=2026-06-30`'
      summary: Compare a listing with its market
      parameters:
      - in: path
        name: listing_id
        schema:
          type: integer
        required: true
      - name: page[number]
        required: false
        in: query
        description: A page number within the paginated result set.
        schema:
          type: integer
      - name: page[size]
        required: false
        in: query
        description: Number of results to return per page.
        schema:
          type: integer
      - in: query
        name: filter[start-date]
        schema:
          type: string
          format: date
        description: First stay date (YYYY-MM-DD). Defaults to 1 January of the current year.
      - in: query
        name: filter[end-date]
        schema:
          type: string
          format: date
        description: Last stay date (YYYY-MM-DD). Defaults to 31 December of the current year. The range must not exceed 731 days.
      - in: query
        name: filter[compare-to]
        schema:
          type: string
          enum:
          - cluster
          - market
        description: 'Which benchmark to compare against: `cluster` (default) for the listing''s immediate neighborhood, or `market` for its whole market.'
      - in: query
        name: fields[market-insights]
        schema:
          type: array
          items:
            type: string
            enum:
            - id
            - date
            - adj-occupancy
            - occupancy
            - average-booked-rate
            - average-posted-rate
        description: endpoint return only specific fields in the response on a per-type basis by including a fields[TYPE] query parameter.
        explode: false
      tags:
      - Insights
      security:
      - oauth2:
        - insights:read
      - oauth2:
        - beyond:read
      - personalAccessToken: []
      responses:
        '200':
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/PaginatedMarketInsightsList'
              examples:
                DailyComparisonEntries:
                  value:
                    data:
                    - data:
                      - type: market-insights
                        id: 123:cluster:2026-03-01
                        attributes:
                          date: '2026-03-01'
                          adj-occupancy:
                            listing: 71.4
                            benchmark: 63.0
                          occupancy:
                            listing: 68.2
                            benchmark: 59.0
                          average-booked-rate:
                            listing: 210.5
                            benchmark: 188.0
                          average-posted-rate:
                            listing: 225.0
                            benchmark: 191.0
                      - type: market-insights
                        id: 123:cluster:2026-08-20
                        attributes:
                          date: '2026-08-20'
                          adj-occupancy:
                            listing: 0.0
                            benchmark: 58.0
                          occupancy:
                            listing: 0.0
                            benchmark: 55.0
                          average-booked-rate:
                            listing: null
                            benchmark: 175.0
                          average-posted-rate:
                            listing: 240.0
                            benchmark: 179.0
                      meta:
                        pagination:
                          page: 1
                          pages: 1
                          count: 2
                        currency: GBP
                        benchmark-data-available: true
                        compare-to: cluster
                        cohort-bedrooms:
                        - '2'
                        start-date: '2026-01-01'
                        end-date: '2026-12-31'
                    links:
                      first: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=1
                      last: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=9
                      prev: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=1
                      next: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=3
                    meta:
                      pagination:
                        count: 42
                        page: 2
                        pages: 5
                  summary: Daily comparison entries
          description: ''
        '400':
          description: Validation error
        '401':
          description: Unauthorized - invalid or missing bearer token
        '403':
          description: Forbidden
        '404':
          description: Not found - resource does not exist
        '422':
          description: Unprocessable - the listing cannot be placed in a market cohort
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
components:
  schemas:
    PaginatedMarketInsightsList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/MarketInsights'
        links:
          type: object
          description: Pagination links for the primary data. These keys MUST be used for pagination links; each MUST be omitted or `null` when that link is unavailable. Values follow JSON:API link rules (URI string, link object, or null). https://jsonapi.org/format/#fetching-pagination https://jsonapi.org/format/#document-links
          properties:
            first:
              type:
              - string
              - 'null'
              format: uri
              example: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=1
              description: 'The first page of data. A JSON:API link: URI string, link object, or null. See https://jsonapi.org/format/#document-links.'
            last:
              type:
              - string
              - 'null'
              format: uri
              example: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=9
              description: 'The last page of data. A JSON:API link: URI string, link object, or null. See https://jsonapi.org/format/#document-links.'
            prev:
              type:
              - string
              - 'null'
              format: uri
              example: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=1
              description: 'The previous page of data. A JSON:API link: URI string, link object, or null. See https://jsonapi.org/format/#document-links.'
            next:
              type:
              - string
              - 'null'
              format: uri
              example: http://example.com/articles?page%5Bsize%5D=10&page%5Bnumber%5D=3
              description: 'The next page of data. A JSON:API link: URI string, link object, or null. See https://jsonapi.org/format/#document-links.'
          additionalProperties: false
        meta:
          type: object
          description: Non-standard meta-information. Page-number stacks often nest totals under `pagination`. JSON:API does not define these keys. Servers MAY add other `meta` members; this schema documents the usual djangorestframework-json-api shape only. https://jsonapi.org/format/#document-meta
          properties:
            pagination:
              type: object
              description: Typical page-number metadata from djangorestframework-json-api; not mandated by JSON:API.
              properties:
                count:
                  type: integer
                  minimum: 0
                  example: 42
                  description: Total number of resources across all pages.
                page:
                  type: integer
                  minimum: 1
                  example: 2
                  description: Current page number (1-based).
                pages:
                  type: integer
                  minimum: 0
                  example: 5
                  description: Total number of pages.
              additionalProperties: false
          additionalProperties: false
      required:
      - data
    MarketInsightResourceTypeEnum:
      type: string
      enum:
      - market-insights
    MarketInsightsComparison:
      type: object
      description: 'One metric, on both sides of the comparison.


        `null` means the metric could not be computed for that date -- no

        availability, no bookings, or no scrape coverage. It never means zero;

        a real zero is returned as `0.0`.


        The two sides do not carry the same precision: `benchmark` is aggregated

        across the cohort and rounded to a whole number upstream, `listing` is

        exact. Do not read a sub-point difference between them as signal.'
      properties:
        listing:
          type:
          - number
          - 'null'
          format: double
          description: Value for this listing, at full precision (aggregated over its sub-units for a multi-unit parent).
        benchmark:
          type:
          - number
          - 'null'
          format: double
          description: 'Value for the comparison cohort, from scraped OTA data. Which cohort that is follows `filter[compare-to]`: the listing''s neighborhood by default, or its whole market. Rounded to a whole number upstream, so it carries no decimals.'
      required:
      - benchmark
      - listing
    MarketInsights:
      type: object
      required:
      - type
      - id
      additionalProperties: false
      properties:
        type:
          allOf:
          - $ref: '#/components/schemas/MarketInsightResourceTypeEnum'
          description: The [type](https://jsonapi.org/format/#document-resource-object-identification) member is used to describe resource objects that share common attributes and relationships.
        id:
          type: string
          description: '`{listing-id}:{compare-to}:{stay-date}`, e.g. `4033897:cluster:2026-03-01`. The benchmark half of a row depends on which listing was asked about and on `filter[compare-to]`, so both are part of the entry''s identity rather than the date alone.'
        attributes:
          type: object
          properties:
            date:
              type: string
              format: date
              description: Stay date this entry describes
            adj-occupancy:
              allOf:
              - $ref: '#/components/schemas/MarketInsightsComparison'
              description: 'Adjusted occupancy percentage: booked nights over *available* nights, so blocked and unavailable nights do not count against it.'
            occupancy:
              allOf:
              - $ref: '#/components/schemas/MarketInsightsComparison'
              description: 'Occupancy percentage over all nights, including nights that were not available to book. Its `benchmark` side is `null` whenever `adj-occupancy`''s is: the scraped series publishes only the adjusted denominator, so neither variant is verifiable without it.'
            average-booked-rate:
              allOf:
              - $ref: '#/components/schemas/MarketInsightsComparison'
              description: Average nightly rate actually booked, in `meta.currency` and in major units (`84.46` is 84.46, not 84 cents). `null` when there were no bookings on that date.
            average-posted-rate:
              allOf:
              - $ref: '#/components/schemas/MarketInsightsComparison'
              description: Average nightly rate on offer, in `meta.currency` and in major units, booked or not. Useful as a fallback where `average-booked-rate` is `null`.
          required:
          - date
          - adj-occupancy
          - occupancy
          - average-booked-rate
          - average-posted-rate
  securitySchemes:
    oauth2:
      type: oauth2
      description: Use OAuth2 client credentials to mint an application token, or add `user_id` and optional `credential_id` in the Authorize dialog to request a user- or credential-scoped token.
      flows:
        clientCredentials:
          tokenUrl: /o/token/
          refreshUrl: /o/token/
          scopes:
            listings:read: Read listings
            listings:write: Modify listings
            reservations:read: Read reservations
            accounts:read: Read account information
            user:read: Read user information
            user:write: Create and modify users
            insights:read: Read market insights
            compsets:read: Read competitive set data
            neyoba:ask: Ask Neyoba
            beyond:read: Read listings, performance, and market data via the Beyond MCP server
            beyond:write: Modify pricing and listing settings via the Beyond MCP server
            beyond:skills: Load Beyond revenue-management skills via the Beyond MCP server
            beyond:usage: Read tool-call history and usage via the Beyond MCP server
            webhooks:read: Read delivered webhook events
            webhooks:write: Modify webhook configuration
    personalAccessToken:
      type: http
      scheme: bearer
      bearerFormat: PersonalAccessToken
      description: Paste a `bpat_...` personal access token. PATs use the same Bearer header as OAuth2 tokens and must still include the runtime-required scopes for each endpoint, even though OpenAPI cannot encode scopes for non-OAuth bearer schemes.
x-provenance:
  method: harvested
  publisher: Beyond Pricing
  source: https://developers.beyondpricing.com/api/v1/schema/
  note: split by refine-openapis from the provider's own published document, verified by fetch (openapi/_original/*.fetch.json);
    stamped by stamp-openapi-provenance.py (roadmap#793)