RPI is an extension on top of the core Tapix payment enrichment API. Due to that, before you begin with this guide, you should familiarize yourself with the basic knowledge from Getting started with Tapix tutorial and the respective guides for enriching card payment data or bank transfers.
Please be aware that Recurring Payments Intelligence is not automatically accessible and requires activation by the Tapix team. If you wish to obtain recurring payments, please contact support@tapix.io.
Recurring Payment Intelligence (RPI) appends a subscription object to your existing enrichment response. It works on both card transactions and SEPA bank transfers — no new endpoint, no new integration.
Available for:
/shops/findByCardTransaction, and its batch (/shops/findByCardTransactionBatch) and complete (/shops/complete/findByCardTransaction, /shops/complete/findByCardTransactionBatch) versions/shops/findByBankTransfer/sepa, and its batch (/shops/findByBankTransferBatch/sepa) and complete (/shops/complete/findByBankTransfer/sepa, /shops/complete/findByBankTransferBatch/sepa) versionsCard transaction (findByCardTransaction):
Query:
/v6/shops/complete/findByCardTransaction?mcc=5818&city=CORK&posId=05197337&amount=1990&country=IE&clientId=CQYFCQADAQIHCQAFAAKHAW%3D%3D¤cy=HUF&customId=1&merchantId=311183094888&description=APPLE.COM%2FBILL&transactionTimestamp=2026-09-03T16%3A11%3A59.000%2B02%3A00
Response:
{
"result": "found",
"handle": "$cJMDgvgdFKLwuqyizL0fV2",
"shop": {
"uid": "ouNTZWfHfDtAi1kBObK5D2",
"type": "online",
"tags": [
"Software / Applications",
"Electronics Goods",
"Apple",
"Shopping Online",
"Subscription",
"Online Digital Services"
],
"merchant": {
"uid": "GbZzrLP0MpfQXAzYXerPn",
"name": "Apple",
"logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/m/GbZzrLP0MpfQXAzYXerPn/l#dc7283e86cd9f17f412182ef416265ca0fab1003"
},
"category": {
"name": "Digital Services",
"logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/category/GPGTWAG23kdhMh6W469Wf4/l"
},
"url": "https://www.apple.com"
},
"subscription": {
"automaticCharging": true,
"clientServiceUid": "e73e605407c5b4b644677a",
"frequency": "Monthly",
"nextBillingDate": "2026-10-03",
"nextAmountType": "Same"
},
"customId": "1"
}SEPA transfer (findByBankTransfer/sepa):
Query:
/v6/shops/complete/findByBankTransfer/sepa?iban=DE69700700100111111100&name=SOS-KINDERD%C3%96RFER%20WELTWEIT%20HERMANN-GMEINER-FONDS%20DEUTSCHLAND%20E.V.&amount=15&country=null&clientId=93b660343b55a997cee4c4d2f2a77782cb10ccf43c54aab0c46fb27be5922cf5¤cy=EUR&customId=1&paymentTimestamp=2026-09-09T10%3A01%3A56.000%2B02%3A00
Response:
{
"result": "found",
"handle": "bkQopQbzlVpHpK1BMdA553",
"shop": {
"uid": "bkQopQbzlVpHpK1BMdA553",
"type": "account",
"tags": [
"Donation And Crowdfunding"
],
"merchant": {
"uid": "QdzQV18Z9E1TbL44Po2zvl@de",
"name": "SOS Kinderdörfer",
"logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/m/QdzQV18Z9E1TbL44Po2zvl/l#a81fa91b7181dfc3c40dc1a835c4a60853c2d4b9",
"localizedNames": {
"latin": "SOS Kinderdörfer"
}
},
"category": {
"name": "Professional Services",
"logo": "https://s3.eu-central-1.amazonaws.com/files.node-prod.dateio.cz/category/yMov9i37wbnBVXfQ6dg6uk/l"
},
"location": {
"address": {
"country": "DE"
}
}
},
"subscription": {
"automaticCharging": true,
"clientServiceUid": "a2f5799f5a48592179f035",
"frequency": "Monthly",
"nextBillingDate": "2026-10-12",
"nextAmountType": "Same"
},
"customId": "1"
}RPI works the same way for all transfer endpoints listed in the documentation.
To learn what input data is required, and its ideal structure used to enrich the card / bank transfer payment data – refer to this link. Additionally, there are more necessary parameters for identifying recurring payments.
| Parameter | Applies to | Drives |
transactionTimestamp (card) / paymentTimestamp (SEPA) | Both — required | frequency, nextBillingDate |
amount | Both — required | frequency, nextAmountType |
currency | Both — required | frequency, nextAmountType |
sourceId | Card only | Detection, clientServiceUid (fallback identifier) |
clientId | SEPA — required (no sourceId exists for transfers). Card — recommended. | clientServiceUid (preferred identifier) — the only one that links the same person's card and transfer payments for one service into a single subscription. |
posEntryMode (good to have) — ISO 8583 Field 22 - Identifier of the method used to obtain the PAN. Example: 10posTransactionStatusIndicator (good to have) — ISO 8583 Field 60.6 - Identifier of the POS Transaction Status Indicator. Example: RecommerceIndicator (good to have) — ISO 8583 Field 126 - Identifier of the Electronic Commerce/MOTO (Mail Order/Telephone Order) Indicator. Example: 02nextPaymentDate — The date of the next scheduled execution of the standing order. Must follow the ISO 8601 format (YYYY-MM-DD). Example: 2025-04-15recurrenceType — Defines the nature of the payment instruction. Possible values: SINGLE (one-off), STANDING_ORDER (recurring), or DIRECT_DEBIT. Enum: "SINGLE" "STANDING_ORDER" "DIRECT_DEBIT"remittanceInfo — ISO 20022 – Remittance Information. Free-text payment reference provided by the originator to the beneficiary. Example: Invoice 2023/09 #4581Before turning on RPI in production it is heavily recommended to share historical data: 13 months minimum, 3 years ideal. Without it, we cannot identify the pattern and will only start creating the rules since you start calling the API. (This means that even though your client is paying for a service for a long time, these payments won't appear as a subscription until we see at least two payments.)
Authorisations vs. settled transactions: send settled/booked transactions for RPI. Sending both produces duplicate-looking payments and most severely degrades nextBillingDate. Either send only the settled transactions or implement a way how to distinguish between them. One option e.g. using rawParams where you write authorisation/settled_transaction. There are other ways, discuss it with the implementation manager at first.
sourceId must be stable in two ways. Across card reissue — the same value before and after a card is replaced (expiry, loss, theft). Across your integration — the same hashing method for the historical load and for production.
Both endpoints append the same object — FindResultSubscription in the API reference:
automaticCharging — boolean. Automatically charged or manually paid.clientServiceUid — string, ≤100 characters. Stable id for one client and one service (merchant + frequency). Same service at a different frequency gets a different id.frequency — enum: Weekly, Monthly, Quarterly, Yearly, Other, Unknown.nextAmountType — enum: Same, Approximate, Unknown.nextBillingDate — date, YYYY-MM-DD. Not returned on invalidations and refreshes.A SEPA transfer can come back "result": "unsolved" and still carry a full subscription object — detection does not depend on the shop being resolved:
Query:
/v6/shops/complete/findByBankTransfer/sepa?iban=DE63430609671294787500&name=B%C3%9CNDNIS%2090%20%2F%20DIE%20GR%C3%9CNEN%20KREISVERBAND%20HAMBURG-NORD&amount=55&country=null&clientId=189945b1886b376a80e4f97b84017add25389a26610b87a4539414c8545c31b5¤cy=EUR&customId=1&paymentTimestamp=2026-09-15T10%3A09%3A52.000%2B02%3A00
Response:
{
"result": "unsolved",
"handle": "yc13853119ab71c9bfbd54f",
"subscription": {
"automaticCharging": true,
"clientServiceUid": "c24b17792b3e585f768a70",
"frequency": "Monthly",
"nextBillingDate": "2026-10-16",
"nextAmountType": "Approximate"
},
"customId": "1"
}Do not filter out unsolved transactions before checking for subscription — you will lose real detections. These might include smaller merchants, e.g. insurances, local sports clubs or rent.
subscription, including frequency, from the first matching transaction.Example of subscription-only merchant detection
| merchant | transactionTimestamp | amount | currency | automaticCharging | nextAmountType | frequency | nextBillingDate | Payment rank |
| Netflix | 27.04.2026 | 4,99 | EUR | TRUE | Same | Monthly | 27.05.2026 | 1. |
| Netflix | 27.05.2026 | 4,99 | EUR | TRUE | Same | Monthly | 27.06.2026 | 2. |
| Netflix | 27.06.2026 | 4,99 | EUR | TRUE | Same | Monthly | 27.07.2026 | 3. |
| Netflix | 27.07.2026 | 4,99 | EUR | TRUE | Same | Monthly | 27.08.2026 | 4. |
nextBillingDate in those responses.Example of mixed merchant detection
| Merchant | transactionTimestamp | amount | currency | automaticCharging | nextAmountType | frequency | nextBillingDate | Payment rank |
| Apple | 14.07.2025 | 7,99 | EUR | 1. | ||||
| Apple | 21.07.2025 | 7,99 | EUR | 1. | ||||
| Apple | 14.08.2025 | 7,99 | EUR | TRUE | Same | Monthly | 14.09.2025 | 2. |
| Apple | 14.09.2025 | 7,99 | EUR | TRUE | Same | Monthly | 14.10.2025 | 3. |
| Apple | 06.10.2025 | 2,99 | EUR | 1. | ||||
| Apple | 14.10.2025 | 7,99 | EUR | TRUE | Same | Monthly | 14.11.2025 | 4. |
| Apple | 06.11.2025 | 2,99 | EUR | TRUE | Same | Monthly | 06.12.2025 | 2. |
A brand-new subscription at a mixed merchant will not appear immediately. Expected behaviour, not a detection failure.
nextBillingDate should be treated as a prediction, not a commitment. Merchants shift charge dates around weekends, bank holidays, and their own billing quirks. A real example stated by Netflix
Same — fixed recurring price. Streaming and media subscriptions, software licences, membership fees.Approximate — amount moves between cycles. Usage-based utility bills, metered mobile/data plans, consumption-based cloud services.Unknown — pattern is regular, amount can't be qualified. Display nothing for the forward amount.Helps us to better understand the subscriptions.
Does not persist corrections per individual end user. A submitted correction is reviewed and, if adopted, becomes a rule-level change — not a personal override for that one customer. Store and apply per-user corrections yourself if you need that behaviour. Reference: POST /feedback.