Integration and authorization
This guide explains how partners authenticate and obtain a public user bearer for calling the Funtrips (QueueUp) content & checkout APIs.
We support two integration modes
- Headless (full API integration)— Your backend uses Client Credentials to create a one-time session code, then your backend exchanges that code for a public bearer, which your frontend can use.
- Webframe (hosted UI) — Your backend uses Client Credentials to create a one-time session code, then Funtrips’ web app (inside your frame/webview) exchanges that code for a public bearer. You do not call the token exchange endpoint yourself.
Quick Glossary
- Backend bearer (client credentials): Server-to-server OAuth 2.0 token used by your backend only (e.g., to create session codes).
- Session code: One-time, short-lived string created by
/session. It can be redeemed exactly once. - Public bearer: Short-lived JWT scoped for end-user operations (list merchants, products, availability, create checkouts, etc.). Safe to use from the browser / mobile webview (with normal precautions).
High-level Flow
🧠 Headless (server → server → frontend)
- Your backend obtains a backend bearer via Client Credentials.
- Your backend calls POST /v1/session with that bearer → receives a session code.
- Your backend calls POST /v1/session/token with the session code → receives a public bearer.
- Your frontend uses the public bearer for product/availability/checkout API calls.
sequenceDiagram
autonumber
participant UserFE as User Frontend
participant PartnerBE as Partner Backend
participant FTAuth as Funtrips Auth
participant FTAPI as Funtrips API
UserFE->>PartnerBE: User wants to browse or purchase
PartnerBE->>FTAuth: POST /oauth/token (client_credentials)
FTAuth-->>PartnerBE: 200 { backend_bearer }
PartnerBE->>FTAPI: POST /v1/session { integration:headless } (Auth: backend_bearer)
FTAPI-->>PartnerBE: 200 { session_code }
PartnerBE->>FTAPI: POST /v1/oauth/token { code: session_code }
FTAPI-->>PartnerBE: 200 { public_bearer }
PartnerBE-->>UserFE: Return public_bearer
UserFE->>FTAPI: (Auth: public_bearer) Access merchants/products/checkout
FTAPI-->>UserFE: 200 OK
🪟 Webframe (server → server → webframe)
- Your backend obtains a backend bearer via Client Credentials.
- Your backend calls POST /v1/session → receives a session code and a frame_url.
- Your mobile/web app opens the Funtrips webframe (e.g., frame_url?session_code=...).
- Funtrips (inside the webframe) redeems the code and stores the public bearer internally.
- You do not implement /session/token in this mode; the frame handles it.
sequenceDiagram
autonumber
participant PartnerBE as Partner Backend
participant FTAuth as Funtrips Auth
participant FTAPI as Funtrips API
participant Webframe as Funtrips Webframe
PartnerBE->>FTAuth: POST /oauth/token (client_credentials)
FTAuth-->>PartnerBE: { backend_bearer }
PartnerBE->>FTAPI: POST /v1/session (Auth: backend_bearer)
FTAPI-->>PartnerBE: { session_code, frame_url }
PartnerBE->>Webframe: Open frame_url?session_code=...
Webframe->>FTAPI: Exchange code → public bearer
FTAPI-->>Webframe: { public_bearer }
Webframe->>FTAPI: Use public bearer for /merchants, /products, /checkout
FTAPI-->>Webframe: 200 OK
Integration
🧩 Get a Backend Bearer (Client Credentials)
Before starting a user session, your backend must authenticate using OAuth 2.0 Client Credentials. This is a server-to-server authentication step that grants a backend bearer token, which is only used for administrative and secure operations—such as creating session codes.
The Client Credentials flow requires:
- client_id — issued by Funtrips for your integration
- client_secret — your private secret (never shared client-side)
- grant_type=client_credentials
Once exchanged, this returns a short-lived backend access token. Use this token only from your backend services to call the session creation endpoint.
This backend token should never be exposed to client or browser environments.
See the backend authentication for details
Notes
- queueup will provide you with a
client_idandclient_secret - The
client_secretis confidential and should only be used for server-to-server requests - When the authorization bearer expires, a new one can be negotiated
🔑 Start a Session → Receive a One-Time Code**
After obtaining your backend bearer token, your backend calls the Session Start endpoint to create a short-lived, one-time session code. This code is tied to your user and (optionally) a campaign.
The session code has two distinct use cases:
- Webframe Integration: Your backend starts a session and then opens the Funtrips-hosted webframe with the session_code in the query string. The Funtrips web application automatically exchanges this code for a public bearer token—you do not need to handle the exchange.
- Headless API Integration: Your backend or client application exchanges the code directly for a public bearer token via the token exchange endpoint. This public bearer can then be stored in your client and used for merchant, product, and checkout calls.
The session code is single-use and expires after a few minutes for security reasons.
See the session endpoint for details
Notes
- code is single-use and expires at
code_expires_at. pkce_requiredwill be false in both modes (per this integration plan).- For webframe, we include a
frame_url. You will append thesession_codequery param when opening it. - Additional security using
PKCEis supported
🧠 Headless: Exchange the Code for a Public Bearer (Your Backend)
Once your backend has created a session code, the next step is to exchange it for a public bearer token. This token represents the authenticated user within your application and is used for all subsequent API calls (e.g., merchants, products, availability, checkout).
In a headless integration, this exchange is performed by your backend to keep secrets secure. The backend sends a POST request to the Token Exchange endpoint, including:
- the one-time session_code
- the client_id and client_secret from your OAuth credentials
- for PKCE-enabled clients: the original code_verifier
The response returns a public bearer JWT, which should be passed to your frontend (or mobile app) and included in all future API requests via the Authorization: Bearer header.
The session code is single-use and expires after a few minutes. If the exchange fails due to expiration, your backend should start a new session and repeat the flow.
See the exchange token endpoint for details
🪟 Webframe: Code Exchanged Automatically by Funtrips
In a webframe integration, your backend does not need to perform the code exchange manually. Instead, once your system has created a session code, you simply open the Funtrips-hosted webframe and include the code as a query parameter.
Example URL pattern:
GET https://app.funtrips.io/frame?session_code=sc_8f4fdd3b9a8c4a8085f2a3b5a1f2e9c1When the webframe loads, Funtrips automatically redeems the code with the backend and issues a public bearer token internally. This token is securely stored within the webframe’s context and used for all subsequent API calls (e.g., merchants, products, availability, checkout).
Notes:
- You never need to handle or expose bearer tokens yourself.
- The token exchange and storage happen securely within Funtrips’ own environment.
- Your only responsibility is to generate the session code via the backend and pass it into the frame.
Because Funtrips performs the exchange, PKCE is not supported for this flow.
🔑 Use the public bearer
Once a public bearer is issued (either you exchanged the code in a headless flow, or Funtrips exchanged it inside the webframe), include it on every request to the content/commerce endpoints.
How to send it
Add the HTTP header: Authorization: Bearer public_token
Lifetime & renewal
- Public bearers are short-lived and scoped to a session.
- When you receive 401 Unauthorized due to expiration, start a new session and obtain a new code → bearer (headless), or reopen the webframe with a fresh code (webframe flow).
- There is no refresh token; rotation is by creating a new session code.
Storage guidance
- Headless (your frontend): keep tokens in memory (preferred). If you must persist across reloads, use sessionStorage over localStorage. Never store in cookies, HTML, or URLs.
- Webframe: handled by Funtrips internally—you never see or store the token.
Do not
- Don’t put tokens in URLs, query params, or logs.
- Don’t share a public bearer across users or devices.
- Don’t rely on the public bearer for backend-to-backend calls (use Backend OAuth for that).
Updated about 2 months ago
