Creation
A connection is created when:- a user completes the authorization flow, or
- you import existing tokens with
POST /v1/connections(useful when migrating from your own OAuth implementation).
connection.created webhook.
Token refresh
Access tokens expire. Some last an hour, some a few minutes, some never. BundleUp keeps them fresh on demand, at the moment a request needs them:
If several requests for the same connection need a refresh at the same moment, only one refresh call is made to the provider and all requests use its result. This matters for providers that rotate refresh tokens: two simultaneous refreshes would otherwise invalidate each other.
Each successful refresh sends a
connection.refreshed webhook.
You can also refresh a connection by hand from the dashboard (Connections → Refresh connection token), for example after fixing an integration’s credentials.
Because refresh happens on demand, a connection that isn’t used for a long time isn’t refreshed in the meantime. That’s fine for most providers: the refresh token is still valid when the next request arrives. A few providers expire unused refresh tokens after a period of inactivity, in which case the user needs to reconnect.
When a refresh fails
A refresh can fail because the user revoked access at the provider, the provider expired the refresh token, the integration’s client secret changed, or the provider was briefly unavailable.- If the token had already expired, the request that triggered the refresh fails and nothing is sent to the provider. On the Proxy and MCP, you get
400 connection_refresh_failedwhen the connection has no refresh token, or a5xxerror when the provider rejects the refresh. - If the refresh was a background one, the current token is still valid, so your request goes through. The failure is silent.
- Watch for repeated
connection_refresh_failederrors, or401/403responses from the provider, on the same connection. - Show the user a “Reconnect” prompt that runs the authorization flow again.
- Store the new connection ID and delete the old connection.
Updates
The only field you can change on a connection is its external ID, from the dashboard or withPATCH /v1/connections/{id}. Changing it sends connection.updated.
To change a connection’s scopes, the user has to go through the authorization flow again, which creates a new connection.
Deletion
Delete a connection when the user disconnects the integration in your product, or when you replace it with a new one:connection.deleted. Any later request with that connection ID fails with connection_invalid.
Deleting an integration deletes all of its connections.
When users revoke access at the provider
If a user removes your app from their account in the provider’s settings, BundleUp isn’t told. The connection still exists, but the provider rejects its token, usually with401. The next refresh also fails. Handle it like any permanent refresh failure: prompt the user to reconnect, then delete the old connection.
