+254 700 123 456 support@schoolos.app
The operating system for modern schools
SchoolOS
HomeAboutPlatformDocsUpdatesContact
Get Started
Ready to digitise your school? Start your free workspace today.
Get Started
SchoolOS

SchoolOS gives every school a modern workspace for academics, payments, attendance, communication, and parent engagement — all in one caring, value-driven platform.

Quick Links

  • About
  • Modules
  • Stories
  • Contact
  • Portal Login

Core Modules

  • Fees & Payments
  • Academics & Grading
  • Attendance Tracking
  • Communication
  • Reports & Analytics
  • Student Management
  • Timetable & Calendar

Contact Us

Nairobi, Kenya
Serving schools countrywide
+254 700 123 456
support@schoolos.app
Mon – Fri: 7:00 AM – 8:00 PM
Sat: 8:00 AM – 1:00 PM
Chat on WhatsApp
© 2026 SchoolOS. All rights reserved.
Privacy PolicyTerms of Use

Documentation

SchoolOS — everything a new user needs

A single scrollable reference: roles, plans, features, login flows, workflows, APIs, SSO, and deployment. Use the table of contents on the left to jump around.

Contents

  • Overview
  • Getting Started
  • Roles & Permissions
  • Plans & Pricing
  • Features by Plan
  • Logging In
  • Core Workflows
  • Super Admin Panel
  • REST API & Keys
  • Single Sign-On
  • SLA & Uptime
  • Multi-tenancy Model
  • Data & Security
  • Deployment
  • FAQ & Troubleshooting

Overview#

SchoolOS is a multi-tenant school management platform. One codebase serves many schools (tenants); each school sees only its own students, staff, fees, and analytics. The platform gates functionality per-school by pricing plan, so a Basic-tier school sees a different sidebar than a Premium Enterprise one.

It ships with:

  • Five paid plans (Basic → Premium Enterprise), three one-time tiers, and two source-code licences.
  • 7 user roles from SUPER_ADMIN down to STUDENT.
  • ~25 first-class modules: students, attendance, grading, fees, quizzes, timetable, admissions, discipline, inventory, communications, duty roster, report cards, etc.
  • A REST API with per-school API keys (Premium Plus+).
  • Google SSO with email-domain restriction (Premium Plus+).
  • SLA uptime monitoring widget (Premium Enterprise).
The marketing homepage lives at /, pricing at /#pricing, contact at /contact. Logged-in users land at /dashboard. Super admins land at /admin.

Getting Started#

For a new school

  1. Visit /#pricing and pick a plan.
  2. Click Get started or Start 14-day free trial (available on Standard and Premium). You'll be taken to /contact with the plan pre-selected.
  3. Submit the form. Your inquiry becomes a sales lead tagged HIGH priority.
  4. A super admin converts the lead into a real school workspace at /admin/leads/[id]/convert. The conversion page pre-fills everything from the lead and, on submit, creates the school on the correct plan plus a principal account.
  5. The super admin shares the credentials card (school code + email + generated password + login URL). The principal signs in and begins onboarding staff/students.

Free trials

Standard and Premium plans include a 14-day free trial. Trial workspaces are identical to paid workspaces and can be upgraded / downgraded at any time from the super admin panel. No credit card is required to request a trial.

Annual billing

All monthly plans offer a 15% discount when billed annually. The setup fee (KES 20–50k depending on tier) is also waived. Toggle the Monthly / Annual switch on the pricing page to see the effective monthly price and annual total.

Roles & Permissions#

Seven roles. Each user belongs to exactly one role per school (SUPER_ADMIN has no school).

