Beyond Accounts API

The Accounts API from Beyond — 3 operation(s) for accounts.

OpenAPI Specification

beyond-accounts-api-openapi.yml Raw ↑
openapi: 3.1.1
info:
  title: Beyond Pricing Public Accounts 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: Accounts
paths:
  /api/v1/users/{user_id}/accounts/:
    get:
      operationId: list_accounts
      description: 'Return a paginated list of accounts (channel connections) for the specified user.


        ## Response Codes

        - **200**: Success

        - **401**: Unauthorized - invalid or missing OAuth2 token

        - **403**: Forbidden - insufficient scope

        - **404**: Not found - user not found'
      summary: List accounts for a user
      parameters:
      - in: path
        name: user_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
      tags:
      - Accounts
      security:
      - oauth2:
        - user:read
      - personalAccessToken: []
      responses:
        '200':
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/PaginatedAccountList'
          description: ''
        '401':
          description: Unauthorized - invalid or missing bearer token
        '403':
          description: Forbidden
        '404':
          description: Not found - resource does not exist
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
    post:
      operationId: create_account
      description: 'Add a channel connection (account) for a user.


        Each channel requires specific credentials.


        ## Supported Channels and Required Credentials


        | Channel | Required Fields | Optional Fields |

        |---------|-----------------|-----------------|

        | `airbnb` | `email` | `password`, `device_id` |

        | `airbnb_partner` | `access_token` | `refresh_token`, `email` |

        | `avantio` | `provider_id`, `username`, `password` | - |

        | `barefoot_direct` | `account_id` | `web_book_reztypeid` |

        | `beds24` | `account_id` | - |

        | `best_beach` | `api_key` | - |

        | `booking_connect` | `email`, `password` | `device_id` |

        | `booking_experts` | `authorization_code` | - |

        | `bookingsync` | `authorization_code`, `redirect_uri` | - |

        | `brightside` | `subdomain`, `api_key` | - |

        | `ciirus` | `company_id` | `booking_id`, `booking_secret` |

        | `cloudbeds` | `authorization_code` | - |

        | `direct` | `organization_id` | - |

        | `elina` | `password` | - |

        | `escapia` | `email`, `domain`, `password`, `pm_id` | `evrn_api_user`, `evrn_api_password` |

        | `fantasticstay` | `api_key` | - |

        | `gfh` | `api_key` | - |

        | `guesty` | `jwt` | `booking_id`, `booking_secret` |

        | `homeaway` | `authorization_code` | - |

        | `homhero` | `reference` | - |

        | `homhero_staging` | `reference` | - |

        | `hospitable` | `authorization_code`, `client_id`, `client_secret`, `redirect_uri` | - |

        | `hostaway` | `client_id`, `client_secret` | - |

        | `hostfully` | `agency_id` | `authorization_code` |

        | `hosthub` | `api_key` | - |

        | `hostify` | `api_key` | - |

        | `icnea` | `account_id` | - |

        | `igms` | `authorization_code` | - |

        | `ipro` | `client_code`, `password`, `domain` | - |

        | `janiis` | `organization_id`, `api_key` | - |

        | `kigo` | `api_key` | - |

        | `kigo_pro` | `authorization_code` | - |

        | `kross_booking` | `hotel_id`, `username`, `password` | - |

        | `lightmaker` | `company_id` | - |

        | `liverez` | `username`, `password`, `security_id` | - |

        | `lodgable` | `client_id`, `client_password` | - |

        | `lodgify` | `api_key` | - |

        | `lodgify_partner` | `api_key` | - |

        | `lodgix` | `api_key` | - |

        | `loggia` | `email`, `api_key`, `page_id` | - |

        | `mews` | `access_token` | - |

        | `myvr` | `authorization_code` | - |

        | `octorate` | `authorization_code`, `redirect_uri` | - |

        | `opera` | `enterprise_id`, `client_id`, `hotel_id`, `client_secret`, `base_url` | - |

        | `ownerrez` | `authorization_code`, `redirect_uri` | - |

        | `real_time_rental` | `account_id` | - |

        | `rentalready` | `authorization_code` | - |

        | `rentals_united` | `email` | `password` |

        | `resly` | `api_key`, `property_id` | - |

        | `rms` | `client_id`, `client_password` | - |

        | `secra` | `landlord_no`, `authcode` | - |

        | `septeo` | `agency_id` | - |

        | `smoobu` | `client_id`, `api_key` | - |

        | `stays` | `username`, `password`, `base_url` | - |

        | `streamline` | `token_key`, `token_secret` | - |

        | `supercontrol` | `client_key` | - |

        | `tokeet` | `access_code`, `redirect_uri` | - |

        | `track` | `username`, `password`, `subdomain`, `post_key`, `post_secret` | - |

        | `travelmob` | `email` | `password` |

        | `uplisting` | `api_key` | - |

        | `villas365` | `account_id`, `owner_token`, `key`, `password` | - |

        | `vrbo` | `email` | `password` |

        | `vreasy` | `api_key` | - |

        | `vrm` | `client_code` | - |

        | `zeevou` | `username`, `secret` | - |

        | `zeevou_direct` | `authorization_code` | - |


        _Dynamic/custom PMS channels require `api_key` and optionally `base_url`._


        ## Response Codes

        - **201**: Account created successfully

        - **400**: Validation error - invalid input data

        - **401**: Unauthorized - invalid or missing OAuth2 token

        - **403**: Forbidden - insufficient scope

        - **404**: Not found - user not found

        - **422**: Channel validation/authentication failed

        - **502**: Channel error (external service issue)'
      summary: Add an account for a user
      parameters:
      - in: path
        name: user_id
        schema:
          type: integer
        required: true
      tags:
      - Accounts
      requestBody:
        content:
          application/vnd.api+json:
            schema:
              $ref: '#/components/schemas/AccountCreateRequest'
            examples:
              APIKeyChannel(Hostify):
                value:
                  data:
                    type: accounts
                    attributes:
                      channel: hostify
                      credentials:
                        api_key: your-api-key-here
                summary: Add an API key channel
              ClientID/SecretChannel(Hostaway):
                value:
                  data:
                    type: accounts
                    attributes:
                      channel: hostaway
                      credentials:
                        client_id: '12345'
                        client_secret: abcdef123456
                summary: Add a client ID/secret channel
              JWTChannel(Guesty):
                value:
                  data:
                    type: accounts
                    attributes:
                      channel: guesty
                      credentials:
                        jwt: your-jwt-token-here
                summary: Add a JWT-based channel
        required: true
      security:
      - oauth2:
        - user:write
      - personalAccessToken: []
      responses:
        '201':
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/AccountResponse'
          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 entity
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
        '502':
          description: Channel error
  /api/v1/users/{user_id}/accounts/{account_id}/:
    get:
      operationId: get_account
      description: 'Retrieve a single account (channel connection) for the specified user.


        ## Response Codes

        - **200**: Success

        - **401**: Unauthorized - invalid or missing OAuth2 token

        - **403**: Forbidden - insufficient scope

        - **404**: Not found - user or account not found'
      summary: Get an account for a user
      parameters:
      - in: path
        name: user_id
        schema:
          type: integer
        required: true
      - in: path
        name: account_id
        schema:
          type: integer
        required: true
      tags:
      - Accounts
      security:
      - oauth2:
        - user:read
      - personalAccessToken: []
      responses:
        '200':
          content:
            application/vnd.api+json:
              schema:
                $ref: '#/components/schemas/AccountResponse'
          description: ''
        '401':
          description: Unauthorized - invalid or missing bearer token
        '403':
          description: Forbidden
        '404':
          description: Not found - resource does not exist
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
    delete:
      operationId: delete_account
      description: 'Remove a channel connection (account) for a user. This unregisters webhooks and soft-deletes the account.


        ## Response Codes

        - **204**: Successfully deleted

        - **401**: Unauthorized - invalid or missing OAuth2 token

        - **403**: Forbidden - insufficient scope

        - **404**: Not found - user or account not found'
      summary: Delete an account for a user
      parameters:
      - in: path
        name: user_id
        schema:
          type: integer
        required: true
      - in: path
        name: account_id
        schema:
          type: integer
        required: true
      tags:
      - Accounts
      security:
      - oauth2:
        - user:write
      - personalAccessToken: []
      responses:
        '204':
          description: No content
        '401':
          description: Unauthorized - invalid or missing bearer token
        '403':
          description: Forbidden
        '404':
          description: Not found - resource does not exist
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
  /api/v1/users/{user_id}/accounts/{account_id}/refresh/:
    post:
      operationId: refresh_account
      description: 'Queue a full listings and reservations refresh for the specified account.


        This endpoint enqueues an asynchronous `sync_all` job and returns immediately.


        Use `recent_sync_threshold_minutes` to control how recently synced listings are skipped. The threshold unit is minutes. When set to `0`, the refresh includes all listings.


        If you have registered a webhook, an `account.refreshed` event is delivered once the listing sync reaches a terminal state, so you do not have to poll. Reservations are refreshed by separate background jobs and are still in flight when that event fires.


        ## Response Codes

        - **400**: Validation error - invalid query parameter value

        - **202**: Refresh accepted and queued

        - **401**: Unauthorized - invalid or missing OAuth2 token

        - **403**: Forbidden - insufficient scope

        - **404**: Not found - user or account not found

        - **409**: Conflict - a refresh is already in progress; retry shortly'
      summary: Refresh an account for a user
      parameters:
      - in: path
        name: user_id
        schema:
          type: integer
        required: true
      - in: path
        name: account_id
        schema:
          type: integer
        required: true
      - in: query
        name: recent_sync_threshold_minutes
        schema:
          type: integer
        description: Skip listings synced within the last N minutes. Defaults to 60. Set to 0 to disable this optimization and refresh all listings.
      tags:
      - Accounts
      security:
      - oauth2:
        - user:write
      - personalAccessToken: []
      responses:
        '400':
          description: Validation error
        '202':
          description: Refresh accepted
        '401':
          description: Unauthorized - invalid or missing bearer token
        '403':
          description: Forbidden
        '404':
          description: Not found - resource does not exist
        '409':
          description: Conflict - a refresh is already in progress for this account
        '429':
          description: Rate limit exceeded
        '500':
          description: Internal server error
