Skip to main content

Overview

The Categories API allows users to create, read, update, and delete custom transaction categories. Categories are used to organize and classify income and expenses for better financial tracking.
Categories are user-specific. Each user can create their own set of categories that work best for their financial tracking needs.

Authentication

All endpoints require session-based authentication via the @api_login_required decorator.

Get All Categories

Retrieve all categories for the authenticated user. Endpoint: GET /api/categories

Response

Returns an array of category objects.
[
  {
    "MaDanhMuc": "abc12345",
    "TenDanhMuc": "Groceries",
    "LoaiDanhMuc": "chi"
  },
  {
    "MaDanhMuc": "def67890",
    "TenDanhMuc": "Salary",
    "LoaiDanhMuc": "thu"
  }
]

Response Fields

MaDanhMuc
string
Unique 8-character category ID
TenDanhMuc
string
Category name (e.g., “Groceries”, “Transportation”)
LoaiDanhMuc
string
Category type: "chi" (expense) or "thu" (income)

Example Request

curl -X GET https://api.finai.com/api/categories \
  -H "Cookie: session=your_session_cookie"

Create Category

Create a new transaction category. Endpoint: POST /api/categories

Request Body

name
string
required
The name of the category (e.g., “Dining Out”, “Freelance Income”)
type
string
required
Category type: "chi" (expense) or "thu" (income)

Example Request

curl -X POST https://api.finai.com/api/categories \
  -H "Content-Type: application/json" \
  -H "Cookie: session=your_session_cookie" \
  -d '{
    "name": "Coffee Shops",
    "type": "chi"
  }'

Response

{
  "status": "success"
}

Error Response

{
  "status": "error",
  "message": "Error description"
}

Update Category

Update an existing category’s name or type. Endpoint: PUT /api/categories/{cat_id}

Path Parameters

cat_id
string
required
The unique category ID

Request Body

name
string
Updated category name
type
string
Updated category type: "chi" or "thu"

Example Request

curl -X PUT https://api.finai.com/api/categories/abc12345 \
  -H "Content-Type: application/json" \
  -H "Cookie: session=your_session_cookie" \
  -d '{
    "name": "Food & Dining",
    "type": "chi"
  }'

Response

{
  "status": "success"
}

Delete Category

Delete a category.
Deleting a category will affect existing transactions that use this category. The category_id field in transactions will be set to NULL due to the ondelete='SET NULL' constraint in the database.
Endpoint: DELETE /api/categories/{cat_id}

Path Parameters

cat_id
string
required
The unique category ID to delete

Example Request

curl -X DELETE https://api.finai.com/api/categories/abc12345 \
  -H "Cookie: session=your_session_cookie"

Response

{
  "status": "success"
}

Implementation Reference

The Categories API is implemented in app/routes/foundation.py:
foundation.py
@foundation_bp.route('/api/categories', methods=['GET', 'POST'])
@api_login_required
def manage_categories():
    user_id = session['user_id']
    if request.method == 'GET':
        cats = Category.query.filter_by(user_id=user_id).all()
        return jsonify([{'MaDanhMuc': c.id, 'TenDanhMuc': c.name, 'LoaiDanhMuc': c.type} for c in cats])
    
    if request.method == 'POST':
        data = request.json
        try:
            db.session.add(Category(
                id=str(uuid.uuid4())[:8], user_id=user_id,
                name=data.get('name'), type=data.get('type')
            ))
            db.session.commit()
            return jsonify({'status': 'success'})
        except Exception as e: return jsonify({'status': 'error', 'message': str(e)}), 500

Database Schema

Categories are stored in the danhmuc table with the following structure:
models.py
class Category(db.Model):
    __tablename__ = 'danhmuc'
    
    id = db.Column('MaDanhMuc', db.String(8), primary_key=True)
    user_id = db.Column('MaNguoiDung', db.String(8), db.ForeignKey('nguoidung.MaNguoiDung', ondelete='CASCADE'))
    name = db.Column('TenDanhMuc', db.String(100), nullable=False)
    type = db.Column('LoaiDanhMuc', db.String(10), nullable=False) # 'thu' or 'chi'
    parent_id = db.Column('MaDanhMucCha', db.String(8), db.ForeignKey('danhmuc.MaDanhMuc', ondelete='SET NULL'))

Build docs developers (and LLMs) love