Skip to main content

Overview

Transactions represent financial activities in Budget Bee. They support categories, tags, line items, and can be filtered by various criteria.

Base URL

{NEXT_PUBLIC_PG_REST_URL}/transactions

Authorization

All transaction endpoints require authentication via JWT token:
Authorization: Bearer {JWT_TOKEN}

List Transactions

Retrieve a list of transactions. Results are automatically filtered based on user/organization context.
GET /transactions

Query Parameters

select
string
Columns to return. Default: * (all columns)
order
string
Sort order. Example: transaction_date.desc or amount.asc
limit
integer
Maximum number of results to return
offset
integer
Number of results to skip (for pagination)
category_id
string
Filter by category ID. Use eq.{uuid} format
status
string
Filter by status. Values: paid, pending, failed
transaction_date
string
Filter by date. Use operators like gte.2024-01-01 or lte.2024-12-31
amount
string
Filter by amount. Use operators like gt.100 or lt.1000

Request Example

curl -X GET "{NEXT_PUBLIC_PG_REST_URL}/transactions?order=transaction_date.desc&limit=50" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json"

Response

id
uuid
Unique transaction identifier
amount
numeric
Transaction amount (decimal with 2 places)
currency
string
Currency code (default: “usd”)
user_id
string
Owner user ID
organization_id
string
Organization ID (null for personal transactions)
external_id
string
External reference ID (for imports)
category_id
uuid
Category reference
reference_no
string
Reference or invoice number
name
string
Transaction name/title
description
string
Detailed description
status
string
Transaction status: paid, pending, failed
source
string
Source of transaction (default: “manual”)
metadata
jsonb
Additional metadata as JSON
transaction_date
timestamp
When the transaction occurred
created_at
timestamp
When the record was created
updated_at
timestamp
Last update timestamp

Response Example

[
  {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "amount": 125.50,
    "currency": "usd",
    "user_id": "usr_abc123",
    "organization_id": "org_456",
    "external_id": null,
    "category_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "reference_no": "INV-2024-001",
    "name": "Office Supplies",
    "description": "Pens, notebooks, and printer paper",
    "status": "paid",
    "source": "manual",
    "metadata": {
      "vendor": "Office Depot",
      "payment_method": "credit_card"
    },
    "transaction_date": "2024-01-15T14:30:00Z",
    "created_at": "2024-01-15T14:32:00Z",
    "updated_at": "2024-01-15T14:32:00Z"
  }
]

Get Transaction

Retrieve a single transaction by ID.
GET /transactions?id=eq.{transaction_id}

Request Example

curl -X GET "{NEXT_PUBLIC_PG_REST_URL}/transactions?id=eq.550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Accept: application/vnd.pgrst.object+json"
Add Accept: application/vnd.pgrst.object+json header to return a single object instead of an array.

Response Example

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 125.50,
  "currency": "usd",
  "name": "Office Supplies",
  "category_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "transaction_date": "2024-01-15T14:30:00Z"
}

Create Transaction

Create a new transaction.
POST /transactions

Request Body

amount
numeric
required
Transaction amount
name
string
required
Transaction name/title
currency
string
Currency code (default: “usd”)
category_id
uuid
Category reference
description
string
Detailed description
status
string
Status: paid, pending, or failed (default: “paid”)
source
string
Source identifier (default: “manual”)
reference_no
string
Reference or invoice number
external_id
string
External system reference ID
metadata
object
Additional metadata as JSON
transaction_date
timestamp
Transaction date (default: current timestamp)
user_id
string
User ID (auto-populated from JWT)
organization_id
string
Organization ID (auto-populated from JWT if in org context)

Request Example

curl -X POST "{NEXT_PUBLIC_PG_REST_URL}/transactions" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d '{
    "amount": 89.99,
    "name": "Monthly Software Subscription",
    "description": "Adobe Creative Cloud",
    "category_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
    "status": "paid",
    "source": "manual",
    "currency": "usd",
    "transaction_date": "2024-01-15T00:00:00Z",
    "metadata": {
      "subscription": true,
      "recurring": "monthly"
    }
  }'
