I ran into an issue recently with API tokens suddenly becoming invalid for users, and after digging into it with Bubble support, I wanted to share what I learned — since this behavior is currently not documented but intended by design.
The issue
I was using user tokens (with a 360-day expiration) in a 3rdParty-to-Bubble integration, expecting them to remain valid for the full duration. However, some tokens started failing unexpectedly — with no clear indication or error until the system broke.
What Bubble support confirmed
Bubble support told me the following:
User tokens are automatically invalidated after 30 days of inactivity.
This is by design, to avoid long-term memory leaks and enforce better security for dormant sessions.
As long as a user remains “active”, the session is extended by another 30 days. But 30 days dormant users get their token to expire.
Unfortunately, there’s no way to check in advance if a token is still valid — you only find out when it fails.
The workaround
I asked if there was any way to work around this, and here’s what support suggested:
“You should be able to work around this by scheduling a no-op workflow every week or so that reschedules itself, or by embedding a re-login flow into your automations.”
To keep a token alive for more than 30 days:
Schedule a recurring no-op workflow (e.g. every 25–28 days) that makes an API call using the user’s token.
This counts as activity and resets the inactivity timeout.
Alternatively, consider re-authenticating the user regularly, though this is less ideal for user experience.
TL;DR
User tokens expire after 30 days of inactivity, even if they were created with a 360-day lifespan.
There is no warning or visibility when a token is invalidated.
You can keep tokens alive with regular background activity using the token.
Hope this helps others avoid the same confusion. I also hope this behavior will be officially documented in Bubble’s API/token documentation in the future.
If anyone’s found other solutions or patterns, feel free to share them below!
The idea is to schedule a workflow that uses the token to call a Bubble API.
This Bubble API is executing an API workflow that does nothing (no-op).
You only add an action “return data from API” and you include something like isTokenValid=true
If the token is valid, you get “true”
FYI, even with this in place, we still have users that get an invalid tokens. (Bubble support is investigating currently)
Managing the error (if isTokenValue=false then do something) help us to wipe out the token from database and to force login to generate a new token.
FYI, here is our final implementation. It has been running for months without any token loss.
1. Token creation
When the token is created, we schedule a backend workflow in 28 days. Let’s call it BWF1.
2. BWF1 execution
When BWF1 runs, it makes an API call using the user’s token. Let’s call it API1.
3. API1 behavior
When API1 is called, there are two possible outcomes:
3A: Token is valid
→ API1 schedules BWF1 again 28 days later and returns isTokenValid=TRUE.
3B: Token is not valid
→ By security design, it returns an ERROR.
4. BWF1 handling of the result
4A: If isTokenValid=TRUE
→ Everything is fine.
4B: If ERROR
→ The user’s token is wiped from the database.
All of the above properly extends the token’s validity. It seems to work because API1 is actually performing an action (scheduling BWF1 again). Previously, the system failed when BWF1 simply returned isTokenValid=TRUE without doing anything.
Improvements added
When BWF1 receives an ERROR, it sends an email alert to our sysadmin team.
Since implementing this version of the fix, we haven’t received any alerts.
We store the scheduled BWF1 ID next to the user’s token to ensure that only one BWF1 is scheduled per user, just in case another process attempts to create one.
Thanks, it’s great to see that the feedback can be helpful
However, I noticed you mentioned that a no-op workflow is enough to extend the token validity. Based on my experience, that’s not correct.
Sorry if that wasn’t clear enough earlier. What I was trying to explain in this sentence:
In our case, the token was only extended when the workflow actually performed an action, such as scheduling BWF1 again. When BWF1 simply returned isTokenValid = TRUE without doing anything else, the token was not extended and eventually expired.
So from what I’ve observed, a no-op workflow is not sufficient. The workflow needs to execute a real action in order to extend the token.