openapi: 3.1.3 info: title: The Special Standard API version: 0.1.0 servers: - url: http://localhost:8080/api/v1 description: Development server - url: https://king-prawn-app-n5vk6.ondigitalocean.app/api/v1 description: Production server tags: - name: Health description: Health check operations - name: Auth description: Authentication Management Operations - name: Sessions description: Therapy session operations - name: Students description: Student management operations - name: Session Students description: Operations for managing the relationship between sessions and students - name: Therapists description: Physical Therapists Registered - name: Themes description: Theme management operations - name: Resources description: Resource management operations - name: SessionResource description: Session-Resource association operations - name: Districts description: District management operations - name: Newsletter description: Newsletter management operations paths: /health: get: summary: Health check description: Check if the API is running and healthy tags: [Health] responses: "200": description: API is healthy (status code only) "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /auth/signup: post: summary: SignUp Feature description: Signs Up New User to the Platform as a Therapist tags: [Auth] requestBody: required: true content: application/json: schema: type: object required: - email - password properties: email: type: string format: email description: Email ID of the User/Therapist example: "dr.doolittle@zoolittle.com" password: type: string description: Password of the User/Therapist (meets strong password requirements) example: "IlikeMYanimalsLITTLE@34" first_name: type: string description: First Name of the User/Therapist example: "John" last_name: type: string description: Last Name of the User/Therapist example: "Dolittle" responses: "201": description: User/Therapist created successfully! content: application/json: schema: type: object required: - access_token - user properties: access_token: type: string description: The JWT Access Token issued for this User example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." user: type: object properties: id: type: string format: uuid description: The unique identifier of the newly created therapist example: "f20e5948-01ba-4113-b453-db05d8bde3bc" "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Bad Request" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Internal Server Error" /auth/login: post: summary: Login Feature description: Log into the Platform tags: [Auth] requestBody: required: true content: application/json: schema: type: object required: - email - password - remember_me properties: email: type: string format: email description: Email ID of the User/Therapist example: "dr.doolittle@zoolittle.com" password: type: string description: Password of the User/Therapist (meets strong password requirements) example: "IlikeMYanimalsLITTLE@34" remember_me: type: boolean description: Whether to remember the user for a longer session duration example: true responses: "200": description: User logged in successfully. content: application/json: schema: type: object required: - access_token - token_type - expires_in - refresh_token - user properties: access_token: type: string description: The JWT Access Token issued for this User example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." token_type: type: string description: Describes the type of JWT Token designated to this User example: "bearer" expires_in: type: int description: The Amount of Time it will take for this token to expire example: 3600 refresh_token: type: string description: Used to get a new access token after the current one expires... example: "67z4xav34h37" user: type: object properties: id: type: string format: uuid description: The unique identifier of the newly created therapist example: "f20e5948-01ba-4113-b453-db05d8bde3bc" error: content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Internal Server Error" "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Bad Request" "401": description: Status Unauthorized Request content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 401 message: "Status Unauthorized?!" /auth/forgot-password: post: summary: Forgot Password Feature description: Forgot Password? Reset it here! tags: [Auth] requestBody: required: true content: application/json: schema: type: object properties: email: type: string format: email description: Email registered to the account that's trying to reset password example: happyPanther@feline.com responses: "200": description: Successfully forgot password. AND we reset it. "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Bad Request" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Internal Server Error" /auth/update-password: put: summary: Updating Password Feature description: Update your password for your account using a reset token tags: [Auth] parameters: - name: token in: query required: false description: Password reset token (typically sent via email to the user) schema: type: string example: "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..." requestBody: required: true content: application/json: schema: type: object required: - password properties: password: type: string format: password description: New Password (must meet strong password requirements) example: "NewPassword@123" responses: "200": description: Successfully updated your password. "400": description: Bad Request (e.g., validation errors, missing token) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Reset token is missing" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Password update failed" /auth/delete-account/{id}: delete: summary: Delete Account Feature description: Delete your Account here! Requires authentication via JWT token in cookies. You can only delete your own account. tags: [Auth] parameters: - name: id in: path required: true description: The UUID of the user (therapist) being deleted. Must match the authenticated user's ID. schema: type: string format: uuid responses: "200": description: Successfully deleted account. Cookies cleared. "400": description: Bad Request (e.g., invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "401": description: Unauthorized! No authentication token found or token invalid content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 401 message: "No authentication token found" "403": description: Forbidden! You can only delete your own account content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 403 message: "You can only delete your own account" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Failed to delete user data" security: - cookieAuth: [] /sessions: /sessions: get: summary: Get all sessions description: Retrieve all therapy sessions from the database with optional filtering tags: [Sessions] parameters: - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 - name: startdate in: query description: Filter sessions starting on or after this datetime schema: type: string format: date-time example: "2025-01-01T00:00:00Z" - name: enddate in: query description: Filter sessions starting on or before this datetime schema: type: string format: date-time example: "2025-12-31T23:59:59Z" - name: month in: query description: Filter sessions by month (1-12) schema: type: integer minimum: 1 maximum: 12 example: 9 - name: year in: query description: Filter sessions by year schema: type: integer minimum: 1776 maximum: 2200 example: 2025 - name: student_ids in: query description: Filter sessions that contain ALL specified student IDs (can be repeated for multiple students) schema: type: array items: type: string format: uuid style: form explode: true example: ["550e8400-e29b-41d4-a716-446655440000"] - name: therapist_id in: query description: Filter sessions by therapist UUID schema: type: string format: uuid style: form explode: true example: "550e8400-e29b-41d4-a716-446655440000" responses: "200": description: List of therapy sessions matching the filters content: application/json: schema: type: array items: $ref: "#/components/schemas/Session" "400": description: Bad request (e.g., invalid query parameters) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid student ID format" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Resource not found" post: summary: Create a new session description: Create a new therapy session tags: [Sessions] requestBody: required: true content: application/json: schema: type: object required: - session_name - start_datetime - end_datetime - therapist_id properties: session_name: type: string description: Name of the Session example: "Grammar say what?!" start_datetime: type: string format: date-time description: Start date and time of the session example: "2025-09-13T17:19:00Z" end_datetime: type: string format: date-time description: End date and time of the session example: "2025-09-13T18:00:00Z" therapist_id: type: string format: uuid description: UUID of the Therapist example: "3fa85f64-5717-4562-b3fc-2c963f66afa6" notes: type: string description: Optional notes about the session example: "Daily Affirmation: My luck is so good that even four-leaf clovers ask for my autograph" location: type: string description: Optional location information of the session example: "Home is where the heart is, the heart is where the spark is..." repetition: type: object required: - recur_start - recur_end - every_n_weeks properties: recur_start: type: string format: date-time description: Starting Date of Recurring Session example: "2025-09-13T17:19:00Z" recur_end: type: string format: date-time description: Ending Date of Recurring Session example: "2025-11-13T17:19:00Z" every_n_weeks: type: int format: positive description: Recurring Session will happen every "N" weeks example: 2 student_ids: type: array items: type: string format: uuid description: List of Student IDs of the students that are being added to this Session. responses: "201": description: Session created successfully content: application/json: schema: type: array items: $ref: "#/components/schemas/Session" description: Single session if non-recurring, or multiple sessions if recurring "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" /sessions/{id}: get: summary: Get session by ID description: Retrieve a specific therapy session by its UUID tags: [Sessions] parameters: - name: id in: path required: true description: UUID of the Session to retrieve schema: type: string format: uuid example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Session found successfully content: application/json: schema: $ref: "#/components/schemas/Session" "400": description: Bad Request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Session not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update session description: Update an existing session (partial update) tags: [Sessions] parameters: - name: id in: path required: true description: UUID of the Session to patch schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateSessionInput" responses: "200": description: Session updated successfully content: application/json: schema: $ref: "#/components/schemas/Session" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session Not Found content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete session description: Delete a session from the database tags: [Sessions] parameters: - name: id in: path required: true description: UUID of the Session to delete schema: type: string format: uuid responses: "200": description: Session deleted successfully content: application/json: schema: type: object properties: message: type: string example: "Session deleted successfully" "400": description: Bad Request Error (parsing invalid uuid, etc.) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session not found content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /sessions/{id}/resources: get: summary: Get resources for a session description: Retrieve all resources associated with a specific session tags: [Sessions] parameters: - name: id in: path required: true description: UUID of the Session to retrieve resources for schema: type: string format: uuid example: "123e4567-e89b-12d3-a456-426614174000" - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: List of resources associated with the session content: application/json: schema: type: array items: $ref: "#/components/schemas/Resource" "400": description: Bad Request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Session not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /sessions/{session_id}/students: get: summary: Get all students for a session description: Retrieve all students associated with a specific session, including bridge table information tags: [Sessions] parameters: - name: session_id in: path required: true description: UUID of the session schema: type: string format: uuid example: "123e4567-e89b-12d3-a456-426614174000" - name: present in: query required: false description: Filter students by attendance status schema: type: boolean - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 - name: therapist_id in: query description: Filter students by therapist UUID schema: type: string format: uuid example: "550e8400-e29b-41d4-a716-446655440000" responses: "200": description: List of students with session relationship details content: application/json: schema: type: array items: $ref: "#/components/schemas/StudentWithSessionInfo" "400": description: Bad request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Session not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /sessions/{id}/recurring: delete: summary: Delete recurring session group description: Delete all the future sessions in the recurring group that share the same parent session ID. This will not delete past sessions that have already occurred. tags: [Sessions] parameters: - name: id in: path required: true description: UUID of the parent Session to delete (with all recurring instances) schema: type: string format: uuid example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Recurring sessions deleted successfully content: application/json: schema: type: object properties: message: type: string example: "Sessions deleted successfully" "400": description: Bad Request Error (invalid UUID) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session not found content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /districts: get: summary: Get all districts description: Retrieve all districts from the system tags: [Districts] responses: "200": description: List of districts content: application/json: schema: type: array items: $ref: "#/components/schemas/District" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /districts/{id}: get: summary: Get district by ID description: Retrieve a district by its numeric ID tags: [Districts] parameters: - name: id in: path required: true description: Numeric district ID schema: type: integer example: 3 responses: "200": description: District found successfully content: application/json: schema: $ref: "#/components/schemas/District" "400": description: Invalid district ID (non-integer) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid district ID" "404": description: District not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "District not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /schools: get: summary: Get schools description: Retrieve all schools, or filter by district using the `district_id` query parameter. tags: [Schools] parameters: - name: district_id in: query required: false description: Filter schools by district ID schema: type: integer example: 4 responses: "200": description: List of schools content: application/json: schema: type: array items: $ref: "#/components/schemas/School" "400": description: Invalid district ID content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid district ID" "500": description: Failed to fetch schools content: application/json: schema: $ref: "#/components/schemas/Error" /students: get: summary: Get all students description: Retrieve a paginated list of students with optional filtering by grade, therapist, and name tags: - Students parameters: - name: page in: query description: Page number for pagination (starts at 1) required: false schema: type: integer minimum: 1 default: 1 example: 1 - name: limit in: query description: Number of students per page required: false schema: type: integer minimum: 1 maximum: 100 default: 10 example: 10 - name: grade in: query description: Filter students by grade level (exact match). -1 = graduated, 0 = kindergarten, 1-12 = grades 1-12 required: false schema: type: integer minimum: -1 maximum: 12 example: 5 - name: therapist_id in: query description: Filter students by therapist UUID required: false schema: type: string format: uuid example: "9dad94d8-6534-4510-90d7-e4e97c175a65" - name: school_id in: query description: Filter students by school ID required: false schema: type: integer example: 2 - name: name in: query description: Search students by name (case-insensitive, matches first or last name) required: false schema: type: string example: "John" responses: "200": description: Successful response with list of students content: application/json: schema: type: array items: $ref: "#/components/schemas/Student" examples: allStudents: summary: All students (no filters) value: - id: "843d4807-1397-4227-9328-330adea56993" first_name: "John" last_name: "Doe" dob: "2010-05-15T00:00:00Z" therapist_id: "9dad94d8-6534-4510-90d7-e4e97c175a65" school_id: 2 district_id: 1 school_name: "Generate Elementary" grade: 5 iep: [ "Active IEP with speech therapy goals", "Occupational therapy accommodations", ] created_at: "2025-09-18T14:14:11.66268Z" updated_at: "2025-09-18T14:14:11.66268Z" filteredByGrade: summary: Filtered by grade value: - id: "843d4807-1397-4227-9328-330adea56993" first_name: "John" last_name: "Doe" grade: 5 therapist_id: "9dad94d8-6534-4510-90d7-e4e97c175a65" emptyResults: summary: No matching results value: [] "400": description: Bad request - Invalid query parameters content: application/json: schema: $ref: "#/components/schemas/Error" examples: invalidTherapistId: summary: Invalid therapist_id format value: code: 400 message: therapistid: "TherapistID is invalid" invalidPagination: summary: Invalid pagination values value: code: 400 message: page: "Page must be greater than or equal to 1" limit: "Limit must be greater than or equal to 1" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" post: summary: Create a new student description: Create a new student record tags: [Students] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateStudentInput" responses: "201": description: Student created successfully content: application/json: schema: $ref: "#/components/schemas/Student" "400": description: Bad request (validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" examples: invalid_json: summary: Invalid JSON format value: code: 400 message: "Invalid JSON format" invalid_date: summary: Invalid date format value: code: 400 message: "Invalid date format. Use YYYY-MM-DD" invalid_therapist_id: summary: Invalid therapist ID value: code: 400 message: "Invalid therapist ID format" "422": description: Therapist not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 422 message: "Therapist not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /students/{id}: get: summary: Get student by ID description: Retrieve a specific student by their ID tags: [Students] parameters: - name: id in: path required: true schema: type: string format: uuid description: Student ID example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Student found content: application/json: schema: $ref: "#/components/schemas/Student" "400": description: Invalid UUID format content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Student not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update student description: Update an existing student's information (partial update) tags: [Students] parameters: - name: id in: path required: true schema: type: string format: uuid description: Student ID example: "123e4567-e89b-12d3-a456-426614174000" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateStudentInput" responses: "200": description: Student updated successfully content: application/json: schema: $ref: "#/components/schemas/Student" "400": description: Bad request (validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" examples: invalid_uuid: summary: Invalid UUID format value: code: 400 message: "Invalid UUID format" invalid_json: summary: Invalid JSON format value: code: 400 message: "Invalid JSON format" invalid_date: summary: Invalid date format value: code: 400 message: "Invalid date format. Use YYYY-MM-DD" "404": description: Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Student not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete student description: Delete a student record tags: [Students] parameters: - name: id in: path required: true schema: type: string format: uuid description: Student ID example: "123e4567-e89b-12d3-a456-426614174000" responses: "204": description: Student deleted successfully (no content) "400": description: Invalid UUID format content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Student not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /students/{student_id}/sessions: get: summary: Get all sessions for a student description: | Retrieve all sessions associated with a specific student, including bridge table information. **Date Filtering Options:** - Use `startDate` and `endDate` for date range filtering: `?startDate=2025-09-01&endDate=2025-09-30` - Use `month` and `year` for monthly filtering: `?month=9&year=2025` - Use `year` alone for yearly filtering: `?year=2025` **Attendance Filtering:** - Use `present` to filter by attendance: `?present=true` or `?present=false` **Combining Filters:** All filters can be combined: `?month=9&year=2025&present=true` tags: [Students] parameters: - name: student_id in: path required: true description: UUID of the student schema: type: string format: uuid example: "987fcdeb-51a2-43d1-9f4c-123456789abc" - name: startDate in: query required: false description: Filter sessions starting after this date (YYYY-MM-DD format) schema: type: string format: date example: "2025-09-01" - name: endDate in: query required: false description: Filter sessions ending before this date (YYYY-MM-DD format) schema: type: string format: date example: "2025-09-30" - name: month in: query required: false description: Filter sessions by month (1-12). Can be combined with year parameter. schema: type: integer minimum: 1 maximum: 12 example: 9 - name: year in: query required: false description: Filter sessions by year. Can be combined with month parameter or used alone. schema: type: integer minimum: 1776 maximum: 2200 example: 2025 - name: present in: query required: false description: Filter sessions by student's attendance status schema: type: boolean example: true - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: List of sessions with student relationship details content: application/json: schema: type: array items: $ref: "#/components/schemas/SessionWithStudentInfo" "400": description: Bad request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Student not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /students/{student_id}/ratings: get: summary: Get ratings for a student description: Retrieve all session ratings for a specific student tags: [Students] parameters: - name: student_id in: path required: true description: UUID of the student schema: type: string format: uuid example: "0711034b-18b9-4f41-9b61-467ce9a373d5" - name: category in: query required: false description: Filter ratings by category schema: type: string enum: ["visual_cue", "verbal_cue", "gestural_cue", "engagement"] - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: List of session ratings for the student content: application/json: schema: type: array items: $ref: "#/components/schemas/StudentRatingEntry" "400": description: Bad request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Student not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /students/{student_id}/attendance: get: summary: Get attendance records for a student description: Retrieve all attendance records for a specific student tags: [Students] parameters: - name: student_id in: path required: true description: UUID of the student schema: type: string format: uuid example: "0711034b-18b9-4f41-9b61-467ce9a373d5" - name: date_from in: query required: false description: Filter attendance records on or after this date (YYYY-MM-DD format), default is no lower limit schema: type: string format: date example: "2025-09-01" - name: date_to in: query required: false description: Filter attendance records on or before this date (YYYY-MM-DD format), default to today schema: type: string format: date example: "2025-11-14" responses: "200": description: List of attendance records for the student content: application/json: schema: $ref: "#/components/schemas/AttendanceRecord" "400": description: Bad request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /students/promote: patch: summary: Promotes all of a therapist's students description: Promotes all of a therapist's students other than the ones that are not moving up. tags: [Students] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PromoteStudentsInput" responses: "200": description: Patch Done Successfully content: application/json: schema: type: object properties: message: type: string example: "Successfully Promoted Students!" "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" /session_students: post: summary: Create session-student relationship description: Associate each given student with each given session, creating an entry in the bridge table tags: [Session Students] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateSessionStudentInput" responses: "201": description: Session-student relationship created successfully content: application/json: schema: type: array items: $ref: "#/components/schemas/SessionStudent" description: The Session-Student relationships that were created successfully "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session or Student not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session or Student not found" "409": description: Relationship already exists content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 409 message: "Student is already associated with this session" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete session-student relationship description: Remove the association between a student and a session tags: [Session Students] requestBody: required: true content: application/json: schema: type: object required: - session_id - student_id properties: session_id: type: string format: uuid description: UUID of the session example: "123e4567-e89b-12d3-a456-426614174000" student_id: type: string format: uuid description: UUID of the student example: "987fcdeb-51a2-43d1-9f4c-123456789abc" responses: "204": description: Session-student relationship deleted successfully (no content) "400": description: Bad request (e.g., invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session-student relationship not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session-student relationship not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update or rate session for a student description: Update the rating for a specific category in a session-student relationship tags: [Session Students] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateSessionStudentInput" responses: "200": description: Session rated successfully content: application/json: schema: $ref: "#/components/schemas/SessionStudentWithRatings" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Session-student relationship not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session-student relationship not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /therapists: get: summary: Get all therapists description: Retrieve all therapists from the database tags: [Therapists] parameters: - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: A list of Therapists content: application/json: schema: type: array items: $ref: "#/components/schemas/Therapist" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Resource not found" post: summary: Create a new therapist description: Create a new therapist for school districts tags: [Therapists] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateTherapistInput" responses: "201": description: Therapist created successfully content: application/json: schema: $ref: "#/components/schemas/Therapist" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /therapists/{id}: get: summary: Get therapist by ID description: Retrieve a specific therapist from the database tags: [Therapists] parameters: - name: id in: path required: true schema: type: string format: uuid description: Therapist ID example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Therapist found content: application/json: schema: $ref: "#/components/schemas/Therapist" "400": description: Invalid UUID format content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "There was an error parsing the given id!" "404": description: Therapist not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Therapist not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update therapist description: Update a specific field within a therapist object in the database tags: [Therapists] parameters: - name: id in: path required: true schema: type: string format: uuid description: Therapist ID example: "123e4567-e89b-12d3-a456-426614174000" requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateTherapistInput" responses: "200": description: Therapist updated successfully content: application/json: schema: $ref: "#/components/schemas/Therapist" "400": description: Bad request (validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "There was an error parsing the given id!" "404": description: Therapist not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Therapist not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete therapist description: Get the specific therapist corresponding to the given ID and delete it tags: [Therapists] parameters: - name: id in: path required: true schema: type: string format: uuid description: Therapist ID example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Therapist deleted successfully content: application/json: schema: type: object properties: message: type: string example: "Therapist deleted successfully" "400": description: Invalid UUID format content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Error querying database for given ID" "404": description: Therapist not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Therapist not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /resources: get: summary: Get all resources description: Retrieve all resources from the database tags: [Resources] parameters: - in: query name: theme_id schema: type: string format: uuid required: false description: Filter resources by theme ID - in: query name: grade_level schema: type: integer minimum: 0 maximum: 12 required: false description: Filter resources by grade level. 0 = kindergarten, 1-12 = grades 1-12 - in: query name: date schema: type: string format: date required: false description: Filter resources by date - in: query name: type schema: type: string required: false description: Filter resources by type - in: query name: title schema: type: string required: false description: Filter resources by title - in: query name: category schema: type: string required: false description: Filter resources by category - in: query name: content schema: type: string required: false description: Filter resources by content/URL - in: query name: theme_name schema: type: string required: false description: Filter resources by theme name - in: query name: theme_month schema: type: integer required: false description: Filter resources by theme month - in: query name: theme_year schema: type: integer required: false description: Filter resources by theme year - in: query name: week schema: type: integer minimum: 1 maximum: 4 required: false description: Filter resources by week (1-4) - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: List of resources content: application/json: schema: type: array items: $ref: "#/components/schemas/ResourceWithPresignURL" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Resource not found" post: summary: Create a new resource description: Create a new resource in the database tags: [Resources] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateResourceBody" responses: "201": description: Resource created successfully content: application/json: schema: $ref: "#/components/schemas/Resource" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Not found (e.g. theme_id does not exist) content: application/json: schema: $ref: "#/components/schemas/Error" /resources/{id}: get: summary: Get resource by ID description: Retrieve a specific resource by its ID tags: [Resources] parameters: - in: path name: id schema: type: string format: uuid required: true description: ID of the resource to retrieve responses: "200": description: Resource found successfully content: application/json: schema: $ref: "#/components/schemas/ResourceWithPresignURL" "400": description: Bad request (e.g., invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Resource not found content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update a resource description: Update an existing resource in the database tags: [Resources] parameters: - in: path name: id schema: type: string format: uuid required: true description: ID of the resource to update requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateResourceBody" responses: "200": description: Resource updated successfully content: application/json: schema: $ref: "#/components/schemas/Resource" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Resource not found content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete a resource description: Delete an existing resource from the database tags: [Resources] parameters: - in: path name: id schema: type: string format: uuid required: true description: ID of the resource to delete responses: "204": description: Resource deleted successfully (no content) "404": description: Resource not found content: application/json: schema: $ref: "#/components/schemas/Error" /session-resource: post: summary: Create a session-resource link description: Create a new association between each session and a utilized resource tags: [SessionResource] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ModifySessionResource" example: session_id: "123e4567-e89b-12d3-a456-426614174001" resource_id: "123e4567-e89b-12d3-a456-426614174002" responses: "200": description: Session-resource link created successfully content: application/json: schema: $ref: "#/components/schemas/SessionResource" example: session_id: "123e4567-e89b-12d3-a456-426614174001" resource_id: "123e4567-e89b-12d3-a456-426614174002" created_at: "2025-09-13T17:19:00Z" updated_at: "2025-09-13T17:19:00Z" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Reference not found" "404": description: Session or Resource not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session or Resource not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete a session-resource link description: Delete an existing association between a session and a resource tags: [SessionResource] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/ModifySessionResource" example: session_id: "123e4567-e89b-12d3-a456-426614174001" resource_id: "123e4567-e89b-12d3-a456-426614174002" responses: "204": description: Session-resource link deleted successfully (no content) "404": description: Session-resource link not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Session or Resource not found" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Reference not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /themes: get: summary: Get all themes description: Retrieve all themes from the database with optional filtering by month, year, and name search tags: [Themes] parameters: - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 - name: month in: query description: Filter themes by month (1-12) required: false schema: type: integer minimum: 1 maximum: 12 example: 3 - name: year in: query description: Filter themes by year required: false schema: type: integer minimum: 1900 maximum: 2100 example: 2024 - name: search in: query description: Search themes by name (case-insensitive, partial matching) required: false schema: type: string maxLength: 255 example: "spring" responses: "200": description: List of themes (filtered and paginated based on query parameters) content: application/json: schema: type: array items: $ref: "#/components/schemas/Theme" examples: all_themes: summary: Get all themes with pagination value: - id: "123e4567-e89b-12d3-a456-426614174000" name: "Spring Activities" month: 3 year: 2024 created_at: "2024-01-15T10:30:00Z" updated_at: "2024-01-15T10:35:00Z" filtered_themes: summary: Get spring themes for 2024 description: Example response for GET /themes?month=3&year=2024&search=spring value: - id: "123e4567-e89b-12d3-a456-426614174000" name: "Spring Activities" month: 3 year: 2024 created_at: "2024-01-15T10:30:00Z" updated_at: "2024-01-15T10:35:00Z" "400": description: Bad request (e.g., invalid filter parameters) content: application/json: schema: $ref: "#/components/schemas/Error" examples: invalid_month: summary: Invalid month parameter value: code: 400 message: month: "Month must be less than or equal to 12" invalid_year: summary: Invalid year parameter value: code: 400 message: year: "Year must be greater than or equal to 1900" invalid_pagination: summary: Invalid pagination parameters value: code: 400 message: "Invalid Pagination Query Parameters" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" post: summary: Create a new theme description: Create a new theme for therapy sessions tags: [Themes] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/CreateThemeInput" responses: "201": description: Theme created successfully content: application/json: schema: $ref: "#/components/schemas/Theme" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /themes/{id}: get: summary: Get theme by ID description: Retrieve a specific theme by its UUID tags: [Themes] parameters: - name: id in: path required: true description: UUID of the theme to retrieve schema: type: string format: uuid example: "123e4567-e89b-12d3-a456-426614174000" responses: "200": description: Theme found successfully content: application/json: schema: $ref: "#/components/schemas/Theme" "400": description: Bad Request (invalid UUID format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid UUID format" "404": description: Theme not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "Theme not found" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" patch: summary: Update theme description: Update an existing theme (partial update) tags: [Themes] parameters: - name: id in: path required: true description: UUID of the theme to patch schema: type: string format: uuid requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/UpdateThemeInput" responses: "200": description: Theme updated successfully content: application/json: schema: $ref: "#/components/schemas/Theme" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Theme not found content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" delete: summary: Delete theme description: Delete a theme from the database tags: [Themes] parameters: - name: id in: path required: true description: UUID of the theme to delete schema: type: string format: uuid responses: "200": description: Theme deleted successfully content: application/json: schema: type: object properties: message: type: string example: "Theme deleted successfully" "400": description: Bad Request Error (parsing invalid uuid, etc.) content: application/json: schema: $ref: "#/components/schemas/Error" "404": description: Theme not found content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /newsletter/by-date: get: summary: Get newsletter by date description: Retrieve a newsletter for a specific date and generate a presigned URL to access it from S3 tags: [Newsletter] parameters: - name: date in: query required: true description: The date to retrieve the newsletter for (YYYY-MM-DD format) schema: type: string format: date example: "2025-01-15" responses: "200": description: Newsletter found and presigned URL generated successfully content: application/json: schema: type: object required: - s3_url properties: s3_url: type: string format: url description: Presigned URL to access the newsletter from S3 (valid for 1 hour) example: "https://bucket.s3.us-west-2.amazonaws.com/newsletter/2025-01-15.pdf?X-Amz-Algorithm=AWS4-HMAC-SHA256&X-Amz-Credential=..." "400": description: Bad Request (missing or invalid date parameter) content: application/json: schema: $ref: "#/components/schemas/Error" examples: missing_date: summary: Missing date query parameter value: code: 400 message: "Missing date query parameter" invalid_date_format: summary: Invalid date format value: code: 400 message: "Invalid date format, use YYYY-MM-DD" "404": description: Newsletter not found for the specified date content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "No newsletter found for this date" "500": description: Internal server error (failed to generate presigned URL) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Failed to generate presigned URL" /game-contents: get: summary: Get Game Contents description: Get all Game Contents for given category and level with a certain number of words tags: [GameContent] parameters: - name: theme_id in: query description: Theme ID associated with the game's contents schema: type: string format: uuid - name: category in: query description: The category associated with the game schema: type: string enum: [ receptive_language, expressive_language, social_pragmatic_language, speech, ] - name: question_type in: query description: The type of question being asked in the game schema: type: string enum: [ sequencing, following_directions, wh_questions, true_false, concepts_sorting, fill_in_the_blank, categorical_language, emotions, teamwork_talk, express_excitement_interest, fluency, articulation_s, articulation_l, ] - name: difficulty_level in: query description: The difficulty level of the game schema: type: integer minimum: 1 - name: question_count in: query description: Refers to the number of questions that should be returned through sampling schema: type: integer minimum: 2 - name: words_count in: query description: The number of words that need to be retrieved as correct answer and wrong options schema: type: integer minimum: 2 - name: exercise_type in: query description: The type of exercise for which content is being requested (game or pdf) schema: type: string enum: [game, pdf] - name: applicable_game_types in: query description: The applicable game types for which content is being requested schema: type: array items: type: string enum: [drag and drop, spinner, word/image matching, flashcards, multi-match] responses: "200": description: The Game Content (corresponding category and level) content: application/json: schema: type: array items: $ref: "#/components/schemas/GameContent" "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Bad Request" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Internal Server Error" /game-results: get: summary: Gets the Game Results description: Gets the Game Results that were asked for..? Filter available by session and student. tags: [GameResult] parameters: - name: session_id in: query description: The SessionID of the session whose game results you seek schema: type: string format: uuid - name: student_id in: query description: The StudentID of the student whose game results you seek schema: type: string format: uuid - name: category in: query description: The category of the game results you seek schema: type: string enum: [ receptive_language, expressive_language, social_pragmatic_language, speech, ] - name: question_type in: query description: The question type of the game results you seek schema: type: string enum: [ sequencing, following_directions, wh_questions, true_false, concepts_sorting, fill_in_the_blank, categorical_language, emotions, teamwork_talk, express_excitement_interest, fluency, articulation_s, articulation_l, ] - name: difficulty_level in: query description: The difficulty level of the game results you seek schema: type: integer minimum: 1 - name: exercise_type in: query description: The exercise type of the game results you seek schema: type: string enum: [ game, pdf, ] - name: game_type in: query description: The game type of the game results you seek schema: type: string enum: [ drag and drop, spinner, word/image matching, flashcards, ] - name: date_from in: query description: Start date to filter game results (inclusive) schema: type: string format: date-time - name: date_to in: query description: End date to filter game results (inclusive) schema: type: string format: date-time - name: page in: query description: Page Number of pagination schema: type: integer minimum: 1 - name: limit in: query description: Number of Items per page in pagination schema: type: integer minimum: 1 responses: "200": description: The Game Results you requested content: application/json: schema: type: array items: $ref: "#/components/schemas/GameResult" "400": description: Bad Request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Bad Request" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Internal Server Error" post: summary: Creates a new game result description: Creates a new result entry for a game result tags: [GameResult] requestBody: required: true content: application/json: schema: $ref: "#/components/schemas/PostGameResultInput" responses: "201": description: Game Result created successfully content: application/json: schema: $ref: "#/components/schemas/GameResult" "400": description: Bad request (e.g., validation errors) content: application/json: schema: $ref: "#/components/schemas/Error" "500": description: Internal server error content: application/json: schema: $ref: "#/components/schemas/Error" /verification/send-code: post: summary: Send Verification Code description: Initiates MFA setup or verification by sending a code to the user. For TOTP-based MFA (Google Authenticator), returns a QR code and secret. tags: [Verification] requestBody: required: true content: application/json: schema: type: object required: - user_id properties: user_id: type: string format: uuid description: The UUID of the user requesting verification example: "f20e5948-01ba-4113-b453-db05d8bde3bc" method: type: string enum: [totp, email, sms] description: Verification method (defaults to totp for Google Authenticator) example: "totp" responses: "200": description: Verification code sent successfully content: application/json: schema: type: object properties: message: type: string example: "Verification code sent successfully" qr_code: type: string description: Base64-encoded QR code image for TOTP setup (only for totp method) example: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." secret: type: string description: TOTP secret key for manual entry (only for totp method) example: "JBSWY3DPEHPK3PXP" backup_codes: type: array items: type: string description: One-time backup codes for account recovery example: ["ABCD-1234", "EFGH-5678", "IJKL-9012"] "400": description: Bad Request (e.g., invalid user_id or method) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid user ID format" "404": description: User not found content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "User not found" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Failed to generate verification code" security: - cookieAuth: [] /verification/verify: post: summary: Verify Code description: Verifies a code provided by the user (from Google Authenticator or other method) tags: [Verification] requestBody: required: true content: application/json: schema: type: object required: - user_id - code properties: user_id: type: string format: uuid description: The UUID of the user being verified example: "f20e5948-01ba-4113-b453-db05d8bde3bc" code: type: string description: The 6-digit verification code from Google Authenticator example: "123456" pattern: '^\d{6}$' responses: "200": description: Code verified successfully content: application/json: schema: type: object properties: message: type: string example: "Verification successful" verified: type: boolean example: true mfa_enabled: type: boolean description: Indicates if MFA is now enabled for this user example: true "400": description: Bad Request (e.g., invalid code format) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid verification code format" "401": description: Unauthorized (invalid or expired code) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 401 message: "Invalid or expired verification code" "404": description: User not found or no pending verification content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "No pending verification found for user" "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Verification failed" security: - cookieAuth: [] /verification/resend: post: summary: Resend Verification Code description: Resends a verification code to the user (useful if the original code was lost or expired) tags: [Verification] requestBody: required: true content: application/json: schema: type: object required: - user_id properties: user_id: type: string format: uuid description: The UUID of the user requesting code resend example: "f20e5948-01ba-4113-b453-db05d8bde3bc" method: type: string enum: [totp, email, sms] description: Verification method to use for resending example: "totp" responses: "200": description: Verification code resent successfully content: application/json: schema: type: object properties: message: type: string example: "Verification code resent successfully" qr_code: type: string description: Base64-encoded QR code image (only for totp method) example: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." secret: type: string description: TOTP secret key (only for totp method) example: "JBSWY3DPEHPK3PXP" "400": description: Bad Request (e.g., invalid user_id) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 400 message: "Invalid request parameters" "404": description: User not found or no verification session exists content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 404 message: "No active verification session found" "429": description: Too Many Requests (rate limit exceeded) content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 429 message: "Too many resend attempts. Please try again later." "500": description: Internal Server Error content: application/json: schema: $ref: "#/components/schemas/Error" example: code: 500 message: "Failed to resend verification code" security: - cookieAuth: [] components: schemas: Error: type: object required: - code - message properties: code: type: integer description: HTTP status code example: 500 message: anyOf: - type: string - type: object description: Error message or validation errors example: "Internal server error" Therapist: type: object required: - id - first_name - last_name - email - active - created_at - updated_at properties: id: type: string format: uuid description: Unique identifier for the therapist example: "123e4567-e89b-12d3-a456-426614174000" first_name: type: string example: "Kevin" last_name: type: string example: "Matilda" email: type: string format: email example: "email123@example.com" schools: type: array items: type: integer description: List of school IDs associated with the therapist example: [1, 2] district_id: type: integer description: School district ID the therapist belongs to example: 2 school_names: type: array items: type: string description: List of school names associated with the therapist example: ["Generate High", "Sherman Center for Academic Excellence"] district_name: type: string description: Name of the school district the therapist belongs to example: "Generate Public Schools" active: type: boolean description: Whether the therapist is currently active example: true created_at: type: string format: date-time example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time example: "2024-01-15T10:35:00Z" CreateTherapistInput: type: object required: - id - first_name - last_name - email - district_id properties: id: type: string format: uuid description: Unique identifier for the therapist example: "123e4567-e89b-12d3-a456-426614174000" first_name: type: string description: First name of the therapist example: "Kevin" last_name: type: string description: Last name of the therapist example: "Matilda" schools: type: array items: type: integer description: List of school IDs associated with the therapist example: [1, 2] district_id: type: integer description: School district ID the therapist belongs to example: 2 email: type: string format: email description: Email of the therapist example: "email123@example.com" UpdateTherapistInput: type: object properties: first_name: type: string description: First name of the therapist example: "Kevin" last_name: type: string description: Last name of the therapist example: "Matilda" schools: type: array items: type: integer description: List of school IDs associated with the therapist example: [1, 2] district_id: type: integer description: School district ID the therapist belongs to example: 2 email: type: string format: email description: Email of the therapist example: "email123@example.com" active: type: boolean description: Whether the therapist is active example: true District: type: object properties: id: type: integer example: 3 name: type: string example: "Central District" created_at: type: string format: date-time example: "2025-01-15T14:30:00Z" updated_at: type: string format: date-time example: "2025-01-15T14:30:00Z" School: type: object properties: id: type: integer example: 12 name: type: string example: "Lincoln Middle School" district_id: type: integer example: 4 created_at: type: string format: date-time example: "2025-01-15T14:30:00Z" updated_at: type: string format: date-time example: "2025-01-15T14:30:00Z" Session: type: object required: - id - session_name - start_datetime - end_datetime - therapist_id - session_parent_id properties: id: type: string format: uuid description: Unique identifier for the session example: "123e4567-e89b-12d3-a456-426614174000" session_name: type: string description: Name of the Session example: "Fluency work with Florence" start_datetime: type: string format: date-time description: Start date and time of the session example: "2024-01-15T14:30:00Z" end_datetime: type: string format: date-time description: End date and time of the session example: "2024-01-15T15:30:00Z" therapist_id: type: string format: uuid description: ID of the therapist conducting the session example: "987fcdeb-51a2-43d1-9f4c-123456789abc" session_parent_id: type: string format: uuid description: UUID of the parent session (for recurring sessions) example: "123e4567-e89b-12d3-a456-426614174000" notes: type: string nullable: true description: Session notes (optional) example: "Patient showed improvement in anxiety management techniques" location: type: string nullable: true description: Session location (optional) example: "To the land where the honey runs..." created_at: type: string format: date-time nullable: true description: When the session record was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time nullable: true description: When the session record was last updated example: "2024-01-15T10:35:00Z" repetition: $ref: "#/components/schemas/Repetition" nullable: true description: Repetition details for recurring sessions CreateSessionInput: type: object required: - session_name - start_datetime - end_datetime - therapist_id properties: session_name: type: string example: "Grammar say what?!" start_datetime: type: string format: date-time example: "2025-09-13T17:19:00Z" end_datetime: type: string format: date-time example: "2025-09-13T18:00:00Z" therapist_id: type: string format: uuid example: "3fa85f64-5717-4562-b3fc-2c963f66afa6" notes: type: string nullable: true location: type: string nullable: true repetition: $ref: "#/components/schemas/Repetition" nullable: true student_ids: type: array items: type: string format: uuid nullable: true UpdateSessionInput: type: object properties: session_name: type: string description: Name of the Session example: "Fluency Work with Florence" start_datetime: type: string format: date-time description: Start date and time of the session example: "2025-09-13T17:19:00Z" end_datetime: type: string format: date-time description: End date and time of the session example: "2025-09-13T18:00:00Z" therapist_id: type: string format: uuid description: UUID of the Therapist example: "3fa85f64-5717-4562-b3fc-2c963f66afa6" notes: type: string description: Optional notes about the session example: "Updated session notes" location: type: string description: Optional location information about the session example: "2nd Floor of the School" Student: type: object required: - id - first_name - last_name - therapist_id - school_id - created_at - updated_at properties: id: type: string format: uuid description: Unique identifier for the student example: "843d4807-1397-4227-9328-330adea56993" first_name: type: string description: Student's first name example: "John" last_name: type: string description: Student's last name example: "Doe" dob: type: string format: date-time description: Student's date of birth example: "2010-05-15T00:00:00Z" therapist_id: type: string format: uuid description: UUID of the assigned therapist example: "9dad94d8-6534-4510-90d7-e4e97c175a65" school_id: type: integer description: ID of the school the student attends example: 3 school_name: type: string nullable: true description: Name of the school the student attends example: "Generate High" district_id: type: integer nullable: true description: ID of the school district the student belongs to example: 2 grade: type: integer nullable: true description: Student's current grade level. -1 = graduated, 0 = kindergarten, 1-12 = grades 1-12 minimum: -1 maximum: 12 example: 5 iep: type: array items: type: string nullable: true description: List of Individualized Education Program goals example: [ "Active IEP with speech therapy goals", "Occupational therapy accommodations", ] created_at: type: string format: date-time description: Timestamp when the student record was created example: "2025-09-18T14:14:11.66268Z" updated_at: type: string format: date-time description: Timestamp when the student record was last updated example: "2025-09-18T14:14:11.66268Z" CreateStudentInput: type: object required: - first_name - last_name - therapist_id - school_id properties: first_name: type: string description: Student's first name example: "John" last_name: type: string description: Student's last name example: "Doe" dob: type: string format: date nullable: true description: Student's date of birth (YYYY-MM-DD format, optional) example: "2010-05-15" school_id: type: integer description: ID of the school the student attends example: 3 therapist_id: type: string format: uuid description: ID of the assigned therapist example: "987fcdeb-51a2-43d1-9f4c-123456789abc" grade: type: integer nullable: true description: Student's current grade level (optional). -1 = graduated, 0 = kindergarten, 1-12 = grades 1-12 minimum: -1 maximum: 12 example: 5 iep: type: array items: type: string nullable: true description: List of Individualized Education Program goals (optional) example: [ "Active IEP with speech therapy goals", "Occupational therapy accommodations", ] Repetition: type: object required: - recur_start - recur_end - every_n_weeks - days # ADD THIS properties: recur_start: type: string format: date-time description: Starting Date of Recurring Session example: "2025-09-13T17:19:00Z" recur_end: type: string format: date-time description: Ending Date of Recurring Session example: "2025-11-13T17:19:00Z" every_n_weeks: type: integer format: positive description: Recurring Session will happen every "N" weeks example: 2 days: # ADD THIS FIELD type: array items: type: integer minimum: 0 maximum: 6 description: Days of week for recurrence (0=Sunday, 1=Monday, ..., 6=Saturday) example: [1, 3, 5] UpdateStudentInput: type: object description: Fields that can be updated (all optional for partial updates) properties: first_name: type: string description: Student's first name example: "John" last_name: type: string description: Student's last name example: "Doe" dob: type: string format: date nullable: true description: Student's date of birth (YYYY-MM-DD format, can be set to null) example: "2010-05-15" therapist_id: type: string format: uuid description: ID of the assigned therapist example: "987fcdeb-51a2-43d1-9f4c-123456789abc" grade: type: integer nullable: true description: Student's current grade level (can be set to null). -1 = graduated, 0 = kindergarten, 1-12 = grades 1-12 minimum: -1 maximum: 12 example: 6 iep: type: array items: type: string nullable: true description: Updated list of IEP goals (can be set to null or empty array) example: [ "Updated IEP with advanced speech therapy goals", "Reading comprehension support", ] Theme: type: object required: - id - name - month - year - created_at - updated_at properties: id: type: string format: uuid description: Unique identifier for the theme example: "123e4567-e89b-12d3-a456-426614174000" name: type: string description: Name of the theme example: "Winter Wonderland" month: type: integer description: Month of the theme (1-12) example: 12 year: type: integer description: Year of the theme (e.g., 2024) example: 2024 created_at: type: string format: date-time description: When the theme was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: When the theme was last updated example: "2024-01-15T10:35:00Z" CreateThemeInput: type: object required: - name - month - year properties: name: type: string description: Name of the theme example: "Winter Wonderland" month: type: integer description: Month of the theme example: 12 year: type: integer description: Year of the theme example: 2024 UpdateThemeInput: type: object description: Fields that can be updated (all optional for partial updates) properties: name: type: string description: Name of the theme example: "Spring Blossoms" month: type: integer description: Month of the theme (1-12) example: 3 year: type: integer description: Year of the theme example: 2024 ThemeInfo: type: object required: - theme_name - month - year properties: theme_name: type: string description: Name of the theme example: "Jungle Adventure" theme_month: type: integer description: Month of the theme (1-12) example: 6 theme_year: type: integer description: Year of the theme example: 2024 created_at: type: string format: date-time description: When the theme was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: When the theme was last updated example: "2024-01-15T10:35:00Z" CreateResourceBody: type: object required: - theme_id properties: theme_id: type: string format: uuid description: ID of the theme associated with the resource example: "123e4567-e89b-12d3-a456-426614174000" grade_level: type: integer nullable: true description: Grade level for the resource (optional). 0 = kindergarten, 1-12 = grades 1-12 minimum: 0 maximum: 12 date: type: string format: date nullable: true description: Date associated with the resource (optional) type: type: string nullable: true description: Type of resource (optional) title: type: string nullable: true description: Title of the resource (optional) category: type: string nullable: true description: Category of the resource (optional) content: type: string nullable: true description: Content/URL of the resource (optional) Resource: type: object required: - id - theme_id properties: id: type: string format: uuid description: Unique identifier for the resource example: "123e4567-e89b-12d3-a456-426614174000" theme_id: type: string format: uuid description: ID of the theme associated with the resource example: "123e4567-e89b-12d3-a456-426614174000" grade_level: type: integer nullable: true description: Grade level for the resource (optional). 0 = kindergarten, 1-12 = grades 1-12 minimum: 0 maximum: 12 example: 5 week: type: integer nullable: true description: Week associated with the resource (optional) example: 2 type: type: string nullable: true description: Type of resource (optional) title: type: string nullable: true description: Title of the resource (optional) example: "Reading Exercises: b vs d" category: type: string nullable: true description: Category of the resource (optional) content: type: string nullable: true description: Content/URL of the resource (optional) example: "https://example.com/resource" theme: $ref: "#/components/schemas/ThemeInfo" description: The theme associated with the resource ResourceWithPresignURL: type: object required: - id - theme_id properties: id: type: string format: uuid description: Unique identifier for the resource example: "123e4567-e89b-12d3-a456-426614174000" theme_id: type: string format: uuid description: ID of the theme associated with the resource example: "123e4567-e89b-12d3-a456-426614174000" grade_level: type: integer nullable: true description: Grade level for the resource (optional). 0 = kindergarten, 1-12 = grades 1-12 minimum: 0 maximum: 12 example: 5 week: type: integer nullable: true description: Week associated with the resource (optional) example: 2 type: type: string nullable: true description: Type of resource (optional) title: type: string nullable: true description: Title of the resource (optional) example: "Reading Exercises: b vs d" category: type: string nullable: true description: Category of the resource (optional) content: type: string nullable: true description: Content/URL of the resource (optional) example: "https://example.com/resource" theme: $ref: "#/components/schemas/ThemeInfo" description: Content/URL of the resource (optional) presigned_url: type: string format: url description: The Presigned URL to access the resource example: "https://some-bucket.s3.us-west.cloudprovider.org/bucket/year/month/somefile.pdf?X-Tmz-Algorithm=LOG4-HMAC-SHA256&X-Tmz-Checksum-Mode=ENABLED&X-Tmz-Credential=AKIAEXAMPLE%2F20251016%2Fus-west%2Fs3%2Faws4_request&X-Tmz-Date=20251016T000000Z&X-Tmz-Expires=900&X-Tmz-SignedHeaders=host&x-id=GetObject&X-Amz-Signature=EXAMPLESIGNATURE1234567890abcdef" UpdateResourceBody: type: object properties: theme_id: type: string format: uuid nullable: true description: ID of the theme associated with the resource (optional) example: "123e4567-e89b-12d3-a456-426614174000" grade_level: type: integer nullable: true description: Grade level for the resource (optional). 0 = kindergarten, 1-12 = grades 1-12 minimum: 0 maximum: 12 example: 5 week: type: integer nullable: true description: Week associated with the resource (optional) example: 2 type: type: string nullable: true description: Type of resource (optional) title: type: string nullable: true description: Title of the resource (optional) example: "Coping with Anxiety" category: type: string nullable: true description: Category of the resource (optional) content: type: string nullable: true description: Content/URL of the resource (optional) example: "https://example.com/resource" SessionRating: type: object required: - category - level properties: category: type: string enum: ["visual_cue", "verbal_cue", "gestural_cue", "engagement"] description: Category of the rating example: "engagement" level: type: string enum: ["minimal", "moderate", "maximal", "low", "high"] description: Rating level example: "high" description: type: string nullable: true description: Optional description for the rating example: "Student was highly engaged throughout the session" SessionStudent: type: object required: - session_id - student_id - present - created_at - updated_at properties: id: type: integer description: Unique identifier for the session-student relationship example: 1 session_id: type: string format: uuid description: UUID of the session example: "123e4567-e89b-12d3-a456-426614174000" student_id: type: string format: uuid description: UUID of the student example: "987fcdeb-51a2-43d1-9f4c-123456789abc" present: type: boolean description: Whether the student was present at the session example: true notes: type: string nullable: true description: Notes about the student's participation in the session example: "Student actively participated in group activities" created_at: type: string format: date-time description: When the relationship was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: When the relationship was last updated example: "2024-01-15T10:35:00Z" CreateSessionStudentInput: type: object required: - session_ids - student_ids properties: session_ids: type: array items: type: string format: uuid description: List of all Sessions' UUIDs student_ids: type: array items: type: string format: uuid description: List of all Students' UUIDs present: type: boolean description: Whether the student was present (defaults to true if not specified) example: true notes: type: string nullable: true description: Initial notes about the student's participation example: "First session with new group" UpdateSessionStudentInput: type: object required: - session_id - student_id properties: session_id: type: string format: uuid description: UUID of the session (cannot be changed) example: "123e4567-e89b-12d3-a456-426614174000" student_id: type: string format: uuid description: UUID of the student (cannot be changed) example: "987fcdeb-51a2-43d1-9f4c-123456789abc" present: type: boolean description: Update the student's attendance status example: false notes: type: string nullable: true description: Update or clear notes (set to null to clear) example: "Student left early due to appointment" ratings: type: array items: $ref: "#/components/schemas/SessionRating" description: List of ratings for this student during the session SessionStudentWithRatings: type: object required: - session_id - student_id - ratings properties: session_id: type: string format: uuid description: UUID of the session (cannot be changed) example: "123e4567-e89b-12d3-a456-426614174000" student_id: type: string format: uuid description: UUID of the student (cannot be changed) example: "987fcdeb-51a2-43d1-9f4c-123456789abc" present: type: boolean description: Update the student's attendance status example: false notes: type: string nullable: true description: Update or clear notes (set to null to clear) example: "Student left early due to appointment" ratings: type: array items: $ref: "#/components/schemas/SessionRating" description: List of ratings for this student during the session StudentRatingEntry: type: object required: - session_id - student_id - session_date - ratings properties: session_id: type: string format: uuid description: UUID of the session example: "123e4567-e89b-12d3-a456-426614174000" student_id: type: string format: uuid description: UUID of the student example: "987fcdeb-51a2-43d1-9f4c-123456789abc" session_date: type: string format: date-time description: Date and time of the session example: "2024-01-15T14:30:00Z" ratings: type: array items: $ref: "#/components/schemas/SessionRating" description: List of ratings for this student StudentWithSessionInfo: type: object required: - session_student_id - student - present - session_id - ratings properties: session_student_id: type: integer description: The unique ID of the session-student relationship example: 1 student: $ref: "#/components/schemas/Student" description: The student information session_id: type: string format: uuid description: UUID of the associated session example: "123e4567-e89b-12d3-a456-426614174000" present: type: boolean description: Whether the student was present at the session example: true notes: type: string nullable: true description: Session-specific notes about the student example: "Showed significant progress with motor skills" created_at: type: string format: date-time description: When the session-student relationship was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: When the session-student relationship was last updated example: "2024-01-15T10:35:00Z" ratings: type: array items: $ref: "#/components/schemas/SessionRating" description: List of ratings given to the student during the session AttendanceRecord: type: object required: - present_count - total_count properties: present_count: type: integer description: Number of sessions the student was present example: 15 total_count: type: integer description: Total number of sessions held example: 20 SessionWithStudentInfo: type: object required: - session - student_id - present - created_at - updated_at properties: session: $ref: "#/components/schemas/Session" description: The nested session object student_id: type: string format: uuid description: UUID of the associated student example: "987fcdeb-51a2-43d1-9f4c-123456789abc" present: type: boolean description: Whether the student was present at this session example: true notes: type: string nullable: true description: Session-specific notes about the student example: "Worked on balance exercises" created_at: type: string format: date-time description: When the session-student relationship was created example: "2024-01-15T10:30:00Z" updated_at: type: string format: date-time description: When the session-student relationship was last updated example: "2024-01-15T10:35:00Z" SessionResource: type: object required: - session_id - resource_id - created_at - updated_at properties: session_id: type: string format: uuid description: ID of completed session resource_id: type: string format: uuid description: ID of referenced resource created_at: type: string format: date-time description: When the session-resource link was created example: "2025-09-13T17:19:00Z" updated_at: type: string format: date-time description: When the session-resource link was last updated example: "2025-09-13T17:19:00Z" ModifySessionResource: type: object required: - session_id - resource_id properties: session_id: type: string format: uuid description: ID of completed session resource_id: type: string format: uuid description: ID of referenced resource PromoteStudentsInput: type: object required: - therapist_id properties: therapist_id: type: string format: uuid description: ID of Therapist excluded_student_ids: type: array items: type: string format: uuid description: List of Students this Therapist will not be promoting... GameContent: type: object required: - id - theme_id - week - category - question_type - difficulty_level - question - options - answer - exercise_type - applicable_game_types - presigned_options - created_at - updated_at properties: id: type: string format: uuid description: ID of a Game Content. example: "123e4567-e89b-12d3-a456-426614174000" theme_id: type: string format: uuid description: The UUID of the Theme associated with the game's content example: "123e4567-e89b-12d3-a456-426614174001" week: type: integer minimum: 1 description: The Week of the Content in the session example: 2 category: type: string enum: [ receptive_language, expressive_language, social_pragmatic_language, speech, ] description: The category of the game example: "speech" question_type: type: string enum: [ sequencing, following_directions, wh_questions, true_false, concepts_sorting, fill_in_the_blank, categorical_language, emotions, teamwork_talk, express_excitement_interest, fluency, articulation_s, articulation_l, ] description: The type of the question being asked in the game example: "fluency" difficulty_level: type: integer minimum: 1 description: The corresponding level of content for this game's content example: 4 question: type: string description: The question being asked in the game example: "What type of reptile is Swampy?" options: type: array items: type: string description: The list of wrong-words that are given for the game. example: ["Crocorokodile", "Krookodile", "Koorkodile"] answer: type: string description: The answer to the game (presigned URL) example: "Crocodile" exercise_type: type: string enum: [game, pdf] description: The exercise type of the game content example: "game" applicable_game_types: type: array items: type: string enum: [drag and drop, spinner, word/image matching, flashcards, multi-match] description: The list of applicable game types for this content example: ["drag and drop", "spinner"] raw_answer: type: string description: The raw answer to the game. example: "" presigned_options: type: array items: type: string description: The list of wrong-words that are given for the game. example: ["Crocorokodile", "Krookodile", "Koorkodile"] created_at: type: string format: date-time description: When the game-content was created example: "2025-09-13T17:19:00Z" updated_at: type: string format: date-time description: When the game-content was last updated example: "2025-09-13T17:19:00Z" GameResult: type: object required: - id - session_student_id - content_id - time_taken_sec - completed - count_of_incorrect_attempts - incorrect_attempts - created_at - updated_at properties: id: type: string format: uuid description: ID of the Game Result. example: "123e4567-e89b-12d3-a456-426614174946" session_student_id: type: string format: uuid description: ID of the Student-Session associated with the Game. example: "123e4567-e89b-12d3-a456-426614174946" content_id: type: string format: uuid description: ID of the Content of the Game example: "123e4567-e89b-12d3-a456-426614174cid" time_taken_sec: type: integer description: Number of seconds it takes to complete the game example: 93 completed: type: boolean description: Whether or not the game was completed or not example: true count_of_incorrect_attempts: type: integer minimum: 0 description: The number of incorrect attempts made during the game example: 1 incorrect_attempts: type: array items: type: string description: The actual incorrect answers chosen during the game example: ["Kroookodiley"] created_at: type: string format: date-time description: When the game-content was created example: "2025-09-13T17:19:00Z" updated_at: type: string format: date-time description: When the game-content was last updated example: "2025-09-13T17:19:00Z" PostGameResultInput: type: object required: - session_student_id - content_id - time_taken_sec - count_of_incorrect_attempts properties: session_student_id: type: integer description: Serial-ID of the Session-Student associated with the gameplay example: 2 content_id: type: string format: uuid description: ID of the Content of the Game example: "123e4567-e89b-12d3-a456-426614174394" time_taken_sec: type: integer description: Number of seconds it takes to complete the game example: 93 completed: type: boolean description: Whether or not the game was completed example: true count_of_incorrect_attempts: type: integer minimum: 0 description: The number of incorrect attempts made during the game example: 3 incorrect_attempts: type: array items: type: string description: The actual incorrect options selected in the course of the game example: ["Lijard", "Leopaard", "BARES"] securitySchemes: cookieAuth: type: apiKey in: cookie name: jwt description: JWT token stored in cookies for authentication