Complete API documentation for PrivateLedger endpoints.
http://localhost:8844
Get API information and available endpoints.
Response:
{
"name": "PrivateLedger API",
"version": "0.1.0",
"endpoints": {
"accounts": "/api/accounts",
"transactions": "/api/transactions",
"categories": "/api/categories",
"import": "/api/import",
"insights": "/api/insights"
}
}List all accounts.
Response:
[
{
"account_id": 1,
"name": "TD Credit Card",
"created_at": "2025-01-15T10:30:00Z"
}
]Get a single account by ID.
Response:
{
"account_id": 1,
"name": "TD Credit Card",
"created_at": "2025-01-15T10:30:00Z"
}Create a new account.
Request:
{
"name": "RBC Chequing"
}Response: 201 Created
{
"account_id": 2,
"name": "RBC Chequing",
"created_at": "2025-01-15T10:35:00Z"
}Update an account's name.
Request:
{
"name": "RBC Chequing Updated"
}Response:
{
"account_id": 2,
"name": "RBC Chequing Updated",
"created_at": "2025-01-15T10:35:00Z"
}Delete an account (cascades to transactions).
Response:
{
"message": "Account deleted successfully"
}List transactions with optional filters.
Query Parameters:
account_id(int) - Filter by accountcategory_id(int) - Filter by categoryuncategorized(bool) - Only uncategorized (true/false)start_date(string) - Date range start (YYYY-MM-DD)end_date(string) - Date range end (YYYY-MM-DD)limit(int) - Max resultsoffset(int) - Pagination offset
Example:
GET /api/transactions?account_id=1&uncategorized=true&limit=50
Response:
[
{
"transaction_id": 1,
"account_id": 1,
"trn_type": "DEBIT",
"fit_id": "25326171322410010",
"date_posted": "2025-01-15T00:00:00Z",
"amount": -45.99,
"transaction_details": "STARBUCKS - DOWNTOWN",
"transaction_type": 1,
"category_id": 3,
"category_source": 1,
"created_at": "2025-01-15T10:40:00Z"
}
]Get a single transaction by ID.
Response: Same as list item above.
Update a transaction's category (manual assignment).
Request:
{
"category_id": 5
}Or to uncategorize:
{
"category_id": null
}Response: Updated transaction object.
Delete a transaction.
Response:
{
"message": "Transaction deleted successfully"
}List all categories with their patterns.
Response:
[
{
"category_id": 1,
"name": "Groceries",
"color": "#4CAF50",
"created_at": "2025-01-15T09:00:00Z",
"patterns": [
{
"category_pattern_id": 1,
"pattern_name": "WALMART",
"category_id": 1,
"created_at": "2025-01-15T09:00:00Z"
},
{
"category_pattern_id": 2,
"pattern_name": "LOBLAWS",
"category_id": 1,
"created_at": "2025-01-15T09:01:00Z"
}
]
}
]Get a single category with patterns.
Response: Same as list item above.
Create a new category with optional initial patterns.
Request:
{
"name": "Dining",
"color": "#FF5722",
"patterns": ["RESTAURANT", "STARBUCKS", "TIM HORTONS"]
}Response: 201 Created - Category with patterns object.
Update a category's name and/or color.
Request:
{
"name": "Restaurants",
"color": "#E91E63"
}Response: Updated category object.
Delete a category (cascades to patterns, clears from transactions).
Response:
{
"message": "Category deleted successfully"
}Manually trigger re-categorization of all uncategorized transactions.
Response:
{
"processed_count": 150,
"categorized_count": 87
}Add a new pattern to a category.
Request:
{
"pattern_name": "MCDONALD'S"
}Response: 201 Created
{
"category_pattern_id": 10,
"pattern_name": "MCDONALD'S",
"category_id": 3,
"created_at": "2025-01-15T11:00:00Z"
}Delete a pattern.
Response:
{
"message": "Pattern deleted successfully"
}Import transactions from an OFX or QFX file.
Content-Type: multipart/form-data
Form Fields:
file(file) - OFX or QFX fileaccount_id(int) - Target account ID
Example (curl):
curl -X POST http://localhost:8844/api/import \
-F "file=@statement.ofx" \
-F "account_id=1"Response:
{
"total_transactions": 120,
"imported_count": 95,
"duplicate_count": 25,
"categorized_count": 68,
"error_count": 0,
"errors": [],
"transactions": [...]
}Validate an OFX or QFX file without importing.
Content-Type: multipart/form-data
Form Fields:
file(file) - OFX or QFX file
Response:
{
"valid": true,
"message": "OFX/QFX file is valid"
}Get complete dashboard statistics.
Response:
{
"current_month": {
"period": {
"label": "2025-01",
"start_date": "2025-01-19T00:00:00Z",
"end_date": "2025-02-18T23:59:59Z"
},
"total_income": 3500.00,
"total_expenses": 2145.67,
"net_amount": 1354.33,
"transaction_count": 89,
"uncategorized_count": 12,
"category_breakdown": [
{
"category_id": 1,
"category_name": "Groceries",
"category_color": "#4CAF50",
"total_amount": 456.78,
"count": 18
}
]
},
"account_count": 3,
"category_count": 8,
"uncategorized_count": 45
}Get financial summary for a specific month.
Query Parameters:
year(int) - Year (e.g., 2025)month(int) - Month 1-12 (e.g., 1 for January)
If no parameters provided, returns current month.
Example:
GET /api/insights/monthly?year=2025&month=1
Response: Same as current_month in dashboard response.
Get the current month period based on config.
Response:
{
"label": "2025-01",
"start_date": "2025-01-19T00:00:00Z",
"end_date": "2025-02-18T23:59:59Z"
}All endpoints return consistent error responses:
400 Bad Request:
{
"error": "Invalid account_id"
}404 Not Found:
{
"error": "Account not found"
}409 Conflict:
{
"error": "Account with this name already exists"
}500 Internal Server Error:
{
"error": "Failed to query database: ..."
}- All timestamps are in UTC
- Date filters use YYYY-MM-DD format
- Custom month boundaries respect
start_of_monthconfig setting - Category source values: 0=none, 1=rule, 2=manual
- Transaction type values: 1=debit, 2=credit
- Background re-categorization is triggered automatically when patterns are added