Skip to main content

Overview

Subscriptions in Budget Bee help you track recurring expenses like software subscriptions, memberships, and regular services.

Base URL

{NEXT_PUBLIC_PG_REST_URL}/subscriptions

Authorization

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

Subscription Schema

id
uuid
Unique subscription identifier
title
string
Subscription name/title (required)
description
string
Detailed description
amount
numeric
Subscription cost per billing period
logo_url
string
URL to the subscription service logo
period
enum
Billing period: monthly, yearly, quarterly, semi-annually, weekly, daily
interval_in_days
integer
Custom interval in days (for non-standard periods)
category_id
uuid
Category reference
user_id
string
Owner user ID
organization_id
string
Organization ID (null for personal subscriptions)

List Subscriptions

Retrieve all subscriptions for the authenticated user or organization.
GET /subscriptions

Query Parameters

select
string
Columns to return. Default: * (all columns)
order
string
Sort order. Example: title.asc or amount.desc
period
string
Filter by billing period
category_id
string
Filter by category ID

Request Example

curl -X GET "{NEXT_PUBLIC_PG_REST_URL}/subscriptions?order=title.asc" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json"

Response Example

[
  {
    "id": "sub_abc123",
    "title": "Netflix Premium",
    "description": "Streaming service subscription",
    "amount": 19.99,
    "logo_url": "https://example.com/logos/netflix.png",
    "period": "monthly",
    "interval_in_days": null,
    "category_id": "cat_entertainment_123",
    "user_id": "usr_abc123",
    "organization_id": null
  },
  {
    "id": "sub_def456",
    "title": "Adobe Creative Cloud",
    "description": "Design software suite",
    "amount": 54.99,
    "logo_url": "https://example.com/logos/adobe.png",
    "period": "monthly",
    "interval_in_days": null,
    "category_id": "cat_software_456",
    "user_id": "usr_abc123",
    "organization_id": "org_789"
  }
]

Get Subscription

Retrieve a single subscription by ID.
GET /subscriptions?id=eq.{subscription_id}

Request Example

curl -X GET "{NEXT_PUBLIC_PG_REST_URL}/subscriptions?id=eq.sub_abc123" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Accept: application/vnd.pgrst.object+json"

Response Example

{
  "id": "sub_abc123",
  "title": "Netflix Premium",
  "description": "Streaming service subscription",
  "amount": 19.99,
  "period": "monthly",
  "category_id": "cat_entertainment_123"
}

Create Subscription

Create a new subscription to track.
POST /subscriptions

Request Body

title
string
required
Subscription name/title
amount
numeric
required
Cost per billing period
period
enum
required
Billing period: monthly, yearly, quarterly, semi-annually, weekly, daily
description
string
Detailed description
logo_url
string
URL to service logo
interval_in_days
integer
Custom interval for non-standard periods
category_id
uuid
Category reference

Request Example

curl -X POST "{NEXT_PUBLIC_PG_REST_URL}/subscriptions" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d '{
    "title": "Spotify Premium",
    "description": "Music streaming service",
    "amount": 9.99,
    "period": "monthly",
    "logo_url": "https://example.com/logos/spotify.png",
    "category_id": "cat_entertainment_123"
  }'

Response Example

{
  "id": "sub_ghi789",
  "title": "Spotify Premium",
  "description": "Music streaming service",
  "amount": 9.99,
  "logo_url": "https://example.com/logos/spotify.png",
  "period": "monthly",
  "interval_in_days": null,
  "category_id": "cat_entertainment_123",
  "user_id": "usr_abc123",
  "organization_id": null
}

Update Subscription

Update an existing subscription.
PATCH /subscriptions?id=eq.{subscription_id}

Request Example

curl -X PATCH "{NEXT_PUBLIC_PG_REST_URL}/subscriptions?id=eq.sub_abc123" \
  -H "Authorization: Bearer {JWT_TOKEN}" \
  -H "Content-Type: application/json" \
  -H "Prefer: return=representation" \
  -d '{
    "amount": 22.99,
    "description": "Updated to premium plus plan"
  }'

Response Example

{
  "id": "sub_abc123",
  "title": "Netflix Premium",
  "amount": 22.99,
  "description": "Updated to premium plus plan"
}

Delete Subscription

Delete a subscription permanently.
DELETE /subscriptions?id=eq.{subscription_id}

Request Example

curl -X DELETE "{NEXT_PUBLIC_PG_REST_URL}/subscriptions?id=eq.sub_abc123" \
  -H "Authorization: Bearer {JWT_TOKEN}"

Response

Returns 204 No Content on successful deletion.

Billing Periods

Available Periods


Subscription Status Tracking

The subscriptions table tracks subscription definitions. For payment status tracking, use the separate app_subscriptions table which tracks active subscriptions, payment status, and billing periods.

Active Subscriptions Query

To get currently active paid subscriptions (for the app itself):
GET /app_subscriptions?status=eq.sub_active&period_start=lte.now&period_end=gte.now

Calculate Annual Cost

Calculate the yearly cost of subscriptions:

Monthly Subscriptions

const annualCost = monthlyAmount * 12;
// Example: $9.99/month = $119.88/year

Custom Periods

const daysPerYear = 365;
const annualCost = (subscriptionAmount / intervalInDays) * daysPerYear;
// Example: $30 every 45 days = $243.33/year

Filter Examples

Get All Monthly Subscriptions

GET /subscriptions?period=eq.monthly

Get Subscriptions Over $50/month

GET /subscriptions?amount=gt.50&period=eq.monthly

Get Subscriptions by Category

GET /subscriptions?category_id=eq.cat_software_456

Search by Title

GET /subscriptions?title=ilike.*netflix*

Access Control

Subscription access follows role-based permissions:

Owner, Admin, Editor

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

Viewer

Read-only: list, get

Personal vs Organization Subscriptions

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

Integration with Transactions

Create recurring transactions for subscriptions:
POST /transactions
{
  "amount": 19.99,
  "name": "Netflix Premium - January 2024",
  "category_id": "cat_entertainment_123",
  "status": "paid",
  "transaction_date": "2024-01-15T00:00:00Z",
  "metadata": {
    "subscription_id": "sub_abc123",
    "recurring": true,
    "period": "monthly"
  }
}

Best Practices

Tracking Subscriptions

  1. Create subscription records for each recurring service
  2. Link to transactions using metadata
  3. Set reminders for subscription renewals
  4. Review regularly to identify unused subscriptions

Cost Management

  1. Track annual costs to understand total spending
  2. Group by category to see spending patterns
  3. Monitor price changes by updating amounts when notified
  4. Cancel unused services to reduce expenses

Organization

  1. Use consistent naming - Include plan tier in title (e.g., “Netflix Premium”)
  2. Add logos - Visual identification helps with quick scanning
  3. Detailed descriptions - Note what the subscription includes
  4. Categorize properly - Use categories like “Software”, “Entertainment”, “Services”

Build docs developers (and LLMs) love