Live config loaded — values shown in teal reflect what is currently deployed on this server.
AGS Documentation
Back to Dashboard

API Reference src/api/

All participant endpoints are under /v1/. All dashboard endpoints are under /v1/dashboard/. Participant JWT required on participant endpoints except enrollment. Researcher JWT (8h) required on all dashboard endpoints.

Participant API

MethodPathAuthSummary
POST/v1/participantsPublicEnroll. Phone → HMAC. Issue JWT + AGS### ID.
POST/v1/participants/reauthPublicRe-authenticate with phone. Rate-limited 5/window.
POST/v1/sessionsParticipantCreate session. Resolve condition server-side. Init Redis context.
POST/v1/sessions/{id}/baselineParticipantRecord baseline tap 1–3. Sets calibration_cleared after tap 3.
POST/v1/sessions/{id}/eventsParticipantSubmit event. Full pipeline. Returns adaptation synchronously. Idempotent via client_event_id.
POST/v1/sessions/{id}/helpParticipantExplicit help. Always Level ≥ 2.
GET/v1/sessions/{id}/starting-scenarioParticipantSelect first scenario for this session using ability estimate + calibration delta + time decay.
POST/v1/sessions/{id}/episodes/completeParticipantEnd episode, update ability estimate (ELO), return next scenario or session_done.
POST/v1/sessions/{id}/surveyParticipantPost-session survey. All items optional.
PATCH/v1/sessions/{id}ParticipantEnd session. Write ended_at UTC. Accept abandonment_reason.
POST/v1/ttsParticipantSynthesise adaptation text to MP3 audio. Returns audio/mpeg (base64 in JSON). Cached 7 days in Redis by sha256(lang:text). Falls back to null when Google Cloud TTS key absent or timeout — client uses Web Speech API. Rate-limited 30/min.
GET/v1/templates/{id}ParticipantServe task template with schema_version.
GET/healthPublicDB-free. Always responds. Railway health check.

Dashboard API

MethodPathRoleSummary
POST/v1/dashboard/auth/loginPublicResearcher login. bcrypt verify. Issue researcher JWT.
GET/v1/dashboard/study/healthResearcherEnrolment, completion, attrition, condition balance.
GET/v1/dashboard/study-conditionResearcherActive condition + history.
PATCH/v1/dashboard/study-conditionAdminChange active condition. Requires reason. Audit log.
GET/v1/dashboard/configResearcherCurrent threshold snapshot.
PATCH/v1/dashboard/configAdminUpdate thresholds. Calibration phase only. Audit log.
GET/v1/dashboard/sessionsResearcherLive + recent sessions with readiness, decision, study ID.
POST/v1/dashboard/sessions/{id}/terminateAdminEmergency session termination. Audit log.
PATCH/v1/dashboard/sessions/{id}/excludeResearcherExclude from analysis. Audit log.
GET/v1/dashboard/participantsResearcherList with study ID, consent, session count, exclusion.
POST/v1/dashboard/participants/{id}/withdrawResearcherFlag withdrawn. Retain data. Audit log.
GET/v1/dashboard/governanceResearcherRule hit rates, cooldown effectiveness.
GET/v1/dashboard/signalsResearcherSignal completeness, confidence histogram, baseline quality.
GET/v1/dashboard/outcomesResearcherCompletion rates by condition, task, demographic.
GET/v1/dashboard/alertsResearcherFour alert categories: study_integrity · data_quality · ethical · technical.
GET/v1/dashboard/audit-logResearcherPaginated audit log.
GET/v1/dashboard/exports/{view}Researcher7 views. CSV / XLSX / SPSS / R. Audit log.
GET/v1/dashboard/contentAdminAdaptation content by step, language, level.
PATCH/v1/dashboard/content/{id}AdminUpdate content. Version history. Audit log.
GET/v1/dashboard/content/delivery-statsResearcherDelivery count + outcome distribution (improved / ignored / worsened / pending) for every current content item. Returns { [content_id]: { total, improved, ignored, worsened, pending } }. Used by the Content tab stats chips.
GET/v1/dashboard/content/llm-fallbacksResearcherAll adaptations where Mistral generated the text (content_source="llm" or llm_updated=true). Returns step_id, level, subtype, generated text, outcome, timestamp. Used to identify content gaps requiring new DB rows.
GET/v1/dashboard/participants/{id}/journeyResearcherFull learning arc for one participant: sessions chronological, per-session ability trajectory, episodes with difficulty/performance/readiness/help events, post-session survey scores. Human-readable field names.
GET/v1/dashboard/sessions/{id}/episodesResearcherAll episodes for a session: difficulty, performance, ability trajectory, governance flags.
GET/v1/dashboard/analytics/sequencingResearcherAbility distribution, episode completion rate, difficulty breakdown, scenario performance table.
GET/v1/dashboard/participant-signals/sessionsResearcherPaginated session explorer with per-session signal aggregates (readiness, error rate, persistence, interventions, survey, ability Δ). Supports filters: condition, age_group, primary_language, device_type, date_from, date_to, include_excluded. Sort by any numeric column.
GET/v1/dashboard/participant-signals/breakdownResearcherDemographic breakdown: signal means (readiness, error rate, persistence, frustration) grouped by age_group, language, literacy, device, or condition. Returns N, completion rate, Δ ability, SD.
GET/v1/dashboard/participant-signals/scatterResearcherScatter plot data for any two signal dimensions (readiness, error rate, persistence, interventions, survey). Includes Pearson r overall and per colour-by group. Max 500 points; truncated flag set if larger.
GET/v1/dashboard/participant-signals/cohortResearcherCohort progression: chosen metric (readiness, error rate, persistence, completion rate, frustration) plotted by session number, grouped by a demographic dimension.
GET/v1/dashboard/usersAdminList all researchers with role, activity status, last login, last audit action.
POST/v1/dashboard/usersAdminCreate researcher account. Body: { email, password, role }. 409 on duplicate email.
PATCH/v1/dashboard/users/{researcher_id}AdminUpdate role, password, or active status. 400 if self-deactivation attempted.
DELETE/v1/dashboard/users/{researcher_id}AdminDelete researcher account. 400 on self-deletion.
GET/v1/dashboard/sessions/{id}ResearcherFull session detail: participant demographics, readiness timeline, governance decisions, adaptations delivered.
DELETE/v1/dashboard/sessions/{id}/excludeAdminReinstate a previously excluded session. Audit log.
PATCH/v1/dashboard/alerts/{id}/resolveResearcherMark an alert resolved. Returns updated alert item.

