Authentication
NIVAA uses custom JWT (HS256) authentication with KV-backed session storage. All API endpoints (except public routes) require a valid Bearer token.
Token Format
Tokens are signed with HS256 using the JWT_SECRET environment variable. The payload contains:
{
"sub": 42, // user ID
"role": "Tutor", // "Admin" | "Tutor" | "Parent"
"email": "[email protected]",
"iat": 1711497600,
"exp": 1712102400 // 7-day expiry
}Making Requests
Include the token in the Authorization header:
The public browser API base is https://ext.instalytics.ai/partner/nivaa. That edge route must strip /partner/nivaa before forwarding to the NIVAA worker.
GET /partner/nivaa/appointments HTTP/1.1
Host: ext.instalytics.ai
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...
Content-Type: application/jsonEndpoints
/api/auth/register PublicCreate a new account. No authentication required.
| Parameter | Type | Description |
|---|---|---|
email | string | Email address |
password | string | Password |
display_name | string | Full display name |
role | string | "Parent" or "Tutor" |
phone | string | Phone number with country code |
{
"ok": true,
"data": {
"token": "eyJhbGci...",
"user": {
"id": 42,
"email": "[email protected]",
"display_name": "Jane Tan",
"role": "Parent"
}
}
}GET /auth/register-prefill?uid={id}&role=tutor returns prefilled educator identity data for setup links. POST /auth/complete-invite finalizes first-time password setup for placeholder-hash invited educator accounts.
/api/auth/login PublicAuthenticate and receive a token. No authentication required.
| Parameter | Type | Description |
|---|---|---|
email | string | Email address |
password | string | Password |
{
"ok": true,
"data": {
"token": "eyJhbGci...",
"user": { ... }
}
}Role-based Access
The Worker's middleware extracts the role from the JWT and enforces access control on each route:
| Route Prefix | Allowed Roles |
|---|---|
/api/admin/* | Admin only |
/api/tutor/* | Admin, Tutor |
/api/parent/* | Admin, Parent |
/api/appointments | All authenticated roles (scoped to own data) |
/api/auth/* | Public (no auth required) |
/api/postings | All authenticated roles |
Dev Auth (Local Only)
During local development, you can bypass JWT authentication by sending special headers:
x-dev-role: Admin
x-dev-user-id: 1
x-dev-email: [email protected]Dev auth headers are ignored on public domains. They only work when the Worker is running locally on localhost or 127.0.0.1.
Many authenticated routes also require resource ownership, not just a valid token. Sensitive records such as posting detail, readiness checks, reschedule decisions, uploaded intake files, and billing PDFs are scoped to the owning user or an admin.
Response Format
All API responses follow a consistent shape:
{
"ok": true,
"data": { ... }
}{
"ok": false,
"error": "Unauthorized"
}Common Error Codes
| HTTP Status | Meaning |
|---|---|
401 | Missing or invalid token |
403 | Valid token but insufficient role |
404 | Resource not found |
422 | Validation error (missing required fields) |
500 | Internal server error |