API: Custom aggregations
Summary
Assess groups customer transactions by their category, and "buckets" together relevant categories into core groupings for an affordability use-case, such as income, essentials and non-essentials (see more here).
Whilst Assess define these groupings based on the SFS standards, you can use this bucketing functionality to customise the grouping definitions to match you for your own custom groupings (and non-Assess-specific use-cases)!
Creating a bucket basically allows you to group together relevant categories and transactions and allow Bud to handle the statistical calculations across those groups using the GET /aggregations/v2/buckets
endpoint (here).
Let's walk through an example.
Background context
You are integrating the API and your business has a very specific definition of Income. After looking at Bud's categories, you find that the only relevant transactions you want to look at for income
are those with the L2 categories:
employment_income
benefits
pension_income
Furthermore, you have an idea of living_expenses
, which consists of the following Bud L2 categories:
groceries
mortgage
rent
public_transport
shared_bills_and_expenses
utilities_energy
utilities_water_and_sewage
Without bucketing, you'd either need to retrieve all of the customer's transactions and do the calculation yourself, or use the Category Totals endpoints (here) to get portions of the calculations (by each category) and then sum them up together again.
With buckets, you can specify the groups once, and then simply retrieve the results per customer.
Creating a new bucket
Using the POST /aggregations/v2/buckets
endpoint (here) to create a new bucket, you can specify the groups you want, and the L1/L2 categories they map onto. So for the example above, the following request would create said bucket:
curl --request POST \
--url https://api-sandbox.thisisbud.com/aggregations/v2/buckets \
--header 'Authorization: Bearer <access_token>' \
--header 'Content-Type: application/json' \
--header 'X-Client-ID: <client_id>' \
--data '{
"name": "your-bucket",
"categorisation_model": "uk-v2",
"buckets": [
{
"bucket_l1": "income",
"criteria": [
{
"bucket_l2": "employment_income",
"category_l1": "income",
"category_l2": "employment_income"
},
{
"bucket_l2": "benefits",
"category_l1": "income",
"category_l2": "benefits"
},
{
"bucket_l2": "pension_income",
"category_l1": "income",
"category_l2": "pension_income"
}
]
},
{
"bucket_l1": "living_expenses",
"criteria": [
{
"bucket_l2": "groceries",
"category_l1": "food_and_drink",
"category_l2": "groceries"
},
{
"bucket_l2": "mortgage",
"category_l1": "mortgage_and_rent",
"category_l2": "mortgage"
},
{
"bucket_l2": "rent",
"category_l1": "mortgage_and_rent",
"category_l2": "rent"
},
{
"bucket_l2": "public_transport",
"category_l1": "transport",
"category_l2": "public_transport"
},
{
"bucket_l2": "electricity_and_gas",
"category_l1": "utilities",
"category_l2": "utilities_energy"
},
{
"bucket_l2": "water",
"category_l1": "utilities",
"category_l2": "utilities_water_and_sewage"
},
{
"bucket_l2": "shared_bills_and_expenses",
"category_l1": "transfers",
"category_l2": "shared_bills_and_expenses"
}
]
}
]
}
'
{
"operation_id": "aggregations_v2_buckets_post",
"data": {
"bucket_id": "<bucket_id>"
}
}
Retrieving Bucket details
After a bucket has been created, you can list the existing buckets using the GET /aggregations/v2/buckets
endpoint (here) endpoint to retrieve your buckets:
curl --request GET \
--url https://api-sandbox.thisisbud.com/aggregations/v2/buckets \
--header 'Authorization: Bearer <access_token>' \
--header 'X-Client-ID: <client_id>'
{
"operation_id": "aggregations_v2_buckets_get",
"data": [
{
"bucket_id": "<bucket_id>",
"name": "your-bucket",
"categorisation_model": "uk-v2",
"created_at": "2023-08-14T15:08:04Z",
"updated_at": "2023-08-14T15:08:04Z",
"buckets": [
"income",
"living_expenses"
]
}
]
}
This just gives a top-level overview of the buckets you have. Using the GET /aggregations/v2/buckets/{bucket_id}
endpoint (here) and the bucket_id
from the previous response, you can see data about a particular bucket:
curl --request GET \
--url 'https://api-sandbox.thisisbud.com/aggregations/v2/buckets/<bucket_id>?unbucketed_categories&bucket_lookup&category_lookup' \
--header 'Authorization: Bearer <access_token>' \
--header 'X-Client-ID: <cient_id>'
{
"operation_id": "aggregations_v2_bucket_get",
"data": {
"bucket_id": "0f4a4911-dff5-4d53-86d0-f12d5a823d08",
"name": "your-bucket",
"categorisation_model": "uk-v2",
"created_at": "2023-08-14T15:08:04Z",
"updated_at": "2023-08-14T15:08:04Z",
"buckets": [
{
"bucket_l1": "income",
"criteria": [
{
"bucket_l2": "employment_income",
"category_l1": "income",
"category_l2": "employment_income"
},
{
"bucket_l2": "benefits",
"category_l1": "income",
"category_l2": "benefits"
},
{
"bucket_l2": "pension_income",
"category_l1": "income",
"category_l2": "pension_income"
}
]
},
{
"bucket_l1": "living_expenses",
"criteria": [
{
"bucket_l2": "groceries",
"category_l1": "food_and_drink",
"category_l2": "groceries"
},
{
"bucket_l2": "mortgage",
"category_l1": "mortgage_and_rent",
"category_l2": "mortgage"
},
{
"bucket_l2": "rent",
"category_l1": "mortgage_and_rent",
"category_l2": "rent"
},
{
"bucket_l2": "public_transport",
"category_l1": "transport",
"category_l2": "public_transport"
},
{
"bucket_l2": "electricity_and_gas",
"category_l1": "utilities",
"category_l2": "utilities_energy"
},
{
"bucket_l2": "water",
"category_l1": "utilities",
"category_l2": "utilities_water_and_sewage"
},
{
"bucket_l2": "shared_bills_and_expenses",
"category_l1": "transfers",
"category_l2": "shared_bills_and_expenses"
}
]
}
]
},
"metadata": {
"category_lookup": {
"income": {
"benefits": {
"category_l1": "income",
"category_l2": "benefits"
},
"employment_income": {
"category_l1": "income",
"category_l2": "employment_income"
},
"pension_income": {
"category_l1": "income",
"category_l2": "pension_income"
}
},
"living_expenses": {
"electricity_and_gas": {
"category_l1": "utilities",
"category_l2": "utilities_energy"
},
"groceries": {
"category_l1": "food_and_drink",
"category_l2": "groceries"
},
"mortgage": {
"category_l1": "mortgage_and_rent",
"category_l2": "mortgage"
},
"public_transport": {
"category_l1": "transport",
"category_l2": "public_transport"
},
"rent": {
"category_l1": "mortgage_and_rent",
"category_l2": "rent"
},
"shared_bills_and_expenses": {
"category_l1": "transfers",
"category_l2": "shared_bills_and_expenses"
},
"water": {
"category_l1": "utilities",
"category_l2": "utilities_water_and_sewage"
}
}
},
"bucket_lookup": {
"food_and_drink": {
"groceries": {
"bucket_l1": "living_expenses",
"bucket_l2": "groceries"
}
},
"income": {
"benefits": {
"bucket_l1": "income",
"bucket_l2": "benefits"
},
"employment_income": {
"bucket_l1": "income",
"bucket_l2": "employment_income"
},
"pension_income": {
"bucket_l1": "income",
"bucket_l2": "pension_income"
}
},
"mortgage_and_rent": {
"mortgage": {
"bucket_l1": "living_expenses",
"bucket_l2": "mortgage"
},
"rent": {
"bucket_l1": "living_expenses",
"bucket_l2": "rent"
}
},
"transfers": {
"shared_bills_and_expenses": {
"bucket_l1": "living_expenses",
"bucket_l2": "shared_bills_and_expenses"
}
},
"transport": {
"public_transport": {
"bucket_l1": "living_expenses",
"bucket_l2": "public_transport"
}
},
"utilities": {
"utilities_energy": {
"bucket_l1": "living_expenses",
"bucket_l2": "electricity_and_gas"
},
"utilities_water_and_sewage": {
"bucket_l1": "living_expenses",
"bucket_l2": "water"
}
}
},
"unbucketed_categories": [
{
"category_l1": "insurance",
"category_l2": "pet_insurance"
},
{
"category_l1": "insurance",
"category_l2": "travel_insurance"
},
{
"category_l1": "insurance",
"category_l2": "vehicle_insurance"
},
{
"category_l1": "insurance",
"category_l2": "business_insurance"
},
// ...
]
}
}
Useful query parameters for bucket retrieval
Importantly, you will want to consider the following query parameters, as they will give you useful information for further integrations:
bucket_lookup
- this allows you to check which bucket a particular category L1/L2 pair falls into. This is useful when you are presenting a list of transactions and want to show their bucket L1/L2 rather than their category L1/L2 labels.category_lookup
- this gives you a lookup for which category L1/L2 a bucket maps to. This is useful for when you want to correct a transaction , and you've presented the user with your bucket options - this allows you to map back to the Bud category pairing that should be appliedunbucketed_categories
- this gives you a list of the categories on the model which have not been made part of your bucket. Use this to see if you are missing out any crucial categories from your analysis.
Retrieving Bucket Totals
Once your bucket is created, you can use it to aggregate a customer's data. If you have the Customer's ID (and their Secret if they aren't a hosted customer), you can then retrieve their totals using the GET /aggregations/v2/buckets/<bucket_id>/totals
endpoint (here) to retrieve the bucket totals:
curl --request GET \
--url 'https://api-sandbox.thisisbud.com/aggregations/v2/buckets/<bucket_id>/totals?group_by=bucket_l1&month_from=2023-02&month_to=2023-07' \
--header 'Authorization: Bearer <access_token>' \
--header 'X-Client-ID: <client_id>' \
--header 'X-Customer-ID: <customer_id>'
{
"operation_id": "aggregations_v2_bucket_totals_get",
"data": [
{
"group_name": "income",
"group_type": "bucket_l1",
"incoming": {
"total": {
"value": "42000.00",
"currency": "GBP"
},
"monthly_average": {
"value": "7000.00",
"currency": "GBP"
},
"transaction_count": 8,
"_links": {
"transactions": "<link_to_transactions>"
}
},
"outgoing": {
"total": {
"value": "0.00",
"currency": "GBP"
},
"monthly_average": {
"value": "0.00",
"currency": "GBP"
},
"transaction_count": 0,
"_links": {
"transactions": "<link_to_transactions>"
}
},
"transaction_count": 8,
"_links": {
"transactions": "<link_to_transactions>"
}
},
{
"group_name": "living_expenses",
"group_type": "bucket_l1",
"incoming": {
"total": {
"value": "0.00",
"currency": "GBP"
},
"monthly_average": {
"value": "0.00",
"currency": "GBP"
},
"transaction_count": 0,
"_links": {
"transactions": "<link_to_transactions>"
}
},
"outgoing": {
"total": {
"value": "7638.49",
"currency": "GBP"
},
"monthly_average": {
"value": "1273.08",
"currency": "GBP"
},
"transaction_count": 173,
"_links": {
"transactions": "<link_to_transactions>"
}
},
"transaction_count": 173,
"_links": {
"transactions": "<link_to_transactions>"
}
}
],
"metadata": {
"date_from": "2023-02-01T00:00:00Z",
"date_to": "2023-07-31T23:59:59Z",
"group_by": [
"bucket_l1"
],
"currency": "GBP"
}
}
Retrieving Customer Transactions
Each subtotal within the bucket totals response provides a link to the customer's transactions which contributed to the total. This allows you to display the transactions for a customer (e.g. to confirm a calculation, or to move a transaction to a different category), whilst saving you from needing to build up the specific transactions query yourself.
{
"_links": {
"transactions": "/<response_transactions_link_url>"
}
}
All you need to do is:
- Prepend the prefix of the Bud API host (e.g. api-sandbox.thisisbud.com)
- Build a request using this URL and the headers for retrieving transactions
You will then be able to get the transactions, in the V2 format, and present them for your users (below is an example for the response received when retrieving the list of transactions in the income bucket).
curl --request GET \
--url 'https://api-sandbox.thisisbud.com/<response_transactions_link_url>' \
--header 'Authorization: Bearer <access_token>' \
--header 'X-Client-ID: <client_id>' \
--header 'X-Customer-ID: <customer_id>'
{
"operation_id": "financial_v2_transactions_get",
"data": [
{
"transaction_id": "953d2696-4543-5835-b519-3915f0867fde",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-07-07T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-08-07T10:00:00Z",
"2023-09-07T10:00:00Z",
"2023-10-09T09:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
},
{
"transaction_id": "442728a8-3b37-59c6-8742-2b801d6dbb28",
"account_id": "d607d0da-fb58-497f-ac51-d70f309be304",
"provider": "Natwest_Sandbox",
"description": "Bonus Pay Check",
"credit_debit_indicator": "credit",
"amount": {
"value": "1500.00",
"currency": "GBP"
},
"date_time": "2023-06-24T06:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.95"
},
"l2": {
"slug": "employment_income",
"confidence": "0.93"
}
}
},
"tags": [
"income"
]
},
{
"transaction_id": "3498642c-8652-52ee-ba71-9c37cea183e2",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-06-06T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-07-06T10:00:00Z",
"2023-08-07T09:00:00Z",
"2023-09-06T10:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
},
{
"transaction_id": "78c1c6cd-effe-5535-806c-eb2eb7c71a48",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-05-06T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-06-06T10:00:00Z",
"2023-07-06T10:00:00Z",
"2023-08-07T09:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
},
{
"transaction_id": "60ad7c9f-f997-545f-9174-3931abdb548b",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-04-05T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-05-05T10:00:00Z",
"2023-06-05T10:00:00Z",
"2023-07-05T10:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
},
{
"transaction_id": "a975e6d4-fcc7-5916-8324-4058e0722abb",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-03-06T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-04-06T10:00:00Z",
"2023-05-09T09:00:00Z",
"2023-06-06T10:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
},
{
"transaction_id": "9e644963-8aa1-59d4-9d79-a4be3b0082e5",
"account_id": "d607d0da-fb58-497f-ac51-d70f309be304",
"provider": "Natwest_Sandbox",
"description": "Bonus Pay Check",
"credit_debit_indicator": "credit",
"amount": {
"value": "1500.00",
"currency": "GBP"
},
"date_time": "2023-02-21T06:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.95"
},
"l2": {
"slug": "employment_income",
"confidence": "0.93"
}
}
},
"tags": [
"income"
]
},
{
"transaction_id": "5bbd38e4-0c03-533e-9456-8168808b39aa",
"account_id": "6aa9a396-75ca-48da-9dba-5f4094cb3a83",
"provider": "Natwest_Sandbox",
"description": "EMPLOYEE SALARY",
"credit_debit_indicator": "credit",
"amount": {
"value": "6500.00",
"currency": "GBP"
},
"date_time": "2023-02-03T10:00:00Z",
"status": "booked",
"enrichments": {
"categories": {
"l1": {
"slug": "income",
"confidence": "0.98"
},
"l2": {
"slug": "employment_income",
"confidence": "0.98"
}
},
"regularity": {
"frequency": "monthly",
"predicted_date_times": [
"2023-03-03T10:00:00Z",
"2023-04-03T10:00:00Z",
"2023-05-03T10:00:00Z"
],
"group_label": "f1bf6824c555c36446dc6d5f78de181a14d5bed46edd283fc30c8b58468c3408-0"
}
},
"tags": [
"income",
"regular-transaction",
"salary"
]
}
],
"metadata": {
"results": 8
}
}
Showing bucket L1/L2 instead of category L1/L2
As noted above regarding bucket retrieval: if you want to show the bucket L1/L2 alongside the transaction (instead of the category L1/L2) in your UI, you'll want to use the
bucket_lookup
response for the bucket to discover what the values are, and show those in your UI instead.
If you have any questions, please contact us via the chatbot (bottom-right of screen 👉) or via a support request or check our FAQs.
Updated 10 months ago