Task Sequencing Endpoints — Detail

These three endpoints form the adaptive task sequencing layer. They sit outside the core event pipeline and are the only integration point between the sequencer and the rest of AGS.

GET /v1/sessions/{id}/starting-scenario
AuthParticipant JWT
Response{ scenario_id, difficulty_level, episode_index, ability_score, baseline_delta_applied, total_episodes }
NotesLoads ParticipantAbility (default 50.0 for first session). Applies time-gap decay (−5 after 14 days, −10 after 30 days). Reads baseline calibration from Redis (IKI ratio, error rate, help rate) to compute baseline_delta. Starting difficulty capped at D3 — D4/D5 are never the first scenario.
POST /v1/sessions/{id}/episodes/complete
AuthParticipant JWT
Body{ scenario_id: string, completed: boolean, duration_s: number }
Response{ session_done, next_scenario_id?, difficulty_level?, episode_index?, ability_score, readiness_adjustment }
NotesReads episode signals from Redis (help count, readiness floor, worsened_outcome flag, max_intervention_level). Scores the attempt, updates ability via ELO formula, selects next scenario via ZPD targeting. Single DB transaction: INSERT ScenarioEpisode + UPSERT ParticipantAbility. session_done: true after 3 episodes or all scenarios exhausted.
GET /v1/dashboard/sessions/{id}/episodes
AuthResearcher JWT
Response{ session_id, episodes: [...], ability_trajectory: [float] }
Episode fieldsepisode_index, scenario_id, difficulty_level, completed, performance_score, ability_before, ability_after, readiness_at_start, readiness_at_end, readiness_floor, help_events, worsened_outcome, max_intervention_level, duration_s

Error codes

StatusWhen
422Mobile signal in desktop session (or vice versa) · naive datetime in event_timestamp · invalid phone format
409Template schema_version mismatch · duplicate phone on enrollment
403Consent not recorded before telemetry (ethics_violation logged to alerts) · session doesn't belong to participant · ended session
401Expired or invalid JWT — participant re-enrolls or reauthenticates; researcher re-logs in
429Reauth rate limit exceeded (5 attempts per window)
502/504Proxy upstream error or timeout — shown inside the iframe as a plain error page