IframeStep 2 of 2
Configure the backend
Receive normalized banking data on your server and correctly acknowledge the callback.
Complete the frontend checklist first. The widget does not send bank data via postMessage: it sends it here, as a POST.
Integration checklist
0 of 41. Create the callback URL
Expose an HTTPS endpoint on your server that accepts POST with a JSON body.
After you have persisted what you need, respond HTTP 200 with this JSON:
{
"status": "ok"
}
If you return a different status code or different JSON, the widget will not notify the frontend that the flow finished correctly.
Treat operation_id as idempotent: a repeated delivery must not create two operations in your system.
2. What arrives in the POST
The body is the same JSON as POST /entities/ in the OpenAPI reference. Fields you need to match the operation:
| Field | Use |
|---|---|
success |
true if the read finished successfully. |
payload |
Normalised data (accounts, portfolios, cards, …). |
statistics.operation_id |
The operation_id your frontend generated. |
statistics.token |
Custodied credential for later refreshes (if tokenisation is on). |
statistics.code |
Institution code (bbva, caixabank, …). |
statistics.SESSION |
Session id, useful in a support ticket. |
statistics.warnings |
Warnings that do not invalidate the read (for example an empty product). |
Shortened example:
{
"success": true,
"payload": {
"user_information": {
"ID": "12345678Z",
"name": "LUIS GARCIA BAQUERO"
},
"accounts": [
{
"uuid": "8076932f04f73e27fe608fee4d12fca8708dec8c",
"subtype": "checking",
"code": "ES4914651234561234567890",
"name": "Cuenta NOMINA",
"currency": "EUR",
"balances": {
"available": 14302.07,
"current": 14302.07
},
"transactions": []
}
]
},
"statistics": {
"SESSION": "A1B2C3D4E5F67890",
"execution_time": 12.4,
"warnings": [],
"operation_id": "8f1c2a6e-4b0d-4c3a-9e21-0d5b7a91c4e2",
"token": "FRJ0mHlaqZwLzu",
"code": "bbva"
}
}
The full payload schema is in the OpenAPI. Do not assume every key is always present: it depends on product_types and on what the user holds at the institution.
3. Associate domain, callback and API key
In the client area associate:
- the domain from which the widget is loaded (your frontend origin);
- the callback URL you just created;
- your
api_key.
Until the domain is registered, the widget does not work.
4. Test the flow
Open the page that loads the widget and sign in:
| Username | Password | Result |
|---|---|---|
MOCKDATA |
anything | Successful read with anonymised sample data. The callback receives JSON with success: true. |
MOCKOTP |
anything | Recreates a two-factor challenge. |
MOCKLOGINKO |
anything | Recreates a login error. The callback is not called. |
If you do not have the welcome email, ask for it at support@wealthreader.com.
If you want to inspect the POST before your endpoint exists, create a temporary URL on a service such as https://pipedream.com/ and set it as the callback.
5. Refresh data (optional)
At this point you have a one-shot integration: one read each time the user opens the widget.
If you need a nightly batch or an “update” button, call the API again with the token and code you stored from the callback. Do not ask for the username and password again.
curl --location 'https://api.wealthreader.com/entities/' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'api_key=YOUR_API_KEY' \
--data-urlencode 'code=bbva' \
--data-urlencode 'token=TOKEN_FROM_CALLBACK' \
--data-urlencode 'product_types=accounts,portfolios'
Pay close attention to the error codes: do not retry an invalid password; you may retry when the institution is under maintenance.
If the token stops working (password change or a new 2FA), open the widget again passing that value in wr_conf.token so the user can re-authenticate.