Manage OAuth tokens that expire when calling external APIs from Bubble. This tutorial shows you how to store access and refresh tokens in the database, build a token refresh workflow that runs before each API call, and handle token rotation so your app never breaks due to expired credentials.
Overview: Dynamic Authentication for API Endpoints in Bubble
Many external APIs use OAuth2 tokens that expire after a set period. When your Bubble app calls these APIs, you need to detect expired tokens, refresh them automatically, and retry the original request. This tutorial covers the full lifecycle from initial token storage to automatic refresh and rotation.
Prerequisites
- A Bubble app with the API Connector plugin installed
- An external API that uses OAuth2 with refresh tokens
- Basic understanding of backend workflows in Bubble
- Familiarity with the API Connector plugin configuration
Step-by-step guide
Create a data type for storing API credentials
Create a data type for storing API credentials
Go to the Data tab and create a new Data Type called APICredential. Add fields: service_name (text), access_token (text), refresh_token (text), token_expires_at (date), and user (User). This stores tokens per user per service. Set Privacy Rules so each user can only access their own credentials.
Pro tip: Never store tokens in custom states or URL parameters — always use the database with Privacy Rules for security.
Expected result: An APICredential data type with fields for tokens, expiration, and user association.
Store tokens after initial OAuth authorization
Store tokens after initial OAuth authorization
After the user completes the OAuth flow (using the API Connector's OAuth2 setup), create a workflow to save the tokens. Add a Create a new APICredential action with service_name set to the API name, access_token and refresh_token from the OAuth response, token_expires_at set to Current date/time plus the expires_in value (usually 3600 seconds = 1 hour), and user set to Current User.
Expected result: Tokens are stored in the database immediately after the user authorizes the external service.
Build the token refresh backend workflow
Build the token refresh backend workflow
Navigate to Backend workflows and create a new workflow called refresh_api_token. Add a parameter: credential (type APICredential). Add an API Connector action that calls the external API's token refresh endpoint with the stored refresh_token. The response returns a new access_token and optionally a new refresh_token. Add a Make changes to credential action to update access_token, refresh_token (if returned), and token_expires_at.
Expected result: A backend workflow that exchanges a refresh token for new access and refresh tokens.
Add a pre-call token check workflow
Add a pre-call token check workflow
Before any API call that uses the stored token, add a conditional check. In your frontend workflow, add a step: Do a search for APICredentials where user is Current User and service_name is the target service. Check if token_expires_at is less than Current date/time plus 5 minutes (refresh early to avoid race conditions). If yes, Schedule API Workflow refresh_api_token with the credential. Wait for completion, then proceed with the API call using the updated access_token.
Pro tip: Refresh 5 minutes before expiration rather than at expiration to account for network delays.
Expected result: Every API call automatically checks token freshness and refreshes if needed before making the request.
Handle refresh token failures gracefully
Handle refresh token failures gracefully
Sometimes refresh tokens themselves expire or get revoked. In the refresh_api_token backend workflow, add error handling. If the refresh call returns an error (usually 401 or 400), update the APICredential's access_token to empty and redirect the user to re-authorize. Show a user-friendly message explaining they need to reconnect the service.
Expected result: When token refresh fails, the user is prompted to re-authorize rather than seeing a cryptic error.
Implement token rotation for security
Implement token rotation for security
Some APIs issue a new refresh token with every refresh (token rotation). In your refresh workflow, always save both the new access_token and the new refresh_token from the response. If the API supports rotation, the old refresh token becomes invalid immediately. Add a check: if the API response includes a refresh_token field, update it; otherwise keep the existing one.
Expected result: Token rotation is handled automatically, always storing the latest valid refresh token.
Complete working example
1DYNAMIC AUTH — WORKFLOW SUMMARY2================================34DATA MODEL5 APICredential:6 - service_name (text)7 - access_token (text)8 - refresh_token (text)9 - token_expires_at (date)10 - user (User)11 Privacy: User can only see own credentials1213BACKEND WORKFLOW: refresh_api_token14 Parameter: credential (APICredential)15 Step 1: API Connector → Token Refresh Call16 - URL: https://api.example.com/oauth/token17 - Body: grant_type=refresh_token&refresh_token=credential's refresh_token18 Step 2: Make changes to credential19 - access_token: Result of step 1's access_token20 - refresh_token: Result of step 1's refresh_token (if present)21 - token_expires_at: Current date/time +(seconds): expires_in22 Error handling: If step 1 fails → clear access_token2324FRONTEND PRE-CALL CHECK25 Step 1: Search for APICredential (user + service)26 Step 2: If token_expires_at < Current date/time + 5 min27 → Schedule refresh_api_token28 → Wait for completion29 Step 3: Proceed with API call using fresh access_token3031RE-AUTHORIZATION FLOW32 If refresh fails (401/400):33 → Clear tokens from credential34 → Show reconnect prompt to user35 → Redirect to OAuth authorization URLCommon mistakes when handling dynamic authentication for API endpoints in Bubble.io: Step-by-Ste
Why it's a problem: Storing tokens in custom states or frontend elements
How to avoid: Always store tokens in a database Data Type with Privacy Rules restricting access to the token owner.
Why it's a problem: Not refreshing tokens before they expire
How to avoid: Refresh tokens 5 minutes before expiration to ensure a valid token is always available.
Why it's a problem: Ignoring refresh token rotation
How to avoid: Always check if the refresh response includes a new refresh_token and update it in the database.
Best practices
- Store all tokens in the database with Privacy Rules, never in custom states
- Refresh tokens 5 minutes before expiration to prevent race conditions
- Handle refresh failures by prompting re-authorization instead of showing errors
- Log token refresh events for debugging authentication issues
- Use backend workflows for token refresh to keep credentials server-side
- Implement token rotation by always saving new refresh tokens from responses
Still stuck?
Copy one of these prompts to get a personalized, step-by-step explanation.
My Bubble.io app connects to an external API using OAuth2 tokens that expire hourly. How do I store tokens securely, refresh them automatically before expiration, and handle cases where the refresh token itself expires?
Create a token management system for my API integration. Add an APICredential data type, a backend workflow for refreshing tokens, and a pre-call check that automatically refreshes expired tokens before making API requests.
Frequently asked questions
How long do OAuth access tokens typically last?
Most APIs issue access tokens valid for 1 hour (3600 seconds). Some APIs use shorter (15 min) or longer (24 hour) durations. Check the API documentation for the exact value.
What happens if both access and refresh tokens expire?
The user must re-authorize by going through the OAuth flow again. Show a clear message explaining the reconnection is needed.
Can I refresh tokens from a frontend workflow?
Technically yes, but it is more secure to use backend workflows. Frontend workflows expose network requests in the browser, potentially leaking token data.
How do I handle multiple APIs with different token lifetimes?
The APICredential data type uses a service_name field to differentiate services. Each credential has its own expiration and refresh logic.
Should I encrypt tokens in the database?
Bubble encrypts its database with AES-256 at rest. For additional security, you could encrypt tokens before storing them, but this adds complexity. Privacy Rules are the primary access control.
Can RapidDev help with complex API authentication flows?
Yes. RapidDev can implement OAuth2, JWT, API key rotation, multi-service authentication, and custom token management for enterprise API integrations.
Talk to an Expert
Our team has built 600+ apps. Get personalized help with your project.
Book a free consultation