Skip to main content

Processing transactions

Synchronous enrichment

When submitting transactions synchronously, the API will block until the enrichment is complete and then return the list of enriched transactions in the same order as the input transactions.

Synchronous enrichment is straightforward, but it is only appropriate for smaller batches (up to 4000 transactions). For larger batches, asynchronous enrichment must be used.

You can see how to run a synchronous enrichment for two transactions in the following example:

$ curl \
-H "X-API-KEY: <YOUR-API-KEY>" \
-H "Content-Type: application/json" \
-X POST \
--data '[
{
"description": "SQ* STARBUCKS UNION SQUARE",
"entry_type": "outgoing",
"amount": 42.17,
"iso_currency_code": "USD",
"date": "2023-01-01",
"transaction_id": "tw3tFmn4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xke",
"country": "US",
"account_holder_id": "id-1",
"account_holder_type": "consumer"
},
{
"description": "AMAZON WEB SERVICES AWS.AMAZON.CO WA Ref5543286P25S Crd15",
"entry_type": "outgoing",
"amount": 12042.27,
"iso_currency_code": "USD",
"date": "2022-11-02",
"transaction_id": "4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn",
"country": "US",
"account_holder_id": "business-1",
"account_holder_type": "business"
}
]' \
https://api.ntropy.com/v2/transactions/sync

You will get back the enriched transactions as a JSON object with the API and as a list of EnrichedTransaction with the SDK:

  [
{
"transaction_id": "tw3tFmn4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xke",
"website": "starbucks.com",
"logo": "https://logos.ntropy.com/starbucks.com",
"merchant": "Starbucks",
"merchant_id": "d4bc3c80-ec1a-3da2-836e-2a4ca4758be5",
"location": "10 Union Square East, New York, New York 10003, US",
"location_structured": {
"address": "10 Union Square East",
"city": "New York",
"state": "New York",
"postcode": "10003",
"country": "US",
"latitude": 40.734834,
"longitude": -73.989782,
"google_maps_url": "https://www.google.com/maps/search/?api=1&query=Starbucks%2C10+Union+Square+East%2C+New+York%2C+New+York+10003%2C+US",
"apple_maps_url": "https://maps.apple.com/?q=Starbucks+10+Union+Square+East&sll=40.734834,-73.989782",
"store_number": null
},
"labels": [
"Cafes and coffee shops"
],
"label_group": "Non-Essential Expenses",
"person": null,
"intermediaries": [
{
"website": "squareup.com",
"name": "Square",
"logo": "https://logos.ntropy.com/squareup.com",
"id": "916bc837-55ef-3106-88f6-5a8269ca9f2a"
}
]
},
{
"transaction_id": "4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn",
"website": "amazon.com",
"logo": "https://logos.ntropy.com/amazon.com",
"merchant": "Amazon.Com",
"merchant_id": "c9485c47-6e77-30b4-88da-bbac9aa4ebf2",
"location": "Washington, US",
"location_structured": {
"address": null,
"city": null,
"state": "Washington",
"postcode": null,
"country": "US",
"latitude": null,
"longitude": null,
"google_maps_url": null,
"apple_maps_url": null,
"store_number": null
},
"labels": [
"infrastructure",
"cloud operations"
],
"label_group": null,
"person": null,
"intermediaries": [],
"recurrence": "recurring",
"recurrence_group": {
"average_amount": 12042.37,
"first_payment_date": "2022-08-01",
"latest_payment_date": "2022-11-01",
"periodicity_in_days": 31,
"id": "def66e68-37fd-3358-a9c7-2ba3f0f8edc4",
"other_party": "aws.amazon.com",
"periodicity": "monthly",
"total_amount": 48169.48,
"transaction_ids": [
"4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFzn",
"4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFcn",
"4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFan",
"4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn"
]
}
}
]

In the SDK you can retrieve a serializable representation of the transaction containing all attributes by using to_dict() method of the EnrichedTransacion:


from ntropy_sdk import SDK, Transaction