Include Prefer: return=representation header to return the created transaction in the response.

Response Example

{
  "id": "9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d",
  "amount": 89.99,
  "currency": "usd",
  "user_id": "usr_abc123",
  "organization_id": "org_456",
  "category_id": "7c9e6679-7425-40de-944b-e07fc1f90ae7",
  "name": "Monthly Software Subscription",
  "description": "Adobe Creative Cloud",
  "status": "paid",
  "source": "manual",
  "metadata": {
    "subscription": true,
    "recurring": "monthly"
  },
  "transaction_date": "2024-01-15T00:00:00Z",
  "created_at": "2024-01-15T10:30:00Z",
  "updated_at": "2024-01-15T10:30:00Z"
}

Update Transaction

Update an existing transaction.
PATCH /transactions?id=eq.{transaction_id}

Request Body

Any transaction fields that need to be updated. Only include fields you want to change.

Request Example

curl -X PATCH "{NEXT_PUBLIC_PG_REST_URL}/transactions?id=eq.550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d '{
    "amount": 95.00,
    "status": "paid",
    "description": "Updated description"
  }'

Response Example

{
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "amount": 95.00,
  "status": "paid",
  "description": "Updated description",
  "updated_at": "2024-01-16T09:15:00Z"
}
The updated_at field is automatically updated via database trigger.

Delete Transaction

Delete a transaction permanently.
DELETE /transactions?id=eq.{transaction_id}

Request Example

curl -X DELETE "{NEXT_PUBLIC_PG_REST_URL}/transactions?id=eq.550e8400-e29b-41d4-a716-446655440000" \
  -H "Authorization: Bearer {JWT_TOKEN}"

Response

Returns 204 No Content on successful deletion.
Deleting a transaction will cascade delete related records like line items and tag associations.

Bulk Operations

Create Multiple Transactions

Create multiple transactions in a single request.
POST /transactions

Request Example

curl -X POST "{NEXT_PUBLIC_PG_REST_URL}/transactions" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d '[
    {
      "amount": 50.00,
      "name": "Groceries",
      "category_id": "cat_food_123",
      "transaction_date": "2024-01-15T00:00:00Z"
    },
    {
      "amount": 30.00,
      "name": "Gas",
      "category_id": "cat_travel_456",
      "transaction_date": "2024-01-15T00:00:00Z"
    }
  ]'

Update Multiple Transactions

Update multiple transactions matching a filter.
PATCH /transactions?status=eq.pending
curl -X PATCH "{NEXT_PUBLIC_PG_REST_URL}/transactions?status=eq.pending" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "status": "paid"
  }'

Advanced Filtering

Filter by Date Range

GET /transactions?transaction_date=gte.2024-01-01&transaction_date=lte.2024-01-31

Filter by Amount Range

GET /transactions?amount=gte.100&amount=lte.500

Filter by Multiple Statuses

GET /transactions?status=in.(paid,pending)

Search by Name

GET /transactions?name=ilike.*subscription*

Complex Filters with OR

GET /transactions?or=(status.eq.paid,amount.gt.1000)

Access Control

Transaction access is controlled by organization roles:

Owner

Full access: list, get, create, update, delete

Admin

Full access: list, get, create, update, delete

Editor

Full access: list, get, create, update, delete

Viewer

Read-only: list, get

Personal vs Organization Transactions

  • Personal: organization_id is null, accessible only by the user
  • Organization: organization_id is set, accessible by organization members based on their role

Error Responses

401 Unauthorized

{
  "message": "JWT expired",
  "code": "PGRST301"
}

403 Forbidden

{
  "message": "permission denied for table transactions",
  "code": "42501"
}

404 Not Found

[]
PostgREST returns an empty array instead of 404 when no rows match the query.

400 Bad Request

{
  "message": "invalid input syntax for type uuid",
  "code": "22P02"
}

Build docs developers (and LLMs) love