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:

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:

Research

GET /api/research/instruments?phase={phase}&track={track}

Returns research survey or assessment instruments.

Common tracks:

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.