KakeiBuddy API Reference
Base URL for local development: http://localhost:8000.
Interactive FastAPI documentation is available at /docs when the backend is running.
All examples use JSON. The API currently uses anonymous user UUIDs rather than login tokens for mobile app calls.
Root And Health
GET /
Returns a welcome response and is used as the Render health check path.
Example response:
{
"message": "Welcome to KakieBuddy API"
}
GET /badges
Returns all seeded backend badges.
Users And Budget Profile
POST /api/users/
Creates an anonymous user. A UUID may be supplied by the client, otherwise the service creates one.
Example request:
{
"uuid": "participant-uuid"
}
Example response:
{
"uuid": "participant-uuid"
}
PUT /api/users/{uuid}/profile/
Creates or updates a user’s budget profile. The request body follows BudgetProfileUpdate in backend/schemas/budget.py.
Example request:
{
"income_range_id": 3,
"user_profile": "student",
"allow_exact_income": false,
"exact_income_local": null,
"coach_style": 1,
"savings_goal_type": "monthly",
"saving_goal_value": 2500,
"budget_cycle_start_day": 1
}
Returns a transaction status message such as created or updated.
GET /api/users/{uuid}/points
Returns the user’s total backend points.
Example response:
{
"total_points": 150
}
Challenge Templates And User Challenges
GET /templates
Returns challenge templates. Optional query parameters:
category_iddifficultyis_ai_suggested
Note: the current route contains a category filter branch that applies the difficulty field when category_id is present. Treat the generated /docs schema and current route behavior as the source of truth until this is reviewed.
Template response fields include id, slug, title, challenge_type, category, metric_key, target_value, unit, reward_points, difficulty, is_ai_suggested, and optional AI suggestion metadata.
GET /api/users/{uuid}/challenges?month=YYYY-MM
Returns user challenges for the requested month.
POST /api/users/{uuid}/challenges/{challenge_template_id}/accept
Accepts a challenge template for a user. Request body follows UserChallengeCreate.
Example request:
{
"challenge_template_id": 12,
"month_range": "2026-06",
"source": "user",
"ai_suggestion_id": null
}
POST /api/users/{uuid}/challenges/{user_challenge_id}/progress
Updates progress for an accepted user challenge. Request body follows UserChallengeUpdateProgress.
Example request:
{
"current_progress": 3
}
POST /api/users/{uuid}/challenges/{user_challenge_id}/claim
Claims a completed challenge reward.
Summaries
POST /api/users/{uuid}/summaries/weekly/
Uploads a weekly summary. Request body follows WeeklySummaryCreate.
Example request:
{
"month_key": 202606,
"week_key": 2,
"total_spent": 3200.5,
"spent_wants": 900,
"spent_needs": 1800.5,
"spent_culture": 300,
"spent_unexpected": 200,
"logging_days_count": 5
}
GET /api/users/{uuid}/summaries/weekly/{month_key}/{week_key}/
Fetches one weekly summary.
POST /api/users/{uuid}/summaries/monthly/
Uploads a monthly summary. Request body follows MonthlySummaryCreate.
Example request:
{
"month_key": 202606,
"total_spent": 14800,
"spent_wants": 4200,
"spent_needs": 8200,
"spent_culture": 1600,
"spent_unexpected": 800,
"logging_days_count": 24
}
GET /api/users/{uuid}/summaries/monthly/{month_key}/
Fetches one monthly summary.
Coach
POST /coach/suggestions
Returns coaching suggestions from the AI policy or fallback rules.
Request body:
{
"budget_used_ratio": 0.72,
"needs_share": 0.45,
"wants_share": 0.28,
"culture_share": 0.12,
"unexpected_share": 0.05,
"savings_goal_progress": 0.4,
"prev_w_adj": 0.5,
"prev_c_adj": 0.5,
"prev_s_adj": 0.5,
"risk_profile": 0.5
}
All values are normalized from 0 to 1. Extra fields are rejected.
Response fields:
policy_versionstate_contract_versionfallback_usedsuggestions
Research
GET /api/research/instruments?phase={phase}&track={track}
Returns research survey or assessment instruments.
Common tracks:
talegala
POST /api/users/{uuid}/research/consent
Stores research consent settings.
Example request:
{
"consented": true,
"age_confirmed": true,
"data_mode": "private",
"participant_code": "P-001",
"allow_research_export": true,
"study_version": "gala-tale-2026-v1"
}
PATCH /api/users/{uuid}/research/data-mode
Updates research data mode metadata.
Example request:
{
"data_mode": "sync"
}
POST /api/users/{uuid}/research/responses
Stores survey or assessment responses.
Example request:
{
"phase": "pre",
"instrument_key": "budget_confidence",
"response_type": "survey",
"responses": {
"q1": 4,
"q2": 3
}
}
POST /api/users/{uuid}/reflections
Stores a user reflection and returns quality feedback fields.
Example request:
{
"phase": "weekly",
"category": "wants",
"reflection_text": "I noticed snacks were my biggest optional expense this week.",
"confidence_rating": 4,
"intended_action": "Limit snack purchases to weekends."
}
POST /api/users/{uuid}/events
Stores an anonymous app event.
Example request:
{
"event_name": "challenge_catalog_viewed",
"context": {
"source": "challenge_tab"
},
"client_timestamp": "2026-06-13T10:30:00Z"
}
POST /api/users/{uuid}/challenge-metrics
Creates or updates challenge metric snapshots.
Example request:
{
"month_range": "2026-06",
"metrics": {
"expense_log_days": 12,
"monthly_savings_goal_progress_percent": 65
},
"client_timestamp": "2026-06-13T10:30:00Z"
}
POST /api/users/{uuid}/research/progress-snapshots
Creates or updates research progress snapshots.
Example request:
{
"month_range": "2026-06",
"level": 2,
"level_title": "Consistency Builder",
"total_points": 150,
"streak_days": 4,
"active_missions_count": 2,
"completed_missions_count": 1,
"claimed_rewards_count": 1,
"failed_missions_count": 0,
"badges_earned_count": 1,
"reflection_count": 2,
"game_metrics": {},
"learning_metrics": {},
"badge_ids": [1],
"mission_summary": []
}
GET /api/admin/research/export
Exports the research dataset.
Required header:
X-Research-Export-Token: <RESEARCH_EXPORT_TOKEN>
If RESEARCH_EXPORT_TOKEN is not configured, the endpoint returns 503. If the header is missing or invalid, it returns 403.
Admin
/admin
FastAdmin is mounted at /admin. The backend seeds a default admin user with UUID admin if it does not exist. Configure ADMIN_PASSWORD before deployment.