Implementation Guide
Create an account verification flow, exchange the authorization code, and fetch the verification report.
Getting Started
Three API calls to verify your user's identity.
Create a Widget link for account verification
Exchange the authorization code for an access token
Fetch the verification report
1. Create the Widget link
POST https://api.finx-s.qwist.cloud/onetime/account-verification
{
"redirect_uri": "https://my-app.example.com/callback",
"name": "Maria Müller",
"account": "DE89370400440532013000",
"language": "de",
"readout": []
}Parameters:
| Parameter | Required | Description |
|---|---|---|
redirect_uri | ✅ | Where the user is returned after the flow. |
name | ✅ | The account holder name to verify against. Use the full name your user provided at registration. |
account | IBAN of the account to verify. If provided, the user's bank is preselected and they go directly to SCA - skipping bank selection. | |
language | Widget UI language. Options: de, en, es, fr, ar. Default: de. | |
readout | Additional data to return alongside verification. Options: "ACCOUNTS", "TRANSACTIONS". Empty array [] = verification only. |
Pass the IBAN when you have itProviding
accountskips the bank selection screen - the user authenticates directly. This significantly improves completion rates in flows where the user has already provided their IBAN (e.g. during onboarding or a loan application form).
Response:
{
"location": "https://widget.qwist.cloud/?token=eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"id": "a9c2e4f8-1b3d-4e7a-9f2c-8d1e3b5a7c9e"
}Store the id - it is your verification ID for fetching the report in step 3.
2. Exchange the authorization code
After the user completes the Widget flow, they are redirected to your redirect_uri with:
| Parameter | Description |
|---|---|
code | Authorization code valid for 1 hour. Present only on success. |
flow_id | Unique identifier for this flow. Matches the id from step 1. |
success | true if the user completed the flow. |
abort | true if the user cancelled. |
state | Your 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 trueThe user cancelled - no
codeis returned. Show a dismissal state and let the user retry. Do not attempt to exchange a missing code.
Exchange the code for a token
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"
}Use the access_token as a Bearer token in the Authorization header for all subsequent requests.
| Token | Lifetime | Notes |
|---|---|---|
| Authorization code | 1 hour | Single use |
| Access token | 1 hour | Authorization: Bearer {token} |
| Refresh token | 90 days | Returned but not needed for one-time flows - see below |
You do not need to implement token refresh for this flowData from a one-time connection is available for 1 hour. After that it is deleted automatically. The
refresh_tokenis returned by the API but serves no purpose here - do not store or use it.
Token storageToken lengths vary. Allocate at least 2048 bytes per token field in your database - do not use fixed-size columns.
3. Fetch the verification report
See Getting your Verification Report for the endpoint and response reference.
