Skip to content

Categories

A category labels what a transaction was for. Categories are typed as income or expense. All routes require a bearer token and live under /api/v1.

MethodPathAction
GET/api/v1/categoriesList categories
POST/api/v1/categoriesCreate a category
GET/api/v1/categories/{id}Show one category
PUT/api/v1/categories/{id}Update a category
DELETE/api/v1/categories/{id}Delete a category
POST/api/v1/categories/seed-defaultsSeed a default set of categories

Listing supports a type query parameter (income or expense) to filter the result.

FieldTypeRequiredNotes
namestringyesUp to 255 characters.
typestringyesincome or expense.
descriptionstringnoFree text.
iconstringnoIcon value.
icon_typestringnoRequired with icon: icon, image, or emoji.
client_idstringnoClient-generated ID, {device_uuid}:{entity_uuid}.
created_atstringnoISO 8601.
Terminal window
curl -X POST https://api.your-domain.example/api/v1/categories \
-H "Authorization: Bearer your-token-here" \
-H "Content-Type: application/json" \
-d '{
"name": "Groceries",
"type": "expense"
}'

To start from a common set instead of an empty list:

Terminal window
curl -X POST https://api.your-domain.example/api/v1/categories/seed-defaults \
-H "Authorization: Bearer your-token-here"
{
"success": true,
"message": "Category created",
"data": {
"id": 4,
"name": "Groceries",
"type": "expense",
"description": null,
"icon": {
"id": 8,
"path": "cart.png",
"type": "image"
},
"client_generated_id": "device-uuid:entity-uuid",
"last_synced_at": "2026-06-14T09:12:00.000000Z"
}
}