RoleScopeSees
SUPER_ADMINPlatform-wideAll schools, plans, users, testimonials, sales leads, analytics
PRINCIPALOne schoolFull access to every module the school's plan allows
DEPUTYOne schoolSame as principal minus school-level settings / user-creation
TEACHEROne schoolStudents, grades (entry + submit), attendance, lessons, duty roster
STAFFOne schoolStaff directory, calendar, duty roster, announcements, messages
PARENTOne schoolOnly their child's grades, fees, attendance, report cards, calendar
STUDENTOne schoolOnly their own grades, assignments, quizzes, timetable, report cards
Permissions are enforced in two layers: role (what you're allowed to see at all) and plan feature (whether this school has the module). A teacher on a Basic-plan school sees no Fees tab — it's hidden AND the API returns 403 if they try direct URL access.

Plans & Pricing#

PlanPriceAnnualSetupTrialMax admins
🟢 BasicKES 5,000 /moKES 51,000KES 20,000—1
🔵 Standard ⭐KES 10,000 /moKES 102,000KES 30,00014 days5
🟣 PremiumKES 20,000 /moKES 204,000KES 50,00014 daysUnlimited
🟣 Premium PlusKES 30,000 /moKES 306,000KES 50,000—Unlimited
🟣 Premium EnterpriseKES 40,000 /moKES 408,000KES 50,000—Unlimited
🟠 Buy — StandardKES 250,000one-timeincl.—Unlimited
🟠 Buy — ProfessionalKES 325,000one-timeincl.—Unlimited
🟠 Buy — EnterpriseKES 400,000one-timeincl.—Unlimited
🔴 Source — SingleKES 800,000one-timeincl.—Unlimited
🔴 Source — UnlimitedKES 3,500,000+one-timeincl.—Unlimited

Setup fees on monthly plans are waived when you choose annual billing. Annual billing also applies the 15% discount. Cancellation terms: monthly plans — 30 days notice; annual plans — pro-rata refund within 90 days.

Features by Plan#

CapabilityBasicStandardPremiumPlusEnt.
Students · Attendance · Calendar · Website✅✅✅✅✅
Basic report cards✅✅✅✅✅
Exams · Grading · Quizzes · Lessons❌✅✅✅✅
Fee management · Invoices · Receipts❌✅✅✅✅
Timetable · Duty Roster · Inventory · Health❌✅✅✅✅
SMS / Email notifications❌✅✅✅✅
Parent / Student / Teacher portals❌❌✅✅✅
Advanced analytics · Mobile app❌❌✅✅✅
Admissions · Discipline · Messaging · Bulk docs❌❌✅✅✅
Priority support (same-day)❌❌✅✅✅
Custom branding❌❌❌✅✅
Single Sign-On (Google / Microsoft)❌❌❌✅✅
REST API access❌❌❌✅✅
Multi-campus❌❌❌❌✅
Dedicated account manager❌❌❌❌✅
99.9% uptime SLA❌❌❌❌✅

Logging In#

School workspace

At /login, keep the tab on School workspace and enter:

  • School code — the slug issued to the school (e.g. school-local, greenfield)
  • Email — user's email address
  • Password — set when the account was created

Platform admin

Switch to the Platform admin tab. The school-code field hides. Enter super-admin email and password. Redirects to /admin on success.

Google SSO

When the server has a GOOGLE_CLIENT_ID and the school's plan includes SSO, a Sign in with Google button appears below the main form. The user enters their school code first, then clicks the button. The SSO flow never creates accounts — the user must already exist in the school. See Single Sign-On below for setup steps.

Core Workflows#

Each module lives at a predictable URL under /dashboard:

ModuleURLWhat it does
Home/dashboardKPIs, recent activity, stat cards; SLA widget for Enterprise
Students/dashboard/studentsRegister / list / view students (tenant-scoped)
Teachers/dashboard/teachersTeaching staff directory
Parents/dashboard/parentsParent directory linked to student records
Attendance/dashboard/attendanceDaily register (PRESENT / LATE / ABSENT)
Classes · Subjects/dashboard/classes · /subjectsTaxonomy for the rest of the system
Timetable/dashboard/timetableWeekly class / subject / teacher grid
Lessons · Exams · Assignments · Quizzes/dashboard/lessons etc.Academic content + online quizzes with autograding
Grades · Results · Report Cards/dashboard/grades etc.Entry, approval, PDF publication
Fees/dashboard/feesInvoices, receipts, M-Pesa/Paystack collection
Admissions/dashboard/admissionsApplicant pipeline from intake to enrolment
Discipline/dashboard/disciplineIncident log + parent notifications
Inventory/dashboard/inventoryAssets, books, lab equipment, stock
Duty Roster/dashboard/duty-rosterGate duty / bus duty / meal supervision
Messages · Bulk · Announcements/dashboard/messages etc.1-to-1, bulk SMS/email, school-wide notices
Testimonials/dashboard/testimonialsPrincipal-moderated reviews shown on landing page
Nav items disappear when the school's plan doesn't include that feature. If a user reaches a gated URL directly, the backend returns 403 with a "Your current plan does not include: X" message and the frontend redirects to /dashboard/upgrade.

Super Admin Panel#

Accessible at /admin for users whose role is SUPER_ADMIN.

  • Overview — cross-tenant analytics (schools, students, revenue).
  • Schools — CRUD schools, toggle active state, manage logos/colours.
  • Plans & Billing — assign a plan to any school. Feature access updates immediately on next request.
  • Sales Leads — see every /contact submission (department=SALES), filter by status, search, convert a lead into a real school + principal in one form.
  • Users — global directory of every user across every school; create, disable, or delete.
  • Testimonials — approve / reject / delete / revert / send back to pending; filter by school; search.
  • Live Monitor — SSE stream of significant events across tenants.

Converting a sales lead to a school

  1. Open /admin/leads — new submissions appear at the top, HIGH-priority ones highlighted.
  2. Click Convert to school on a lead.
  3. Form pre-fills: school name (from lead), school code (auto-slugged), plan (detected from the [Plan] subject prefix), principal email + full name.
  4. Optionally supply a password, or leave blank to auto-generate a 10-char strong one.
  5. Submit. Backend creates the school with the correct plan + billing type + max admins, creates the principal, marks the lead CONVERTED, and returns credentials.
  6. Copy the Login URL · School code · Email · Password off the success card and hand them off. The password is only visible here.

REST API & Keys#

Available on Premium Plus and Premium Enterprise plans only (feature flag API_ACCESS).

Generate a key

  1. Principal or deputy opens /dashboard/api-keys.
  2. Gives the key a name (e.g. "Payroll sync", "Zapier").
  3. Clicks Generate key.
  4. Copies the plaintext (format: sk_live_xxxxxxxxxxxxxxxxxxxx). This is the only time the full value is shown.

Use a key

Send it as either header — both work:

# X-API-Key header
curl https://api.schoolos.geenjoroge.org/api/students \
  -H "X-API-Key: sk_live_xxxxxxxxxxxx"

# Authorization header
curl https://api.schoolos.geenjoroge.org/api/fees \
  -H "Authorization: Bearer sk_live_xxxxxxxxxxxx"

Every request is automatically scoped to the school that issued the key. Plan-gated endpoints still respect @RequireFeature — e.g. the key will hit 403 on /api/quizzes if the school's plan doesn't include QUIZZES_ASSIGNMENTS (though Premium Plus has it).

Revoke a key

From the same /dashboard/api-keys page, click Revoke to disable it immediately (keeps the audit trail) or the trash icon to delete entirely.

Common endpoints

MethodPathReturns
GET/api/studentsList of students
GET/api/students/:idOne student
POST/api/studentsRegister student
GET/api/attendanceAttendance records
GET/api/gradesGrade entries
GET/api/feesFee records
GET/api/fees/summaryTotals + collection rate
GET/api/quizzesQuizzes
GET/api/calendar-eventsSchool events
GET/api/admissionsAdmissions pipeline

Single Sign-On#

Google Workspace SSO is available on Premium Plus and Premium Enterprise.

Server setup (one time)

  1. Go to Google Cloud Console → APIs & Services → Credentials.
  2. Create an OAuth 2.0 Client ID of type Web application.
  3. Under Authorized JavaScript origins, add your frontend URL (e.g. https://schoolos.geenjoroge.org).
  4. Copy the client ID.
  5. Add GOOGLE_CLIENT_ID=xxxxxx.apps.googleusercontent.com to backend .env.
  6. Restart the backend.

School-level setup

  1. Principal opens /dashboard/sso.
  2. Checks Enable Google Sign-In for this school.
  3. Optionally adds Allowed domains (comma-separated, e.g. yourschool.ac.ke, staff.yourschool.ac.ke). Leave empty to allow any domain.
  4. Saves.

User flow

  1. User opens /login, enters the school code.
  2. Clicks Sign in with Google.
  3. Google returns an ID token. Backend verifies it, checks plan + domain allowlist, looks up the user by email within the school.
  4. If a matching active user exists, a session is issued and the user is redirected to the dashboard.
SSO never creates accounts. Users must first be added via Staff / Students pages by a principal. This prevents rogue sign-ups.

SLA & Uptime#

Premium Enterprise includes a 99.9% uptime commitment. The dashboard home page shows a live uptime widget with:

  • Current SLA % for the last 30 days
  • Target (99.9%) and whether we're meeting it
  • Process uptime in days
  • Database connection status
  • Last-incident timestamp

Backend endpoint: GET /api/sla/uptime — requires the SLA_UPTIME feature flag.

Multi-tenancy Model#

One Postgres database, one codebase, many schools.

  • Every tenant row carries a schoolId column (foreign key to schools.id).
  • The TenantMiddleware resolves each request's schoolId from the JWT or X-School-Code header (SUPER_ADMIN can switch; everyone else is locked to their own school).
  • Every service method receives schoolId as its first parameter via a parameter decorator and puts it into every query.
  • Email uniqueness is partial: (email, schoolId) is unique for regular users; (email) alone is unique for SUPER_ADMIN.

Schools cannot see each other's data. Even a principal calling /api/students directly gets only students from their own school.

Data & Security#

  • Kenya Data Protection Act (2019) compliant. DPA available on request.
  • Passwords hashed with bcrypt (10 rounds).
  • JWTs signed with HS256; 7-day expiry; secret in env JWT_SECRET.
  • API keys stored only as bcrypt hashes. The plaintext is shown once at generation and never again.
  • SSO tokens verified server-side with Google's public keys.
  • Rate limiting: 200 requests / 15 min per IP.
  • Helmet enforces a strict CSP, HSTS, no inline scripts.
  • Backups: automated nightly Postgres dumps on subscription plans.
  • Data portability: full CSV + PDF export on any plan.

Deployment#

The platform splits into two repositories:

  • schoolos-backend — NestJS on Node 18+, Postgres 14+
  • schoolos-frontend — Next.js 15 (App Router) on Node 18+

Backend checklist

  1. Copy .env.example → .env, fill in DB_*, JWT_SECRET, CORS_ORIGINS.
  2. Ensure uuid-ossp Postgres extension is available.
  3. npm install && npm run build.
  4. npm run migration:run (applies 0001 → 0005).
  5. npm run seed:demo — optional comprehensive demo data.
  6. Run with pm2 start dist/main.js --name schoolos-backend.

Frontend checklist

  1. Set NEXT_PUBLIC_API_URL in .env.local to the backend's public URL.
  2. npm install && npm run build.
  3. pm2 start "npm run start" --name schoolos-frontend.

Nginx (recommended)

server {
  server_name schoolos.example.com;
  location / { proxy_pass http://localhost:3000; }
}
server {
  server_name api.schoolos.example.com;
  location / { proxy_pass http://localhost:4010; }
}
Add the frontend origin to CORS_ORIGINS in the backend .env (comma-separated). The backend rejects requests from other origins — including common dev ports like 3000, 3001, 3002 if you forget to whitelist them.

FAQ & Troubleshooting#

Login returns "Invalid email or password"

Check the school code matches exactly (school-local not schoollocal). For super admin, switch to the Platform admin tab — super admin has no school code.

Sidebar is missing modules I expect

The school's plan doesn't include them. Go to /admin/plans as super admin and bump the plan — changes take effect immediately.

API returns 403 "Your current plan does not include…"

Same reason — plan gating. Either upgrade the plan or use a different endpoint that's covered by the current tier.

CORS errors on the frontend

The frontend origin isn't in CORS_ORIGINS. Add it (including the port in dev). Restart the backend.

Migration fails with "relation already exists"

All migrations are idempotent after 0002. If you see this on 0001, the schema was built via synchronize — safe to ignore; subsequent migrations will short-circuit.

Google SSO button doesn't appear

Four requirements, all must hold: (1) GOOGLE_CLIENT_ID set on the server, (2) the school's plan includes SSO, (3) the school has ssoEnabled: true, (4) the user is on the School workspace tab (not Platform admin).

How do I reset a lost password?

Currently a super admin can recreate the user from /admin/users (delete + recreate with a new password) or open the DB and update the passwordHash column directly with a bcrypt hash (10 rounds). A self-service password reset flow is planned.

SchoolOS Docs · Last updated 2026-04-17 · For questions, contact support.