UK and European Open Banking regulations require users to periodically reconfirm their consent to share account data with your app. This article explains what that consent is, how long it lasts, and what to build to keep it renewed.
What is consent under Open Banking?
Open Banking in the UK, and the equivalent PSD2 framework in the rest of Europe, requires a user to give explicit consent before a third party like your app can access their account data. To grant that consent, the user completes Strong Customer Authentication (SCA) directly with their bank, confirming their identity and authorizing the specific data being shared.
This consent is not permanent. Regulation requires it to be periodically reconfirmed for data access to continue. How that reconfirmation happens, and how often, is set by regulation and by each bank's own implementation, not by your integration.
On Plaid's side, this is tracked on the Item's consent_expiration_time field. Consent is separate from the item's access_token, which does not expire on its own: once consent expires, the access_token still exists, but no further data can be retrieved for that item until the user renews their consent through Link's update mode.
Consent duration depends on the institution's country: UK institutions have a 90-day consent window, and institutions elsewhere in Europe have a 180-day window.
What the user sees at renewal
For UK institutions that support the faster flow: the user opens Link and sees a single confirmation screen asking them to confirm they still want to share access. They confirm with one click and are done. They are not sent to their bank.
For UK institutions that have not yet adopted the faster flow, and for institutions elsewhere in Europe: the user opens Link and is redirected to their bank to authenticate again, similar to the original connection flow.
Which of these a user sees is determined by the institution, not by your integration. There is no parameter in /link/token/create to request one flow over the other.
Example: UK renewal, both possible outcomes
A user connects a UK bank account. Ninety days later, your app receives a PENDING_EXPIRATION webhook and prompts the user to reconnect. From here, one of two things happens, depending on that institution:
If the institution supports the faster flow: the user opens Link, sees the one-click confirmation screen, confirms, and is done. They never leave your app or see their bank's login page.
If the institution has not adopted the faster flow: the user opens Link and is redirected to their bank's login page, authenticates, and is returned to your app once finished.
Your integration is identical in both cases. It calls /link/token/create with the item's access_token and opens Link the same way, regardless of which screen the user ends up seeing.
Example: renewal elsewhere in Europe
A user connects a bank account in a European country outside the UK. One hundred eighty days later, your app receives the same PENDING_EXPIRATION webhook and prompts the user the same way. The user opens Link and is redirected to their bank's login page to authenticate again, then returned to your app once finished.
Unlike the UK case, there is currently no one-click outcome for these institutions. Every renewal for a non-UK European institution goes through the bank redirect.
What to build
The integration steps are the same regardless of which screen the user ends up seeing:
-
Listen for the
PENDING_EXPIRATIONwebhook. It's sent seven days before a UK or European item's consent expires. - Prompt the user to reconnect. Once the webhook fires, notify the affected user in your app.
-
Call
/link/token/createwith the item's existingaccess_token. This puts Link into update mode for that item. -
Open Link with the resulting
link_token, the same way Link is opened elsewhere in your integration.
No separate screen needs to be built for the renewal step itself. Whichever flow applies is rendered by Link.
If an item reaches a state where its consent can no longer be renewed, remove the item and have the user reconnect from the start using [/item/remove](https://plaid.com/docs/api/items/#itemremove).
For full implementation details, see Link - Update mode.