Download OpenAPI specification:
REST API of Kibooz, the kindergarten app where teachers record the mood of children and parents follow it and earn points for sorting trash.
Every JSON response uses one envelope. A success has success: true with an optional message and data.
A failure has success: false, a message and a stable errorCode, and validation failures also carry a
details object with one message per field.
Protected routes need the access token from login as a bearer token. Rate limits answer 429 with RATE_LIMITED.
A GURU registers together with a new class and becomes its teacher. A WALI registers with the class code of the teacher and the details of the child. A class whose teachers were all deleted cannot accept new children.
| email required | string <email> <= 255 characters |
| password required | string <password> [ 8 .. 72 ] characters At most 72 bytes, which is the limit of bcrypt |
| fullName required | string [ 2 .. 150 ] characters |
| role required | string Enum: "GURU" "WALI" |
| phoneNumber | string <= 30 characters |
| nip | string <= 50 characters |
| schoolName | string <= 150 characters |
| address | string <= 1000 characters |
| whatsappNumber | string <= 30 characters |
object Required for a GURU | |
| classCode | string [ 4 .. 12 ] characters ^[A-Za-z0-9]+$ Required for a WALI, the join code from the dashboard of the teacher |
object Required for a WALI |
{- "email": "teacher@example.com",
- "password": "{{password}}",
- "fullName": "Ibu Siti",
- "role": "GURU",
- "class": {
- "name": "Bunga",
- "gradeLevel": "Class A"
}
}{- "success": true,
- "message": "string",
- "data": {
- "token": "string",
- "refreshToken": "string",
- "user": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "email": "user@example.com",
- "fullName": "string",
- "role": "GURU",
}
}
}| email required | string <email> <= 255 characters |
| password required | string <password> <= 72 characters |
| role required | string (Role) Enum: "GURU" "WALI" "ADMIN" Teacher, parent or administrator. ADMIN cannot be registered. |
{- "email": "user@example.com",
- "password": "pa$$word",
- "role": "GURU"
}{- "success": true,
- "message": "string",
- "data": {
- "token": "string",
- "refreshToken": "string",
- "user": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "email": "user@example.com",
- "fullName": "string",
- "role": "GURU",
}
}
}The refresh token is single use, so the old one stops working as soon as this call succeeds.
| refreshToken required | string <= 128 characters |
{- "refreshToken": "string"
}{- "success": true,
- "message": "string",
- "data": {
- "token": "string",
- "refreshToken": "string",
- "user": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "email": "user@example.com",
- "fullName": "string",
- "role": "GURU",
}
}
}The child, today's mood, the points summary and the recommended guidance. Without studentId the oldest child is used.
| studentId | string <uuid> A child of the signed in parent |
{- "success": true,
- "data": {
- "student": {
- "id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
- "fullName": "string",
- "className": "string",
- "nisn": "string"
}, - "todayMood": {
- "moodType": "SENANG",
- "label": "Happy / Cheerful",
- "confidence": 0,
- "recordedAt": "2019-08-24T14:15:22Z",
- "teacherNotes": "string"
}, - "pointsSummary": {
- "totalPoints": 0,
- "classRank": 0,
- "organicCount": 0,
- "anorganicCount": 0
}, - "recommendedGuidance": {
- "id": "string",
- "title": "string",
- "category": "string",
- "bannerUrl": "string"
}
}
}| guidanceId required | string <= 64 characters |
| studentId required | string <uuid> |
| parentNotes | string <= 2000 characters |
{- "guidanceId": "string",
- "studentId": "316b73a5-f34b-4c3c-9a64-99b549057ec7",
- "parentNotes": "string"
}{- "success": true,
- "message": "string"
}The class overview and the distribution of today's moods. Without classId the first class of the teacher is used.
| classId | string <uuid> A class of the signed in user |
{- "success": true,
- "data": {
- "classOverview": {
- "classId": "f0846d40-4884-40d5-8fc5-9f2c5ef371c4",
- "className": "string",
- "joinCode": "string",
- "totalStudents": 0,
- "presentStudents": 0,
- "dominantMood": "SENANG"
}, - "dailyMoodDistribution": {
- "senang": 0,
- "sedih": 0,
- "marah": 0,
- "bingung": 0
}
}
}Only the latest mood of a child per local day counts in the dashboards and charts.
| studentId required | string <uuid> |
| moodType required | string (Mood) Enum: "SENANG" "SEDIH" "MARAH" "BINGUNG" Happy, sad, angry or confused |
| source | string Default: "MANUAL_INPUT" Enum: "AI_CAMERA" "MANUAL_INPUT" |
| confidenceScore | number <float> [ 0 .. 1 ] Required for the AI_CAMERA source, 1 by default otherwise |
| notes | string <= 2000 characters |
{- "studentId": "316b73a5-f34b-4c3c-9a64-99b549057ec7",
- "moodType": "SENANG",
- "source": "AI_CAMERA",
- "confidenceScore": 0,
- "notes": "string"
}{- "success": true,
- "message": "string",
- "data": {
- "logId": "d2062bfa-97e3-46e4-80bf-86fffbf5d060",
- "recordedAt": "2019-08-24T14:15:22Z"
}
}The donut summary and the Monday to Friday trend. The monthly range adds the distribution of the month.
| classId | string <uuid> A class of the signed in user |
| range | string Default: "weekly" Enum: "weekly" "monthly" |
{- "success": true,
- "data": {
- "donutSummary": [
- {
- "mood": "SENANG",
- "percentage": 0,
- "colorHex": "#34C759"
}
], - "weeklyTrend": [
- {
- "day": "Monday",
- "averageHappyScore": 0
}
], - "monthlyDistribution": [
- {
- "mood": "SENANG",
- "count": 0
}
]
}
}A child can claim a limited number of times per local day. The optional photo is stored as evidence and has to be a JPEG, PNG or WebP image of at most 4 MiB, given as base64 or as a data URI.
| studentId required | string <uuid> |
| trashType required | string (TrashType) Enum: "ORGANIK" "ANORGANIK" "B3" |
| confidenceScore | number <float> [ 0 .. 1 ] Default: 0 |
| photoBase64 | string Optional evidence photo as base64 or a data URI, at most 4 MiB once decoded |
{- "studentId": "316b73a5-f34b-4c3c-9a64-99b549057ec7",
- "trashType": "ORGANIK",
- "confidenceScore": 0,
- "photoBase64": "string"
}{- "success": true,
- "message": "string",
- "data": {
- "pointsAdded": 0,
- "totalPoints": 0,
- "newRank": 0,
- "remainingDailyScans": 0
}
}Ranked by points, then name. A parent sees the class of their child and a teacher sees a class they teach.
| classId | string <uuid> A class of the signed in user |
{- "success": true,
- "data": {
}
}Sets the photo of the signed in user, or of one of their children when studentId is given by a parent. The
file has to be a JPEG, PNG or WebP image of at most 2 MiB. The previous photo is deleted from storage.
| file required | string <binary> |
| studentId | string <uuid> A child of the signed in parent |
{- "success": true,
- "message": "string",
}Soft deletes the account after the password is confirmed. The sessions are revoked, the account can no longer sign in, and the children of a parent are deleted with it.
| password required | string <password> <= 72 characters |
{- "password": "pa$$word"
}{- "success": true,
- "message": "string"
}Answers 200 when the database works, with degraded when Redis is down, and 503 when the database is down.
This route lives at the root and not under /api/v1.
{- "success": true,
- "status": "ok",
- "version": "string",
- "checks": {
- "database": "ok",
- "redis": "ok",
- "storage": "ok"
}
}