Categories organize transactions into a two-level hierarchy: a primary category (e.g., FOOD_AND_DRINK) and a detailed subcategory (e.g., FOOD_AND_DRINK_GROCERIES). Breadbox ships with the Plaid taxonomy pre-loaded, and you can customize it by creating, editing, or merging categories. Transaction rules and manual overrides reference categories by their slug.
Two-level hierarchy
Every category has a primary parent and an optional detailed child. For example:
FOOD_AND_DRINK
├── FOOD_AND_DRINK_GROCERIES
├── FOOD_AND_DRINK_RESTAURANTS
└── FOOD_AND_DRINK_COFFEE
TRANSPORTATION
├── TRANSPORTATION_GAS
└── TRANSPORTATION_PUBLIC_TRANSIT
Primary categories group broad spending areas. Detailed categories give finer-grained labels for rules, filters, and reporting. When you filter transactions by category_slug, you can use either level.
List categories
Returns all categories in the two-level hierarchy.
Auth: Read
Response
{
"data": [
{
"id": "c1a2b3c4-d5e6-f789-0abc-def123456789",
"short_id": "Ab1cDe2f",
"slug": "food-and-drink",
"name": "Food & Drink",
"primary_slug": null,
"description": "Restaurants, groceries, coffee, and bars.",
"created_at": "2025-11-01T09:00:00Z",
"updated_at": "2025-11-01T09:00:00Z"
},
{
"id": "c2b3c4d5-e6f7-890a-bcde-f12345678901",
"short_id": "Bc2dEf3g",
"slug": "food-and-drink-groceries",
"name": "Groceries",
"primary_slug": "food-and-drink",
"description": "Supermarkets and grocery stores.",
"created_at": "2025-11-01T09:00:00Z",
"updated_at": "2025-11-01T09:00:00Z"
}
]
}
curl -H "X-API-Key: bb_your_key" \
"http://localhost:8080/api/v1/categories"
Export categories as TSV
GET /api/v1/categories/export
Returns all categories as a tab-separated values (TSV) file. Useful for bulk editing in a spreadsheet and re-importing with POST /api/v1/categories/import.
Auth: Read
The response has Content-Type: text/tab-separated-values and includes a header row:
slug name primary_slug description
food-and-drink Food & Drink Restaurants, groceries, coffee, and bars.
food-and-drink-groceries Groceries food-and-drink Supermarkets and grocery stores.
curl -H "X-API-Key: bb_your_key" \
"http://localhost:8080/api/v1/categories/export" \
-o categories.tsv
Get a single category
GET /api/v1/categories/{id}
Returns a single category by its UUID or slug.
Auth: Read
Path parameters
The category’s Breadbox UUID, short ID, or slug.
curl -H "X-API-Key: bb_your_key" \
"http://localhost:8080/api/v1/categories/food-and-drink-groceries"
Create a category
Creates a new category. To create a detailed subcategory, set primary_slug to the slug of an existing primary category.
Auth: Write
Request body
{
"slug": "food-and-drink-meal-prep",
"name": "Meal Prep & Delivery",
"primary_slug": "food-and-drink",
"description": "Meal kit subscriptions and prepared food delivery services."
}
URL-safe identifier for the category. Lowercase letters, numbers, and hyphens only. Must be globally unique. Immutable after creation.
Human-readable display name (e.g., "Meal Prep & Delivery").
Slug of the parent primary category. Set this to create a detailed subcategory. Omit to create a top-level primary category.
Optional description shown in the admin dashboard.
Response
Returns the created category object with 201 Created.
curl -X POST \
-H "X-API-Key: bb_your_key" \
-H "Content-Type: application/json" \
-d '{
"slug": "food-and-drink-meal-prep",
"name": "Meal Prep & Delivery",
"primary_slug": "food-and-drink"
}' \
"http://localhost:8080/api/v1/categories"
Update a category
PUT /api/v1/categories/{id}
Updates an existing category. You can change the name, description, and primary_slug. The slug cannot be changed after creation.
Auth: Write
Path parameters
The category’s UUID, short ID, or slug.
Request body
{
"name": "Meal Kits & Delivery",
"description": "Updated description."
}
curl -X PUT \
-H "X-API-Key: bb_your_key" \
-H "Content-Type: application/json" \
-d '{"name": "Meal Kits & Delivery"}' \
"http://localhost:8080/api/v1/categories/food-and-drink-meal-prep"
Delete a category
DELETE /api/v1/categories/{id}
Deletes a category. Transactions currently assigned to this category will have their category cleared unless you merge the category into another before deleting. You cannot delete a primary category that still has active detailed subcategories.
Auth: Write
Path parameters
The category’s UUID, short ID, or slug.
curl -X DELETE \
-H "X-API-Key: bb_your_key" \
"http://localhost:8080/api/v1/categories/food-and-drink-meal-prep"
Import categories from TSV
POST /api/v1/categories/import
Imports categories from a TSV file. Existing categories with matching slugs are updated; new slugs are created. The TSV must include a header row with columns slug, name, primary_slug, and description.
Auth: Write
Request body
Send the TSV content as Content-Type: text/tab-separated-values:
curl -X POST \
-H "X-API-Key: bb_your_key" \
-H "Content-Type: text/tab-separated-values" \
--data-binary @categories.tsv \
"http://localhost:8080/api/v1/categories/import"
Response
{
"created_count": 3,
"updated_count": 12
}
Merge a category
POST /api/v1/categories/{id}/merge
Merges a category into another. All transactions assigned to the source category are reassigned to the target category, and the source category is deleted. This is the recommended way to consolidate duplicate or unwanted categories without losing transaction history.
Auth: Write
Path parameters
The source category to merge and delete.
Request body
{
"into_slug": "food-and-drink-restaurants"
}
The slug of the target category that will receive all transactions from the source.
Response
{
"reassigned_count": 47,
"deleted_slug": "food-and-drink-meal-prep"
}
curl -X POST \
-H "X-API-Key: bb_your_key" \
-H "Content-Type: application/json" \
-d '{"into_slug": "food-and-drink-restaurants"}' \
"http://localhost:8080/api/v1/categories/food-and-drink-meal-prep/merge"
Category response fields
8-character base62 alias.
URL-safe unique identifier (e.g., "food-and-drink-groceries"). Immutable after creation.
Human-readable display name.
Slug of the parent primary category. null for top-level primary categories.
Optional description for the admin dashboard.
Error codes
| Condition | Status | Code |
|---|
| Missing or invalid API key | 401 | MISSING_API_KEY / INVALID_API_KEY |
| Category not found | 404 | NOT_FOUND |
| Slug already exists | 409 | VALIDATION_ERROR |
| Invalid request body | 422 | VALIDATION_ERROR |