# Renew Consents (/data-api/guides/resources/renew-consents)

A playbook for helping customers renew Data API consents before they expire.



Customer consent is not a "set and forget" connection. For privacy and regulatory reasons, consents have expiry dates to prevent unfettered access to a user's data. Your application needs a renewal process that helps users refresh their consent before access is interrupted.

This playbook explains how to identify expiring consents, notify customers, and create a renewal [Auth Session](/data-api/guides/core-concepts/auth-sessions) so users can update an existing consent without starting from scratch.

<Callout type="info">
  Consent renewal uses the existing consent's `arrangement_id`. The renewed consent uses the permissions from the existing consent, while the new consent period comes from your current team configuration in the Fiskil Console.
</Callout>

How Consent Expiry Works [#how-consent-expiry-works]

A consent can last for up to 12 months. The consent duration is configurable in the [Fiskil Console](https://console.fiskil.com/) as part of your consent flow setup, alongside data history, use case descriptions, and branding.

When a consent expires, your application may no longer be able to access the user's shared data. To avoid broken connections, notify users at least one month before expiry, or earlier depending on your product experience.

A good renewal workflow usually looks like this:

1. Find consents that are approaching expiry.
2. Notify affected users in your app, by email, SMS, or another owned channel.
3. Create a new Auth Session using the existing consent's `arrangement_id`.
4. Send the user through the consent update flow with [Fiskil Link](/data-api/guides/link-widget/integrating-the-link-sdk).
5. Listen for confirmation that the consent was updated.

Recommended Renewal Timeline [#recommended-renewal-timeline]

Start renewal outreach before the consent becomes urgent.

| Time before expiry | Recommended action                                                |
| ------------------ | ----------------------------------------------------------------- |
| 60-45 days         | Optional early reminder for low-frequency users.                  |
| 30 days            | Start your main renewal campaign.                                 |
| 14 days            | Show in-app prompts or banners.                                   |
| 7 days             | Increase urgency in messaging.                                    |
| 1-3 days           | Send a final reminder before the connection expires.              |
| After expiry       | Ask the user to reconnect before you attempt further data access. |

You can choose the exact timing, but avoid waiting until the final few days. Users may need time to log in to their institution, complete OTP verification, and select accounts.

Step 1: Find Consents Approaching Expiry [#step-1-find-consents-approaching-expiry]

Use the [Consents API](/data-api/api-reference/consents#list-consents) to query consents that are due to expire soon. Pass `active=true` with `expires_before` to find active consents expiring before an RFC3339 timestamp.

```bash
curl --request GET \
  --url "https://api.fiskil.com/v1/consent?active=true&expires_before=2026-07-09T00:00:00Z" \
  --header "Authorization: Bearer ${access_token}" \
  --header "Accept: application/json"
```

Example response:

```json
[
  {
    "arrangement_id": "94549a73-a554-4b76-b824-d96898829751",
    "end_user_id": "eu_2yRHN2ag2y4p8kCtm5DOeccZEXB",
    "institution_id": "11",
    "institution_name": "Example Bank",
    "active": true,
    "permissions": ["accounts", "balances", "transactions"],
    "duration": 31536000,
    "expires_at": "2026-07-09T00:00:00Z"
  }
]
```

To find recently expired consents, query inactive consents and filter by `expires_before` or your own stored expiry timestamp.

```bash
curl --request GET \
  --url "https://api.fiskil.com/v1/consent?active=false&expires_before=2026-07-09T00:00:00Z" \
  --header "Authorization: Bearer ${access_token}" \
  --header "Accept: application/json"
```

Use the returned `arrangement_id`, `end_user_id`, `institution_id`, and `expires_at` values to decide which customers to contact and when.

Step 2: Notify the User [#step-2-notify-the-user]

Once you know which consents are approaching expiry, notify the user through your preferred channel.

Your message should clearly explain:

* Their current connection is due to expire.
* Renewal keeps their account or service connected.
* They will be redirected to their institution to confirm consent.
* They can review or update which accounts are shared.

Example in-app copy:

> Your bank connection expires soon
>
> To keep your account data up to date, renew your consent before 9 July 2026. You'll be asked to securely authenticate with your institution and confirm the accounts you want to share.

Avoid implying that consent renewal is automatic. The user must complete the institution flow themselves.

Step 3: Create a Renewal Auth Session [#step-3-create-a-renewal-auth-session]

To renew an existing consent, create a new Auth Session and pass the existing consent's `arrangement_id`. This tells Fiskil to launch an update flow for the current arrangement instead of creating an unrelated new connection.

<Callout type="info">
  Permissions come from the existing consent, not from the current team configuration.
</Callout>

For renewal:

* The renewed consent period comes from the current team configuration in the Fiskil Console.
* The `institution_id` can be included to keep the user on the same institution.
* `redirect_uri` and `cancel_uri` are required for redirect flows, but can be omitted when you are using the Link SDK.

```bash
curl --request POST \
  --url "https://api.fiskil.com/v1/auth/session" \
  --header "Authorization: Bearer ${access_token}" \
  --header "Accept: application/json" \
  --header "Content-Type: application/json" \
  --data '{
    "end_user_id": "eu_2yRHN2ag2y4p8kCtm5DOeccZEXB",
    "arrangement_id": "94549a73-a554-4b76-b824-d96898829751",
    "institution_id": "11"
  }'
```

Example response:

```json
{
  "id": "5qcql2s0bn9qfh1m5qd1sl4gth",
  "session_id": "ea564d-56012s4-6ds4564",
  "auth_url": "https://auth.fiskil.com/consent?session=ea564d-56012s4-6ds4564",
  "expires_at": 1621083785
}
```

Store the `session_id` for debugging and audit purposes, then pass it to Link.

Step 4: Send the User Through Link [#step-4-send-the-user-through-link]

Use the [Fiskil Link SDK](/data-api/guides/link-widget/integrating-the-link-sdk) to launch the consent update flow inside your application.

```typescript
import { link } from '@fiskil/link';

const flow = link('ea564d-56012s4-6ds4564');

try {
  const result = await flow;
  console.log('Renewed consent:', result.consentID);
} catch (err) {
  console.error('Renewal failed:', (err as any).code);
}
```

During the update flow, the user will typically:

* Review the consent request.
* Authenticate with their institution.
* Confirm the accounts they want to share.
* Return to your application once complete.

For update flows, previously shared accounts are preselected where supported. The user can still review and adjust their selection before confirming the renewed consent.

Once the user completes the flow, continue with your normal post-consent handling. For example, refresh account data, update the user's connection status, or remove renewal banners from your application.

Step 5: Track the Result [#step-5-track-the-result]

Track consent renewal using your Link result, redirect flow, and webhooks. Webhooks are the most reliable server-side signal because they do not depend on the user returning to your application successfully.

Fiskil supports consent webhook events, including `consent.received`, `consent.updated`, and `consent.revoked`. A `consent.updated` event is emitted when Front Door completes the renewal through `authorize_callback` and confirms that an access token exists.

Example webhook payload:

```json
{
  "publish_time": "2026-06-09T05:10:03.957Z",
  "message_id": "9061924608716421",
  "data": {
    "event": "consent.updated",
    "consent_id": "con_123456",
    "end_user_id": "eu_2yRHN2ag2y4p8kCtm5DOeccZEXB",
    "client_id": "your_client_id",
    "institution_id": "11"
  }
}
```

When you receive `consent.updated`, mark the connection as renewed and store the latest consent expiry date. Use `message_id` for idempotency so duplicate webhook deliveries do not trigger duplicate work.

Handling Cancelled or Failed Renewals [#handling-cancelled-or-failed-renewals]

If a user cancels or fails the renewal flow, Link rejects with an error code. In a redirect flow, Fiskil redirects the user to your `cancel_uri` with error details.

Example cancelled redirect:

```text
https://yourapp.com/consent/cancelled?error=access_denied&error_type=CONSENT_ENDUSER_DENIED&error_id=err_acde070d-8c4c-4f0d-9d8a-162843c10333
```

| Error type                          | What it means                                                         | Recommended action                                                   |
| ----------------------------------- | --------------------------------------------------------------------- | -------------------------------------------------------------------- |
| `CONSENT_ENDUSER_DENIED`            | The user cancelled or denied consent.                                 | Let the user retry when ready.                                       |
| `CONSENT_OTP_FAILURE`               | The user failed OTP verification.                                     | Ask the user to retry and check their institution details.           |
| `CONSENT_TIMEOUT`                   | The flow timed out or was abandoned.                                  | Create a new Auth Session and let the user try again.                |
| `CONSENT_ENDUSER_INELIGIBLE`        | The institution did not allow the user to share the selected account. | Ask the user to check account eligibility with their institution.    |
| `CONSENT_UPSTREAM_PROCESSING_ERROR` | The institution encountered an error.                                 | Ask the user to retry. Raise a support ticket if the issue persists. |

Best Practices [#best-practices]

* Renew before expiry, not after. Start outreach at least 30 days before expiry so users have time to complete the flow.
* Use the existing `arrangement_id`. This tells Fiskil that the Auth Session is intended to update an existing arrangement rather than create an unrelated new one.
* Keep the message user-friendly. Explain the benefit: renewing consent keeps their connection active. Avoid regulatory language unless your product requires it.
* Handle retries gracefully. Users may abandon the flow, fail OTP, or need to come back later. Make it easy to restart renewal.
* Listen for webhooks. Webhooks help your application react when consent is updated or revoked without relying only on client-side completion. Fiskil retries failed webhook deliveries up to five times with backoff intervals.
