{"openapi":"3.1.0","info":{"title":"SchoolKick API","version":"0.3.0"},"paths":{"/api/v1/openapi.json":{"get":{"summary":"OpenAPI description of this API","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/tenants":{"post":{"summary":"Create an institution and its first administrator","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/auth/login":{"post":{"summary":"Sign in with email and password","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/auth/logout":{"post":{"summary":"End the current session","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/session":{"get":{"summary":"Who is signed in (me is null when nobody is)","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/users":{"get":{"summary":"List people in this institution","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"post":{"summary":"Create a staff or guardian account","security":[{"session":[]}],"x-roles":["owner"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/learners":{"get":{"summary":"List learners with their guardians","security":[{"session":[]}],"x-roles":["owner","registrar","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"post":{"summary":"Add a learner","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/learners/{id}/guardians":{"post":{"summary":"Link a guardian account to a learner","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/learners/import":{"post":{"summary":"Import learners from CSV (dryRun=1 checks only)","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/classes":{"get":{"summary":"Classes you can see, with today’s attendance progress","security":[{"session":[]}],"x-roles":["owner","registrar","teacher"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"post":{"summary":"Create a class","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/classes/{id}/teachers":{"post":{"summary":"Assign a teacher to a class","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/classes/{id}/enrollments":{"post":{"summary":"Enrol a learner in a class","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/classes/{id}/attendance":{"get":{"summary":"Roster with the current status for a day","security":[{"session":[]}],"x-roles":["owner","registrar","teacher"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"put":{"summary":"Save attendance marks (corrections need a reason)","security":[{"session":[]}],"x-roles":["owner","registrar","teacher"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/classes/{id}/attendance/history":{"get":{"summary":"Every attendance event for a day, newest first","security":[{"session":[]}],"x-roles":["owner","registrar","teacher"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/insights/overview":{"get":{"summary":"Attendance overview: today, trend, class register, exceptions","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/learners":{"get":{"summary":"Your linked learners with today and the last two weeks","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/audit":{"get":{"summary":"Latest 200 audit events","security":[{"session":[]}],"x-roles":["owner"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/settings":{"get":{"summary":"Payment settings: UPI id and which methods are on","security":[{"session":[]}],"x-roles":["owner","registrar","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"put":{"summary":"Set or clear the school UPI id used for payment QR codes","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices/{id}/upi":{"get":{"summary":"UPI link for the outstanding amount, for a QR at the office counter","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices":{"get":{"summary":"List invoices with paid amounts and status","security":[{"session":[]}],"x-roles":["owner","registrar","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"post":{"summary":"Create an invoice for one learner","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/classes":{"get":{"summary":"Classes with learner counts, for invoicing a whole class","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices/bulk":{"post":{"summary":"Create the same invoice for every learner in a class","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices/{id}/void":{"post":{"summary":"Void an invoice that has no payments (recorded, never deleted)","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices/{id}/payments":{"get":{"summary":"Payments for one invoice with receipts and refunds","security":[{"session":[]}],"x-roles":["owner","registrar","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/invoices/{id}/payments/manual":{"post":{"summary":"Record a cash or bank payment received outside the system","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/reconciliation":{"get":{"summary":"Online payments that are unresolved, with age, so none are forgotten","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/payments/{id}":{"get":{"summary":"One payment with its full event timeline","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/payments/{id}/resolve":{"post":{"summary":"Settle, fail or annotate an unresolved payment (evidence and reason required)","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/payments/{id}/refund":{"post":{"summary":"Request a refund against a settled payment; the owner approves it","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/refunds":{"get":{"summary":"Refund requests with their decision","security":[{"session":[]}],"x-roles":["owner","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/fees/refunds/{id}/decide":{"post":{"summary":"Approve or reject a refund request (owner only; approval records the refund)","security":[{"session":[]}],"x-roles":["owner"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/fees":{"get":{"summary":"Fees for linked children, with honest payment states","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/invoices/{id}/pay":{"post":{"summary":"Start a hosted payment for (part of) an invoice","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/payments/{id}":{"get":{"summary":"Current state of a payment (read-only; the return page uses this)","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/payments/{id}/cancel":{"post":{"summary":"Abandon a payment you started but did not complete","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/invoices/{id}/upi":{"post":{"summary":"Start a UPI payment: returns a QR link for the exact amount","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/payments/{id}/claim":{"post":{"summary":"Tell the school you paid by UPI, with the transaction id (UTR)","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/receipts/{id}":{"get":{"summary":"A receipt, with any refunds recorded against it and its verification link","security":[{"session":[]}],"x-roles":"any signed-in user","responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/receipts/{id}/pdf":{"get":{"summary":"Receipt as a PDF with a verification QR code","security":[{"session":[]}],"x-roles":"any signed-in user","responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/verify/{id}/{sig}":{"get":{"summary":"Check a receipt is genuine (public, no personal data)","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/webhooks/payments/sandbox":{"post":{"summary":"Signed provider notification: processing, settled, failed, refunded","security":[],"x-roles":"public","responses":{"200":{"description":"OK"}}}},"/api/v1/guardian/payments/{id}/sandbox":{"post":{"summary":"Sandbox checkout: choose the outcome the test provider reports","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/exams":{"post":{"summary":"Create an exam with its fee, subjects, deadlines and eligibility rule","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}},"get":{"summary":"Exams with registration counts","security":[{"session":[]}],"x-roles":["owner","registrar","finance"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/exams/{id}/register":{"post":{"summary":"Register a learner on their behalf (override reason needed if not eligible)","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/exams/{id}/registrations":{"get":{"summary":"Registrations for an exam with payment and review status","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/exams/registrations/{id}/decide":{"post":{"summary":"Approve or reject a paid registration; approval issues the hall ticket number","security":[{"session":[]}],"x-roles":["owner","registrar"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/exams":{"get":{"summary":"Exams for linked children: eligibility, fee, registration and payment status","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/exams/{id}/register":{"post":{"summary":"Register a linked child; creates the exam fee invoice","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}},"/api/v1/guardian/exams/registrations/{id}/hall-ticket":{"get":{"summary":"Hall ticket, available only once the registration is approved","security":[{"session":[]}],"x-roles":["guardian"],"responses":{"200":{"description":"OK"},"401":{"description":"Not signed in"},"403":{"description":"Role not allowed"}}}}},"components":{"securitySchemes":{"session":{"type":"apiKey","in":"cookie","name":"schoolkick_session"}}}}