Skip to main content

Overview

The AI Services API provides intelligent financial assistance through category prediction, conversational AI, and automated insights. All endpoints require authentication and leverage Google Gemini AI. Base Path: /api Authentication: Required (@api_login_required decorator) AI Engine: Google Gemini (configured via app.ai_service)

Predict Category

Automatically predict the most appropriate category for a transaction based on its description.
POST
method
/api/predict-category

How It Works

  1. Fetches the user’s existing category list
  2. Sends transaction description + category menu to AI
  3. AI selects the best matching category from user’s options
  4. Returns category ID, name, type, and confidence score

Request Body

description
string
required
Transaction description to analyze (e.g., “Mua cà phê sáng”, “Đổ xăng xe”)

Response

status
string
success, no_match, or error
category_id
string
Matched category ID (only on success)
category_name
string
Category name (only on success)
category_type
string
Category type: thu (income) or chi (expense)
confidence
number
AI confidence score (0-100)
message
string
Error message (only on error)

Example Request

curl -X POST https://api.finai.com/api/predict-category \
  -H "Content-Type: application/json" \
  -H "Cookie: session=your-session-cookie" \
  -d '{
    "description": "Mua cà phê sáng tại Highlands"
  }'

Example Response

Success
{
  "status": "success",
  "category_id": "c1234567",
  "category_name": "Ăn uống",
  "category_type": "chi",
  "confidence": 95
}
No Match
{
  "status": "no_match"
}
Error
{
  "status": "error",
  "message": "No description"
}

Implementation Details

Source: app/routes/ai.py:25-61

Chat with AI Assistant

Converse with an AI financial advisor that understands your financial context.
POST
method
/api/chat

Context Provided to AI

The AI receives comprehensive financial context:
Current balance for all user wallets

Request Body

message
string
required
User’s question or message to the AI assistant

Response Format

Returns a streaming response (text/plain) where AI response is sent incrementally as it’s generated.

Example Request

curl -X POST https://api.finai.com/api/chat \
  -H "Content-Type: application/json" \
  -H "Cookie: session=your-session-cookie" \
  -d '{
    "message": "Tôi chi tiêu tháng này thế nào?"
  }'

Example Response (Streaming)

Dựa vào dữ liệu của bạn, tháng này bạn đã chi tiêu 4.5 triệu đồng, 
trong đó Ăn uống chiếm 2.1 triệu, Xăng xe 1.2 triệu. So với thu nhập 
5 triệu, bạn đã tiết kiệm được 500 nghìn. Tuy nhiên, chi tiêu cho 
Ăn uống hơi cao, bạn nên cân nhắc giảm bớt...

Context Building

Source: app/routes/ai.py:75-108
# 1. Wallet balances
wallets = Wallet.query.filter_by(user_id=user_id).all()
for w in wallets: 
    context_text += f"- {w.name}: {int(w.balance):,} VND\n"

# 2. 30-day expense summary (grouped)
expense_summary = db.session.query(
    Category.name, func.sum(Transaction.amount)
).join(Transaction, Transaction.category_id == Category.id).filter(
    Transaction.user_id == user_id, 
    Transaction.date >= last_30_days,
    Transaction.type == 'chi'
).group_by(Category.name).all()

# 3. Recent 5 transactions
recent_transactions = Transaction.query.filter_by(user_id=user_id)\
    .order_by(Transaction.date.desc()).limit(5).all()

Chat History Storage

  • Conversations are logged to ChatbotLog table after streaming completes
  • Each log entry includes question, full answer, timestamp, and user ID
  • Used for conversation history and quality monitoring

Error Response

{
  "response": "Hệ thống AI đang bảo trì, vui lòng thử lại sau!"
}

Get Chat History

Retrieve recent chat conversation history.
GET
method
/api/chat/history

Response

history
array
Array of message objects in chronological order (oldest first)

Example Request

curl -X GET https://api.finai.com/api/chat/history \
  -H "Cookie: session=your-session-cookie"

Example Response

[
  {
    "role": "user",
    "content": "Tôi chi tiêu tháng này thế nào?"
  },
  {
    "role": "ai",
    "content": "Dựa vào dữ liệu của bạn, tháng này bạn đã chi tiêu 4.5 triệu đồng..."
  },
  {
    "role": "user",
    "content": "Tôi nên tiết kiệm thế nào?"
  },
  {
    "role": "ai",
    "content": "Để tiết kiệm hiệu quả, bạn nên..."
  }
]

Implementation Details

Source: app/routes/ai.py:150-161
  • Retrieves last 20 messages
  • Ordered by creation date (newest first in query)
  • Reversed before returning (oldest first for display)
  • Messages interleaved between user and AI roles

Dashboard Insights

Get quick AI-generated financial insights for dashboard display.
GET
method
/api/dashboard-insights

Features

  • Returns exactly 3 concise financial tips
  • Based on current month’s income and expenses
  • Respects user’s AI settings (UserSetting.ai_suggestions)
  • Formatted as clean, actionable advice (no greetings or markdown)

Response

status
string
success, disabled, or error
data
array
Array of 3 insight strings (only on success)
message
string
Status message (on disabled/error)

Example Request

curl -X GET https://api.finai.com/api/dashboard-insights \
  -H "Cookie: session=your-session-cookie"

Example Response

Success
{
  "status": "success",
  "data": [
    "Chi tiêu Ăn uống cao, giảm 20% tháng sau",
    "Tiết kiệm được 15% thu nhập, rất tốt",
    "Nên lập quỹ khẩn cấp 3 tháng lương"
  ]
}
Disabled
{
  "status": "disabled",
  "message": "Tính năng AI đang bị tắt."
}
Error
{
  "status": "error",
  "message": "Hệ thống AI đang bận."
}

AI Prompt Engineering

Source: app/routes/ai.py:191-202 The prompt enforces strict formatting:
question = (
    "Dựa vào số liệu trên, hãy đưa ra 3 lời khuyên tài chính. "
    "YÊU CẦU NGHIÊM NGẶT ĐỂ ĐỊNH DẠNG: "
    "1. TUYỆT ĐỐI KHÔNG chào hỏi, KHÔNG xưng hô. "
    "2. TUYỆT ĐỐI KHÔNG có câu dẫn dắt. "
    "3. Trả về ĐÚNG 3 dòng, mỗi dòng là một lời khuyên trực tiếp. "
    "4. Độ dài tối đa: Dưới 15 chữ cho MỖI dòng. "
    "5. Không dùng markdown, không dùng icon."
)

Post-Processing

  1. Collects full streaming response
  2. Splits by newlines
  3. Strips leading bullets/markers (-*•)
  4. Filters empty lines
  5. Returns first 3 insights

Implementation Reference

Source: app/routes/ai.py

Error Codes

Status CodeDescription
200Request successful
400Missing required parameter
401Unauthorized (not logged in)
500AI service error or database failure

Build docs developers (and LLMs) love