Recurring transaction guide

Understand how we identify recurring tansactions

Recurrence detection is not enabled by default. To request access, please contact us at [email protected]. Please note, enabling this feature may add ~10ms of latency to your enrichment requests.

Overview

Our recurrence flag leverages transaction history and merchant information to identify recurring spend. We define recurring transactions as spend that happens on a consistent basis to a specific merchant (often via a subscription). Examples of recurring transactions that we flag include subscription payments to Netflix and a Con Edison electricity bill - shopping at the same grocery store on a regular basis is not considered a recurring transaction.

We use a combination of merchant data and user transaction history to determine if a specific transaction is recurring.

Understanding Recurrence Data

Our recurring transaction flag includes the following fields:

  • intervalDays: The number of days between recurring transactions
  • intervalType: The type of recurrence pattern (weekly, biweekly, monthly, quarterly, etc.)
  • nextPaymentExpected: The predicted date of the next payment in this pattern
  • recentRecurrences: An array of up to 5 recent transactions in this pattern, including:
    • amount: The transaction amount
    • occurredAt: Timestamp of when the transaction occurred
    • enrichmentId: Spade's unique identifier for the enrichment
    • transactionId: Your original transaction identifier

Getting started

To get started:

  • Ensure this feature is enabled by contacting [email protected]
  • Verify that your integration includes the following:
    • Unique and consistent ‘userId’ parameters
    • Correct ‘occurredAt’ dates
    • Accurate transaction ‘amount’

In order to get the best results, we recommend sending at least 3 months of backfilled transactions with the correct occurredAt dates (not the date the transaction was backfilled). For historical recurring transactions, we need 3 or more transactions with matching characteristics to establish a recurring pattern. Please contact your account representative to discuss backfill approach.

Testing for Recurring Transactions

Our API allows you to detect recurring transactions through our enrichment endpoints. Here's how to get started:

1. Send Transaction Data

First, send your first transaction to our enrichment endpoint:

import requests

raw_transaction = {
   "amount": "22.99",
   "cardId": null,
   "userId": "user_1234",
   "location": {
      "city": "LOS GATOS",
      "region": "CA",
      "country": "USA"
   },
   "occurredAt": "2024-06-01",
   "categoryCode": "4899",
   "categoryType": "MCC",
   "currencyCode": "USD",
   "merchantName": "NETFLIX.COM",
   "transactionId": "transaction_1"
}

response = requests.post("https://east.sandbox.spade.com/transactions/cards/enrich", json=raw_transaction, headers={"X-Api-Key": "<Your API Key Here>"})
enriched_transaction = response.json()

print(enriched_transaction)

2. Check Recurrence Information

As the previous request is one that we had predicted to be a recurring transaction (subscription), the enrichment response will include a recurrenceInfo object for transactions that are part of a recurring pattern:

{
	"transactionInfo": {
		"type": "spending",
		"thirdParties": [],
		"spendingInfo": {
			"channel": {
				"value": "digital"
			}
		},
		"transactionId": "5678",
		"recurrenceInfo": {
			"intervalType": "monthly",
			"intervalDays": 30,
			"nextPaymentExpected": "2024-07-01",
			"recentRecurrences": null
		}
	},
  ...
}

Any transaction that is not part of a predicted or historical recurring pattern will have null for the recurrenceInfo object.

3. Send Additional Transaction Data

As you send additional transactions, you will see the recurrenceInfo object update with the new data:

import requests

raw_transaction = {
   "amount": "22.99",
   "cardId": null,
   "userId": "user_1234",
   "location": {
      "city": "LOS GATOS",
      "region": "CA",
      "country": "USA"
   },
   "occurredAt": "2024-07-01",
   "categoryCode": "4899",
   "categoryType": "MCC",
   "currencyCode": "USD",
   "merchantName": "NETFLIX.COM",
   "transactionId": "transaction_2"
}

response = requests.post("https://east.sandbox.spade.com/transactions/cards/enrich", json=raw_transaction, headers={"X-Api-Key": "<Your API Key Here>"})
enriched_transaction = response.json()

print(enriched_transaction)

4. Check Recurrence Information

The enrichment response will now include a recentRecurrences object under the recurrenceInfo object:

{
	"transactionInfo": {
		"type": "spending",
		"thirdParties": [],
		"spendingInfo": {
			"channel": {
				"value": "digital"
			}
		},
		"transactionId": "transaction_2",
		"recurrenceInfo": {
			"intervalType": "monthly",
			"intervalDays": 30,
			"nextPaymentExpected": "2024-07-31",
			"recentRecurrences": [
				{
					"amount": 22.99,
					"enrichmentId": "227dd480-2bd5-4805-b88d-185c306ee9bb",
					"occurredAt": "2024-06-01 00:00:00+00:00",
					"transactionId": "transaction_1"
				}
			]
		}
	},
  ...
}

As you add additional recurring transactions, the recentRecurrences array will be updated with the new transactions, up to a maximum of 5.

In addition to predicting recurring transactions, we also use historical transactions to find recurring patterns. For example, if you send transactions for a user on 2024-07-01, 2024-08-01, 2024-09-01, and 2024-10-01, all with similar amounts, we will use the historical data to determine if the transaction is recurring. If so, it will mark the last transaction as recurring, and the intervalType will be set to monthly.

Troubleshooting

Common reasons why transactions might not be recognized as recurring:

  • Transaction amounts that vary significantly between occurrences
  • Irregular timing (varying more than a few days from the expected pattern)
  • Missing or incorrect userId values
  • Insufficient transaction history

If you're not seeing expected recurring patterns, ensure that:

  1. The amount of the transactions are correct
  2. The userId is consistent across transactions
  3. The occurredAt dates reflect the actual transaction dates
  4. You've sent enough transaction history (at least 3 occurrences)