components:
  schemas:
    AccountResourceTypeEnum:
      type: string
      enum:
      - accounts
    StateEnum:
      enum:
      - queued
      - in_progress
      - completed
      - unknown
      type: string
      description: '* `queued` - queued

        * `in_progress` - in_progress

        * `completed` - completed

        * `unknown` - unknown'
    AccountCreateRequest:
      type: object
      properties:
        data:
          type: object
          required:
          - type
          additionalProperties: false
          properties:
            type:
              type: string
              description: The [type](https://jsonapi.org/format/#document-resource-object-identification) member is used to describe resource objects that share common attributes and relationships.
              enum:
              - accounts
            attributes:
              type: object
              properties:
                channel:
                  type: string
                  minLength: 1
                  description: 'Channel identifier (e.g., ''hostify'', ''hostaway''). Supported channels: airbnb, airbnb_partner, avantio, barefoot_direct, beds24, best_beach, booking_connect, booking_experts, bookingsync, brightside, ciirus, cloudbeds, direct, elina, escapia, fake, fake_2, fake_pms, fantasticstay, gfh, guesty, homeaway, homhero, homhero_staging, hospitable, hostaway, hostfully, hosthub, hostify, icnea, igms, ipro, janiis, kigo, kigo_pro, kross_booking, lightmaker, liverez, lodgable, lodgify, lodgify_partner, lodgix, loggia, mews, myvr, octorate, opera, ownerrez, real_time_rental, rentalready, rentals_united, resly, rms, secra, septeo, smoobu, stays, streamline, supercontrol, tokeet, track, travelmob, uplisting, villas365, vrbo, vreasy, vrm, zeevou, zeevou_direct'
                credentials:
                  type: object
                  additionalProperties: {}
                  description: Credentials for the specified channel
              required:
              - channel
              - credentials
      required:
      - data
    PaginatedAccountList:
      type: object
      properties:
        data:
          type: array
          items:
            $ref: '#/components/schemas/Account'
        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
    AccountResponse:
      type: object
      properties:
        data:
          $ref: '#/components/schemas/Account'
      required:
      - data
    AccountSyncStatus:
      type: object
      description: 'Serializer for the account sync status.


        Receives the full ManagedAccount instance via ``source="*"`` and derives

        the sync state from the pending sync job and ``listings_synced_at``.'
      properties:
        state:
          allOf:
          - $ref: '#/components/schemas/StateEnum'
          description: 'Current sync state: queued, in_progress, completed, or unknown


            * `queued` - queued

            * `in_progress` - in_progress

            * `completed` - completed

            * `unknown` - unknown'
        last-successful-sync-at:
          type:
          - string
          - 'null'
          format: date-time
          description: Timestamp of the last successful listing sync, or null if never synced
      required:
      - last-successful-sync-at
      - state
    Account:
      type: object
      required:
      - type
      - id
      additionalProperties: false
      properties:
        type:
          allOf:
          - $ref: '#/components/schemas/AccountResourceTypeEnum'
          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: {}
        attributes:
          type: object
          properties:
            user-id:
              type: integer
              description: ID of the user who owns this account
            channel:
              type: string
              description: Channel identifier (e.g., 'airbnb', 'guesty')
            channel-id:
              type: string
              description: Account identifier on the channel side
            channel-display-id:
              type:
              - string
              - 'null'
              description: Human-readable display ID
            label:
              type: string
              description: Human-readable channel label
            email:
              type:
              - string
              - 'null'
              description: Email associated with this account
            valid:
              type: boolean
              description: Whether the account credentials are currently valid
            nb-enabled-listings:
              type: integer
              readOnly: true
              description: Number of enabled listings in this account
            nb-listings:
              type: integer
              readOnly: true
              description: Total number of listings in this account
            is-pms:
              type: boolean
              readOnly: true
              description: Whether this channel is a property management system
            sync-status:
              allOf:
              - $ref: '#/components/schemas/AccountSyncStatus'
              readOnly: true
              description: Status of the account sync process started after account connection
          required:
          - id
          - user-id
          - channel
          - channel-id
          - channel-display-id
          - label
          - email
          - valid
  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
    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.