HomeGuidesAPI Reference
Log In
Guides

Implementation Guide

Create an ongoing access flow, exchange the authorization code, and fetch financial data.

Getting Started

Three API calls to set up ongoing access to your user's financial data.

Step 1

Create a Widget link for ongoing account access

Step 2

Exchange the authorization code for an access token

Step 3

Fetch accounts and transactions


1. Create the Widget link

POST https://api.finx-s.qwist.cloud/ongoing/access

{
  "redirect_uri": "https://my-app.example.com/callback",
  "user_id": "user_maria_mueller_42",
  "language": "de",
  "accounts": [
    { "id": "DE89370400440532013000" }
  ],
  "account_types": ["Giro account"],
  "allow_multi_selection": true,
  "sync_period": 90,
  "save_secrets": false
}

Parameters:

ParameterRequiredDescription
redirect_uriWhere the user is returned after the flow.
user_idYour unique identifier for this user. Allows multiple bank connections per user.
languageWidget UI language. Options: de, en, es, fr, ar. Default: de.
accountsPre-fill the user's IBAN to skip bank selection.
account_typesRestrict to specific types (e.g. "Giro account"). Skips the type selection screen.
allow_multi_selectiontrue (default) lets the user connect multiple accounts. Set false to restrict to one.
sync_periodDays of history to fetch on first sync. Default: 90.
save_secretsfalse (default): user sees a checkbox to choose credential storage. true: credentials always saved, autosync always enabled.
📘

Improve conversion

Passing accounts + account_types together gives the best completion rate: the user goes directly to SCA, skipping both bank selection and account type screens.

📘

save_secrets behaviour

When save_secrets is false, the user is shown a "save credentials" checkbox during the Widget flow. If they uncheck it, autosync will not activate. If reliable autosync is required for your product, set save_secrets: true - but review consent obligations with your legal team first.

Response:

{
  "location": "https://widget.qwist.cloud/?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "id": "8f2e9d1c-4b3a-4721-bc8d-2e9f1a3d5c7b"
}

Forward the user to location. The Widget handles bank selection, login, and SCA.

🚧

Looking for one-time access?

See the Financial Data (one-time) Implementation Guide.


2. Exchange the authorization code


2. Exchange the authorization code

After the user completes the Widget flow, they are redirected to your redirect_uri with:

ParameterDescription
codeAuthorization code valid for 1 hour. Present only on success.
flow_idUnique identifier for this flow. Matches the id from step 1.
successtrue if the user completed the flow.
aborttrue if the user cancelled.
stateYour original state value, echoed back for session correlation.

Example callback URL:

https://my-app.example.com/callback
  ?code=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...
  &flow_id=3ca31c37-986a-454e-ad64-8e97143c86bc
  &success=true
  &abort=false
  &state=user_42_session_9f3a
🚧

If abort is true

The user cancelled - no code is returned. Show a dismissal state and let the user retry. Do not attempt to exchange a missing code.

Exchange the code for tokens

POST https://api.finx-s.qwist.cloud/auth/token

// Request
{
  "grant_type": "authorization_code",
  "code": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
  "redirect_uri": "https://my-app.example.com/callback"
}
// Response
{
  "access_token": "AoFmNJLDTW8jQtGSJ1iZeeoLiwNZ2ihz3iiCHGpuvE439nppuY...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "RTfI2WNyK78NozupDH9ai8GPRbjjdVsXPPt...",
  "scope": "accounts=ro balance=ro transactions=ro offline"
}

Use the access_token as a Bearer token in the Authorization header for all subsequent requests. Store both tokens - you will need the refresh_token to keep access alive without re-asking the user.

TokenLifetimeNotes
Authorization code1 hourSingle use
Access token1 hourAuthorization: Bearer {token}
Refresh token90 daysEach use returns a new token - replace it immediately
📘

Token storage

Token lengths vary. Allocate at least 2048 bytes per token field in your database - do not use fixed-size columns.

Refreshing the access token

Access tokens expire after 1 hour. For ongoing access, refresh server-side before expiry rather than waiting for a 401.

POST https://api.finx-s.qwist.cloud/auth/token

// Request
{
  "grant_type": "refresh_token",
  "refresh_token": "RTfI2WNyK78NozupDH9ai8GPRbjjdVsXPPt..."
}
// Response
{
  "access_token": "BpGnOKMEUX9kRuHTK2jZfpoMjxOa3jhQtjjDIHqwvF540oqqvZ...",
  "token_type": "Bearer",
  "expires_in": 3600,
  "refresh_token": "SUgJ3XOzL89PazvrEI0bj9HQSckkwWtYQQu...",
  "scope": "accounts=ro balance=ro transactions=ro offline"
}
🚧

Replace the refresh token immediately

Each call invalidates the previous refresh_token and returns a new one. Persist the new token before using the new access_token - using the old refresh token will fail with 401.




3. Fetch financial data

Use the access_token as a Bearer token. See Fetching Account & Transaction Data for the full endpoint reference.