Implementation Guide
Upload transactions, poll processing status, and fetch enriched data using the returned access token.
Getting Started
Three steps to enrich your transaction data with nrich.
flowchart LR
A[Your Server] -->|POST /uploads\nBasic Auth| B[nrich API\nstatus: QUEUED]
B -->|Poll GET /uploads/id\nevery 2-5s| C{Status?}
C -->|Still processing| C
C -->|COMPLETED| D[Response includes\naccess_token]
D -->|GET /rest/transactions\nBearer token| E[Enriched data\nwith categories]
Upload your transactions
Poll until processing is complete
Fetch enriched data
Step 1: Upload transactions
POST https://api.finx-s.qwist.cloud/uploads
{
"accounts": [
{
"iban": "DE89370400440532013000",
"bic": "COBADEFFXXX",
"owner": "Maria Müller",
"balance": 3421.87,
"balance_date": "2025-06-01T00:00:00.000Z",
"currency": "EUR",
"transactions": [
{
"iban": "SE3550000000054910000003",
"bic": "ESSESESS",
"amount": -12.99,
"currency": "EUR",
"name": "SPOTIFY AB",
"purpose": "SVWZ+Spotify Abo 55912837 EREF+SPOTISP1234567",
"booking_text": "Lastschrift",
"creditor_id": "SE59ZZZ0000017491",
"mandate_reference": "SPOTIFY-DE-923847102",
"end_to_end_reference": "SPOTISP1234567",
"booked_at": "2025-05-28T00:00:00.000Z",
"settled_at": "2025-05-28T00:00:00.000Z"
},
{
"iban": "DE12500105170648489890",
"bic": "BELADEBEXXX",
"amount": 2850.00,
"currency": "EUR",
"name": "ACME GMBH",
"purpose": "Gehalt Mai 2025 Maria Mueller",
"booking_text": "Überweisungsgutschrift",
"booked_at": "2025-05-30T00:00:00.000Z",
"settled_at": "2025-05-30T00:00:00.000Z"
}
]
}
]
}Required fields:
| Field | Description |
|---|---|
account.iban | IBAN of the account. |
transaction.iban | IBAN of the counterparty. |
transaction.amount | Amount. Negative = debit (money out), positive = credit (money in). |
transaction.purpose | Purpose text. Pass an empty string "" if not available from your source. |
transaction.booked_at | Booking date in ISO 8601 format. |
All other fields are optional but improve enrichment quality. The more context you provide (booking text, creditor ID, SEPA references), the more accurately nrich can categorise and identify payment partners.
Response:
{
"id": "9556429e-378f-4c96-a7f0-44af2a9b7b38",
"status": "QUEUED",
"created_at": "2025-06-01T09:12:38.362Z",
"started_at": null,
"ended_at": null
}Store the id - you need it to poll status in step 2.
Step 2: Poll processing status
GET https://api.finx-s.qwist.cloud/uploads/{id}
Poll this endpoint until status is COMPLETED. We recommend polling every 2–5 seconds. Most uploads complete in under 30 seconds.
Authorization: Basic {Base64(clientId:clientSecret)}
Status values:
| Status | Meaning |
|---|---|
QUEUED | Waiting to be processed. |
PROCESSING | Enrichment in progress. |
COMPLETED | Done. Use the access_token to fetch results. |
FAILED | Processing failed. Check the response for details and retry with corrected data. |
Response when COMPLETED:
{
"id": "9556429e-378f-4c96-a7f0-44af2a9b7b38",
"status": "COMPLETED",
"created_at": "2025-06-01T09:12:38.362Z",
"started_at": "2025-06-01T09:12:38.462Z",
"ended_at": "2025-06-01T09:12:39.041Z",
"access_token": "AoFmNJLDTW8jQtGSJ1iZeeoLiwNZ2ihz3iiCHGpuvE439nppuY..."
}Once status is COMPLETED, use the access_token as a Bearer token for all subsequent requests.
Step 3: Fetch enriched data
GET https://api.finx-s.qwist.cloud/rest/transactions
Authorization: Bearer {access_token}
Response:
{
"transactions": [
{
"transaction_id": "T984794105855541249.1",
"account_id": "A984794105855541249.1",
"amount": -12.99,
"currency": "EUR",
"name": "SPOTIFY AB",
"purpose": "SVWZ+Spotify Abo 55912837 EREF+SPOTISP1234567",
"booking_text": "Lastschrift",
"booked": true,
"booked_at": "2025-05-28T00:00:00.000Z",
"settled_at": "2025-05-28T00:00:00.000Z",
"categories": [
{ "id": 22, "parent_id": null, "name": "Leisure" },
{ "id": 33, "parent_id": 22, "name": "Music streaming" }
],
"payment_partner": {
"id": "c9944518e86e46409e46a52b0f55dee0",
"name": "Spotify AB"
}
},
{
"transaction_id": "T984794105855541249.2",
"account_id": "A984794105855541249.1",
"amount": 2850.00,
"currency": "EUR",
"name": "ACME GMBH",
"purpose": "Gehalt Mai 2025 Maria Mueller",
"booked": true,
"booked_at": "2025-05-30T00:00:00.000Z",
"settled_at": "2025-05-30T00:00:00.000Z",
"categories": [
{ "id": 1, "parent_id": null, "name": "Income" },
{ "id": 2, "parent_id": 1, "name": "Salary" }
],
"payment_partner": {
"id": "a1b2c3d4e5f6",
"name": "Acme GmbH"
}
}
]
}Other available endpoints
With the same access_token, you can also call:
| Endpoint | Product |
|---|---|
GET /rest/income-reports/{id} | Income Verification Report |
POST /rest/risk-reports + GET /rest/risk-reports/{id} | Risk Insights Report |
Error handling
| Code | Meaning |
|---|---|
200 OK | Request succeeded. |
400 Bad Request | Malformed request or missing required fields. Check which field failed validation. |
401 Unauthorized | Invalid credentials. |
422 Unprocessable Entity | Valid JSON structure but invalid field values (e.g. malformed IBAN). Check each account and transaction. |
