Skip to content

Authentication

This page is the overview for all supported ways to call the Partners API (/api/v1/*). Step-by-step curl examples live in the profile guides linked below.

Choose The Right Mechanism

Who you are What you should use Why
Partner or company integrating many customers on a secure backend OAuth2 client credentials with a confidential client Strongest option: client secret never ships to end-user devices, machine-to-machine access, optional per-user and per-credential narrowing with user_id and credential_id.
Individual Beyond user automating your own account (CLI, script, agent) OAuth2 device authorization on a public client or a personal access token (PAT) Public clients cannot hold a shared secret safely. Device flow is best for interactive sign-in and rotating refresh tokens. A PAT is a simpler alternative when Beyond has already issued a long-lived, credential-scoped secret for non-interactive automation.

Partners should not rely on PATs for production integrations: PATs exist only for personal automation applications, not partner multi-tenant apps.

Personal automation: device flow versus PAT

Both options target the same personal app profile (one OAuth2 application bound to one Beyond user).

Topic Device authorization Personal access token
Minting Your client calls /o/device-authorization/ and /o/token/; the bound user approves in a browser. Beyond provisions the token (support or internal operations). Not minted through /o/token/.
Best for CLIs and tools where the user can complete a browser step; refresh tokens keep access renewable. Servers, cron jobs, or agents where storing one secret is acceptable and you want to skip interactive approval each time.
Bearer format Standard OAuth2 access token (opaque string from /o/token/). Prefix bpat_ (for example Authorization: Bearer bpat_…).
Credential scope Same listing and account visibility as OAuth2 for that user and login. Always tied to one Beyond login (credential) chosen when the PAT was created.

For curl walkthroughs, use CLI And Headless Clients. For partner token requests with user_id / credential_id, use Server Integrations.

On every /api/v1/* request, send the access token or PAT in the header Authorization: Bearer <token>.

OAuth2: Client Credentials (Confidential Partner)

Typical path: your backend exchanges client_id and client_secret for an access token, then calls /api/v1/*. Optional user_id and credential_id narrow the token (see Server Integrations).

sequenceDiagram
    participant Partner as PartnerBackend
    participant Token as OAuthTokenEndpoint
    participant API as PartnersAPI

    Partner->>Token: POST /o/token/ client_credentials
    Note right of Partner: client_id, client_secret, scope optional user_id credential_id
    Token-->>Partner: access_token, expires_in, token_type Bearer
    Partner->>API: GET /api/v1/... with Authorization Bearer
    API-->>Partner: JSON API response

OAuth2: Device Authorization And Refresh (Public Personal Client)

The user completes approval in a browser; your client polls /o/token/ until tokens are returned. Use the refresh grant to obtain new access tokens without another device round-trip.

sequenceDiagram
    participant Client as AutomationClient
    participant Device as DeviceAuthorizationEndpoint
    participant User as UserBrowser
    participant Token as OAuthTokenEndpoint
    participant API as PartnersAPI

    Client->>Device: POST /o/device-authorization/ client_id, scope
    Device-->>Client: device_code, user_code, verification_uri
    Client->>User: Show user_code and open verification URL
    User->>User: Sign in and approve scopes at Beyond
    loop Poll at interval from device response
        Client->>Token: POST /o/token/ device_code grant
        Token-->>Client: authorization_pending or access plus refresh tokens
    end
    Client->>API: GET /api/v1/... with Authorization Bearer
    Note over Client,Token: Later POST /o/token/ refresh_token grant for rotated refresh and new access token

Shared OAuth2 Rules

The Partners API follows RFC 9700 - OAuth 2.0 Security Best Current Practice.

Token Lifetimes

  • Access tokens expire after 1 hour.
  • Refresh tokens expire after 30 days (where the grant uses them).
  • Refresh tokens rotate on refresh.

Grant Restrictions

Grant Type Status Notes
Client Credentials Allowed For partner server integrations
Device Authorization Allowed For personal automation clients
Refresh Token Allowed For device flows
Implicit Disabled Rejected
Password Disabled Rejected

User-Scoped Tokens

Server integrations can ask /o/token/ for either an application-level token or a user-scoped token:

  • Application-level token: omit user_id. The token acts for the OAuth application and can access all users owned by that application, subject to the scopes granted on the token.
  • User-scoped token: include user_id. The token is bound to that one user. You may also include credential_id to apply one Beyond login's visibility and permissions; without it, Beyond uses the user's primary credential.

If Beyond enables require_user_scoped_tokens for your application, user-level resource scopes cannot be used on an application-level token. You must include user_id for those scopes. App-level scopes and cross-tier scopes still work without user_id.

Scope Tiers

All requested scopes must first be enabled for your OAuth application. After that, token tier rules apply:

Tier Scopes Application-level token, no user_id User-scoped token, with user_id
App-level user:write Allowed. Operates on the application as a whole. Rejected. App-level scopes cannot be combined with user_id.
User-level listings:read, listings:write, reservations:read, accounts:read, insights:read Allowed only when require_user_scoped_tokens is disabled for the application. Rejected when it is enabled. Allowed. Access is limited to the bound user, and to the selected credential when credential_id is present.
Cross-tier user:read Allowed. Returns users owned by the application. Allowed. Returns only the bound user.

Scope Reference

Scope Tier Description
user:write App-level Create and modify users
user:read Cross-tier Read user information
listings:read User-level Read listing data
listings:write User-level Modify listings
reservations:read User-level Read reservation data
accounts:read User-level Read account information
insights:read User-level Read market insights

IP Allowlist

When configured for an application, IP allowlists are enforced on both /o/ and /api/v1/.

Personal Access Token (PAT)

PATs are not an OAuth2 grant. Beyond users can create and manage their own PATs from the Beyond dashboard user settings when they need a long-lived credential for personal automation. Beyond shows the secret exactly once at creation time; after that, each request uses Authorization: Bearer with the PAT. Store it like any other high-value credential. Allowed scopes, IP restrictions (when Beyond has configured them for the app), and what listings and accounts the token can see follow the same rules as for OAuth2 access tokens for that same app and login.

sequenceDiagram
    participant Client as AutomationClient
    participant API as PartnersAPI

    Client->>API: Authorized request with Bearer PAT
    API-->>Client: JSON API response

Use your issued cleartext value in the Authorization header. Personal access tokens always start with the bpat_ prefix.

PAT Rules (Summary)

  • Personal automation only — PATs are for personal automation apps (one Beyond user), not for partner-style multi-customer integrations.
  • One login — A PAT only ever acts as the Beyond login it was issued for. It cannot switch to another login under the same user.
  • Self-service creation — PATs are created from the Beyond dashboard, not minted through /o/token/.
  • Scopes — PATs use the same scope names as OAuth2. Each PAT is limited to a subset of scopes Beyond enabled for your app; if Beyond later removes a scope from the app, existing PATs lose that scope too.
  • No OAuth minting — PATs are not created or refreshed through /o/token/. Use the device or refresh flow when you need OAuth-issued tokens instead.