Ella Backend: API & Database System Inventory

This document provides a technical specification and catalog of the database schema, active API endpoints, and real-world testing examples for the Ella voice-first English tutor backend.

Base URL Prefix

All API endpoints are deployed behind the production gateway at: https://ella.navgurukul.org/api For local testing, swap the prefix with: http://localhost:8000/api

Interactive API Documentation

You can access the auto-generated Swagger and ReDoc pages to test endpoints and inspect response schemas directly:

Placement & Onboarding Flow API Sequence

When a student launches the app and goes through placement, the following APIs are triggered in sequence:
  1. App Launch & Welcome Screen:
    • POST /auth/anonymous: Automatically invoked in the background to exchange the device’s generated UUID for a secure JWT access token, registering the account if it’s the first run.
  2. Placement Screen (Voice screening chat):
    • POST /llm/placement-turn: Called on every message turn (speech or text) containing the conversation history. Zoe replies with the next prompt until sufficient turn evidence is gathered, at which point the API responds with is_complete: true and the evaluated CEFR level results.
  3. Transitioning to Result Screen:
    • PUT /users/me: Updates student’s extracted name, age, and location.
    • POST /placements: Persists the final CEFR level assessment, description highlight, hobbies, and conversation transcript.

Client App API Integration Summary

This table summarizes which backend APIs are actively integrated and called by the student-facing Flutter client app versus those that are unused, administrative, or diagnostic.
API Group / EndpointHTTP MethodFrontend Service MethodStatus in Client App
Authentication
/auth/anonymousPOSTensureAuthenticated() / _anonymousAuth()Active (Called on launch)
User Profiles
/users/meGETgetMyProfile()Unused (No client-side consumption yet)
/users/mePUTupdateProfile()Active (Updates profile details after placement)
/users/me/memoryGETUnused (Only used in loop simulator)
/users/me/memoryPUTUnused
Placement Loop
/placementsPOSTsavePlacement()Active (Saves test result on completion)
/placements/latestGETgetLatestPlacement()Unused (No client-side consumption yet)
/placementsGETUnused
/llm/placement-turnPOSTsendPlacementTurn()Active (Drives placement chat)
Active Practice Chat
/sessionPOSTcreateConversation()Active (Starts new learning session)
/sessionGETlistConversations()Unused (History screen not implemented)
/session/{session_id}/messagesPOSTstoreMessage()Active (Saves message bubbles)
/session/{session_id}/messagesGETgetMessages()Unused
/session/{session_id}/turnPOSTconversationTurn()Active (Submit user response and get Zoe’s response)
/session/{session_id}/analysisGETgetConversationAnalysis()Active (Retrieve qualitative/quantitative conversation analysis)
/session/{session_id}/session-logGETgetSessionLog()Active (Retrieve compiled session log)
/llm/conversation-starterPOSTgetConversationStarter()Active (Generates Zoe’s opening question)
/llm/conversation-turnPOSTsendConversationTurn()Active (Zoe’s chat responses + corrections)
/llm/session-analysisPOSTgetSessionAnalysis()Active (Generates end-of-session summary card)
Progress & Admin
/progress/summaryGETgetProgressSummary()Unused (Dashboard not yet built)
/admin/*GETUnused (Supervisor portal only)

1. Database Schema & Models

The backend utilizes PostgreSQL 16 (mapped in Docker via SQLAlchemy models under backend/app/models/). There are 5 primary tables in the database:

A. Users Table (user.py)

Stores registered students, their CEFR levels, interest tags, and learning settings.
ColumnSQLAlchemy TypeConstraintsDescription
idString(36)Primary Key (UUID v4)Unique user identifier.
device_idString(64)Unique, IndexedHardware UUID sent by mobile client on first launch.
nameString(100)NullableStudent’s name (extracted during placement).
ageString(10)NullableStudent’s age bracket (extracted during placement).
locationString(100)NullableStudent’s location (extracted during placement).
levelString(5)NullableAssigned CEFR level (e.g., A1, A2, B1).
level_labelString(50)NullableUser-facing label (e.g., Beginner, Intermediate).
interestsString(200)NullableComma-separated interest tags (e.g., cricket,music).
first_session_doneBooleanDefault: FalseTracks if onboarding is complete.
created_atDateTime(timezone=True)Default: UTC NowAccount creation timestamp.
updated_atDateTime(timezone=True)Default/Update: UTC NowAccount last update timestamp.

B. Placements Table (placement.py)

Logs the results of the 3-turn voice screening test taken by the user.
ColumnSQLAlchemy TypeConstraintsDescription
idString(36)Primary Key (UUID)Unique placement record identifier.
user_idString(36)ForeignKey(users.id), IndexOwner of the placement test.
levelString(5)RequiredAssessed CEFR level code.
level_labelString(50)NullableLevel display label.
confidenceString(20)NullableLLM confidence rating on grading accuracy.
highlightTextNullableHighlight sentence displayed to the student.
transcript_jsonTextNullableFull serialized transcript of the 3 placement turns.
created_atDateTime(timezone=True)Default: UTC NowTest completion timestamp.

C. Conversations Table (conversation.py)

Tracks each session container/call completed by the user.
ColumnSQLAlchemy TypeConstraintsDescription
idString(36)Primary Key (UUID)Unique call session identifier.
user_idString(36)ForeignKey(users.id), IndexThe student who conducted this session.
topicString(100)NullableSelected conversation topic.
header_titleString(100)NullableUser-facing display title for the call.
duration_secondsIntegerNullableEstimated length of the call in seconds. Scaled automatically on the backend from the number of learner turns (turns * 30).
session_typeString(20)NullableType of session (e.g. topic, free_flow).
qualityString(20)NullableOverall session performance quality.
completedBooleanDefault: FalseStatus flag.
created_atDateTime(timezone=True)Default: UTC NowStart time.
completed_atDateTime(timezone=True)NullableEnd time.

D. Messages Table (message.py)

Logs every spoken turn inside active conversation sessions.
ColumnSQLAlchemy TypeConstraintsDescription
idString(36)Primary Key (UUID)Unique message identifier.
conversation_idString(36)ForeignKey(conversations.id), IndexSession container this message belongs to.
roleString(20)Required"user" or "assistant".
contentTextRequiredTranscribed voice text of the message.
correctionTextNullableGrammar suggestions/corrections for the user.
stt_duration_msIntegerNullableSpeech-to-Text conversion time telemetry.
llm_duration_msIntegerNullableLLM response generation time telemetry.
tts_duration_msIntegerNullableText-to-Speech audio conversion time telemetry.
turn_numberIntegerDefault: 0Sequence index of the turn inside the conversation.
created_atDateTime(timezone=True)Default: UTC NowMessage send timestamp.

E. Session Analyses Table (session_analysis.py)

Stores post-session LLM analysis cards generated at the end of each conversation.
ColumnSQLAlchemy TypeConstraintsDescription
idString(36)Primary Key (UUID)Unique analysis card identifier.
conversation_idString(36)ForeignKey(conversations.id), Unique, IndexOne-to-one link to conversation container.
overallString(20)RequiredOverall grade/evaluation score (e.g. great, okay).
best_moment_quoteTextNullableQuote highlighting student’s best speech moment.
best_moment_noteTextNullableExplanation note why it was the best moment.
courage_typeString(30)NullableType of courage shown (e.g. speaking_clearly).
courage_contentTextNullableExplanation note regarding shown courage.
try_next_skillTextNullableSuggested grammar/vocab skill to practice next.
try_next_exampleTextNullableUsage example of the recommended next skill.
transcript_notes_jsonTextNullableSerialized list of turn-by-turn notes for progress analysis.
created_atDateTime(timezone=True)Default: UTC NowEvaluation generation timestamp.

2. API Endpoints Catalog & Purpose Specs

FastAPI routes are organized under backend/app/routers/.

Group 1: Onboarding & Authentication

  • POST https://ella.navgurukul.org/api/auth/anonymous
    • Payload: AnonymousAuthRequest (device_id string)
    • Purpose & Reason: Establishes a zero-friction user account on first app install. We want to avoid requiring emails or passwords for young students. If the device_id is new, it silently provisions a new SQL record in users and issues a JSON Web Token (JWT). If the device is returning, it issues a fresh token to authenticate subsequent calls.

Group 2: User Profiles & Learning Settings

  • GET https://ella.navgurukul.org/api/users/me
    • Headers: Authorization: Bearer <token>
    • Purpose & Reason: Fetches the student’s active status (level, tags, and settings). This is called when the app starts to check if the student has completed their first voice placement screening.
  • PUT https://ella.navgurukul.org/api/users/me
    • Payload: UpdateProfileRequest (name, age, location)
    • Purpose & Reason: Captures details parsed from LLM placement transcripts. It updates demographic details on the student’s profile for localized progress grouping.

Group 3: Voice Placement Screening Loop

  • POST https://ella.navgurukul.org/api/llm/placement-turn
    • Payload: PlacementTurnRequest (messages, name, age)
    • Purpose & Reason: Runs the 3-turn voice screening test. Zoe greets the student and conducts a conversational prompt flow. The API acts as the state machine; once 3 turns are completed, it evaluates CEFR proficiency and sets is_complete=True.
  • POST https://ella.navgurukul.org/api/placements
    • Payload: CreatePlacementRequest (level, level_label, confidence, highlight, transcript_json, interests)
    • Purpose & Reason: Finalizes the placement test. Saves the final CEFR grading, logs confidence scoring, extracts interest tags, and stores the chat transcript JSON. It updates the student’s profile settings to lock in their learning level.
  • GET https://ella.navgurukul.org/api/placements/latest
    • Purpose & Reason: Fetches the student’s active placement parameters to adjust vocabulary and theme choices.
  • GET https://ella.navgurukul.org/api/placements
    • Purpose & Reason: Lists historical placement tests completed, allowing progress comparisons over time.

Group 4: Call Sessions & Active Voice Chat

  • POST https://ella.navgurukul.org/api/session
    • Payload: CreateConversationRequest (topic)
    • Purpose & Reason: Creates a new session container. Binds the selected learning theme (e.g. “My Family”) to a unique session ID, allowing us to group subsequent message turns under one session.
  • POST https://ella.navgurukul.org/api/session/{session_id}/turn
    • Payload: ConversationTurnRequest (content)
    • Purpose & Reason: The core turn-by-turn conversational logic. For every sentence the student speaks, this endpoint processes the message, runs context analysis, and returns Zoe’s response.
  • POST https://ella.navgurukul.org/api/session/{session_id}/messages
    • Payload: StoreMessageRequest (role, content, correction, stt_duration_ms, llm_duration_ms, tts_duration_ms, turn_number)
    • Purpose & Reason: Persists individual message bubbles, corrections, and latency metrics to database history.
  • GET https://ella.navgurukul.org/api/session/{session_id}/messages
    • Purpose & Reason: Returns the transcript history of a call to display the chat list UI.
  • GET https://ella.navgurukul.org/api/session/{session_id}/analysis
    • Purpose & Reason: Returns qualitative and quantitative evaluation of the session once completed.
  • GET https://ella.navgurukul.org/api/session/{session_id}/session-log
    • Purpose & Reason: Returns the compiled structured log for learning analytics.

Group 5: Post-Session Evaluation & Progress

  • POST https://ella.navgurukul.org/api/llm/session-analysis
    • Payload: SessionAnalysisRequest
    • Purpose & Reason: Runs immediately after session completion. Zoe analyzes the full transcript, extracting a “Best Moment” and “Courage” moments to build encouragement cards. The endpoint automatically computes practice duration dynamically as learner_turns * 30 seconds and saves it to the database, completing the conversation.
  • GET https://ella.navgurukul.org/api/progress/summary
    • Purpose & Reason: Computes aggregate statistics (total calls, completed sessions, speaking time, and placement history) to display on the student’s profile dashboard.

Group 6: Classroom Admin Dashboards (Key Protected)

  • GET https://ella.navgurukul.org/api/admin/stats
    • Purpose & Reason: Provides classroom stats (user levels, total minutes spoken) for supervisor auditing (requires query string key).
  • GET https://ella.navgurukul.org/api/admin/conversations/{conversation_id}/transcript
    • Purpose & Reason: Allows supervisors to fetch full transcripts with detailed latency profiles to review student progress (requires admin key).
  • GET https://ella.navgurukul.org/api/admin/placements/{user_id}/transcript
    • Purpose & Reason: Allows supervisors to review the transcript of a student’s placement test to audit grading accuracy (requires admin key).

Group 7: Accent Evaluation (POC — Disabled)

  • POST https://ella.navgurukul.org/api/accent/predict
    • Payload: UploadFile (Multipart WAV Audio)
    • Purpose & Reason: Implements an accent prediction POC. Takes WAV audio files, extracts MFCC features using librosa, and uses a trained Keras CNN model (accent_model.h5) to classify the accent as Indian or American. (Currently commented out in main app due to heavy machine learning dependencies).

Group 8: System Diagnostics

  • GET https://ella.navgurukul.org/api/
    • Purpose & Reason: Verifies the API server is reachable and redirects to OpenAPI specs.
  • GET https://ella.navgurukul.org/api/health
    • Purpose & Reason: Basic health check endpoint for DevOps monitoring.

3. Practical API Curl Examples

Below are standard curl calls demonstrating how to query the primary backend endpoints.

1. Anonymous Device Registration (Token Exchange)

Call this once on first launch to exchange the device UUID for a secure token:
curl -X POST https://ella.navgurukul.org/api/auth/anonymous \
  -H "Content-Type: application/json" \
  -d '{
    "device_id": "8c59-cc44-b71a-40e9-uuid"
  }'

2. Fetch User Profile Details

Retrieves details of the authenticated student profile:
curl -X GET https://ella.navgurukul.org/api/users/me \
  -H "Authorization: Bearer <your_access_token>"

3. Start a Session

Creates a session call container for a specific topic:
curl -X POST https://ella.navgurukul.org/api/session \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "topic": "My Favorite Sports"
  }'

4. Execute a Conversation Turn (Zoe’s Response)

Sends the user’s spoken transcription to the AI tutor and returns Zoe’s spoken reply and grammar suggestions:
curl -X POST https://ella.navgurukul.org/api/llm/conversation-turn \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "3be40648-1fd1-4942-b96f-44c3a02344db",
    "messages": [
      {
        "role": "user",
        "content": "hello zoe i like to play cricket with my friends"
      }
    ],
    "topic": "My Favorite Sports",
    "level": "A1",
    "level_label": "Getting Started",
    "current_turn": 1
  }'

5. Log Message Turn (Telemetry and Corrections)

Saves the message bubble, corrections, and latency metrics to database history:
curl -X POST https://ella.navgurukul.org/api/session/3be40648-1fd1-4942-b96f-44c3a02344db/messages \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "role": "user",
    "content": "hello zoe i like to play cricket with my friends",
    "correction": "Hello Zoe, I like playing cricket with my friends.",
    "stt_duration_ms": 320,
    "llm_duration_ms": 1100,
    "tts_duration_ms": 500,
    "turn_number": 1
  }'

6. Generate Post-Session Analysis

Runs at the end of the call, saving evaluation cards to the database:
curl -X POST https://ella.navgurukul.org/api/llm/session-analysis \
  -H "Authorization: Bearer <your_access_token>" \
  -H "Content-Type: application/json" \
  -d '{
    "conversation_id": "3be40648-1fd1-4942-b96f-44c3a02344db",
    "messages": [
      {
        "role": "user",
        "content": "hello zoe i like to play cricket with my friends"
      },
      {
        "role": "assistant",
        "content": "Cricket is great! Who is your favorite player?"
      }
    ],
    "topic": "My Favorite Sports",
    "level": "A1",
    "level_label": "Getting Started"
  }'

7. Retrieve Classroom Stats Dashboard (Admin Route)

Pulls user stats and conversation metrics (must include the admin secret query string):
curl -X GET "https://ella.navgurukul.org/api/admin/stats?key=<your_admin_secret_key>"