sdk = SDK("YOUR-API-KEY")
txs = [
Transaction(
description = "SQ* STARBUCKS UNION SQUARE",
entry_type = "outgoing",
amount = 42.17,
iso_currency_code = "USD",
date = "2023-01-01",
transaction_id = "tw3tFmn4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xke",
country = "US",
account_holder_id = "id-1",
account_holder_type = "consumer"
)
]

enriched = sdk.add_transactions(txs)[0]
print(enriched.to_dict())

# and convert it to JSON
import json
print(json.dumps(enriched.to_dict()))

Asynchronous enrichment

Transactions can also be enriched asynchronously with the async endpoint. Asynchronous enrichment follows the same input format as synchronous, but can handle larger batches between 1-24960 transactions in a single request.

Unlike the synchronous endpoint, the asynchronous endpoint will answer immediately, returning information for the submitted batch. This includes an id which can be used to query for the status of the batch.

The following example shows how to submit a batch asynchronously:

$ curl \
-H "X-API-KEY: <YOUR-API-KEY>" \
-H "Content-Type: application/json" \
-X POST \
--data '[
{
"description": "SQ* STARBUCKS UNION SQUARE",
"entry_type": "outgoing",
"amount": 42.17,
"iso_currency_code": "USD",
"date": "2023-01-01",
"transaction_id": "tw3tFmn4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xke",
"country": "US",
"account_holder_id": "id-1",
"account_holder_type": "consumer"
},
{
"description": "AMAZON WEB SERVICES AWS.AMAZON.CO WA Ref5543286P25S Crd15",
"entry_type": "outgoing",
"amount": 12042.27,
"iso_currency_code": "USD",
"date": "2022-11-02",
"transaction_id": "4yp49x3tbj9mD8DB4fM8DDY6Yxbx8YP14g565Xketw3tFmn",
"country": "US",
"account_holder_id": "business-1",
"account_holder_type": "business"
}
]' \
https://api.ntropy.com/v2/transactions/async

Handling async in the API

The async API endpoint returns a JSON response containing information of the batch, such as id, status, and progress.

{
"id": "39a316c6-eb48-4dc4-a094-025243221ddc",
"status": "started",
"progress": 0,
"updated_at": "2021-10-28T08:32:55.340976+00:00"
}

The id field can be used in the /v2/transactions/async/{id} endpoint to request the enriched set of transactions. For example, for the previous batch:

$ curl \
-H "X-API-KEY: <YOUR-API-KEY>" \
https://api.ntropy.com/v2/transactions/async/39a316c6-eb48-4dc4-a094-025243221ddc

If the processing is still in progress, you will get a response back similar to the previous request, with the progress field showing the number of transactions from the batch that have finished processing. When batch enrichment is complete, the status field will be set to finished and the object in the response will contain an additional results field that holds the list of enriched transactions, e.g.:

{
"id": "39a316c6-eb48-4dc4-a094-025243221ddc",
"progress": 2,
"results": [ ... ],
"status": "finished",
"updated_at": "2021-10-28T08:55:25.294044+00:00"
}

Handling async in the SDK

The SDK response for async enrichment is encapsulated in a Batch object that lets users poll the API automatically or block while continously polling for a response:

response, status = batch.poll()

print("id: %s, status: %s", % (batch.id, status))

# do any operations in the meantime
# ...

# block waiting for the result
result = batch.wait(poll_interval=1)

Additionally, a Batch object can be directly constructed from its id. The following code is equivalent to querying the /v2/transactions/async/{id} endpoint:

batch = Batch(sdk, "39a316c6-eb48-4dc4-a094-025243221ddc")
response, status = batch.poll()

Accessing input transactions

If you are using the SDK, all EnrichedTransaction objects obtained through add_transactions or get_account_holder_transactions contain a reference to the original input transaction, allowing access to all input parameters such as description and amount. You can use it as follows:

sdk = SDK("YOUR-API-KEY")
enriched = sdk.add_transactions(txs)

for e in enriched:
print(f"{e.parent_tx.description} -> {e.merchant}")

# it can also be used when fetching history
account_holder_history = sdk.get_account_holder_history("YOUR-ACCOUNT-HOLDER")
for e in account_holder_history:
print(f"{e.parent_tx.description} -> {e.merchant}")