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.
- Server Integrations — confidential clients and client credentials
- CLI And Headless Clients — public clients and the device authorization grant
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 includecredential_idto 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.