Skip to content

Staff SDK Reference

Auto-generated by scripts/generate-sdk-docs.py on 2026-04-27. Do not edit manually — regenerate with python3 scripts/generate-sdk-docs.py (or npm run sync from ui-clients/sdk/ to also refresh the underlying OpenAPI specs).

import { attendanceStaff, canteenStaff, academicReport, invoice, school, wallet, audit } from '@smartsapp/sdk/staff';

Student Attendance (attendanceStaff)

Student Pickup Persons

updatePickupPersonAssignment()

Update authorisation settings for a student-pickup-person assignment

PUT /api/attendance/students/{studentId}/pickup-persons/{pickupPersonId}

Parameters:

Name Type In Required Description
studentId string (uuid) path Yes
pickupPersonId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateStudentPickupPersonRequest

Field Type Required Description
authorisationMode "GENERAL" | "DAY_SPECIFIC" Yes Authorisation mode
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Yes Permission type
monday boolean No Authorised on Monday
tuesday boolean No Authorised on Tuesday
wednesday boolean No Authorised on Wednesday
thursday boolean No Authorised on Thursday
friday boolean No Authorised on Friday

Response: StudentPickupPersonResponse (200)

Field Type Description Example
id string (uuid) Assignment ID "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonId string (uuid) ID of the pickup person "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Full name of the pickup person "John Doe"
pickupPersonPhone string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
authorisationMode "GENERAL" | "DAY_SPECIFIC" How pickup authorisation is verified: PIN, QR_CODE, FACE_ID "GENERAL"
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Permission scope: ALWAYS, SCHEDULED "DROPOFF_ONLY"
monday boolean Whether pickup is allowed on Mondays
tuesday boolean Whether pickup is allowed on Tuesdays
wednesday boolean Whether pickup is allowed on Wednesdays
thursday boolean Whether pickup is allowed on Thursdays
friday boolean Whether pickup is allowed on Fridays
createdAt string (date-time) When the assignment was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the assignment was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zUpdateStudentPickupPersonRequest } from '@smartsapp/sdk/staff';
import type { UpdateStudentPickupPersonRequest, StudentPickupPersonResponse } from '@smartsapp/sdk/staff';

const input: UpdateStudentPickupPersonRequest = {
  authorisationMode: "GENERAL",
  permissionType: "DROPOFF_ONLY",
  monday: "...",
  tuesday: "..."
};

const parsed = zUpdateStudentPickupPersonRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: studentPickupPerson, error } = await attendanceStaff.updatePickupPersonAssignment({
  body: input,
  path: { studentId: "...", pickupPersonId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// studentPickupPerson is typed as StudentPickupPersonResponse

removePickupPersonAssignment()

Remove a pickup person from a student

DELETE /api/attendance/students/{studentId}/pickup-persons/{pickupPersonId}

Parameters:

Name Type In Required Description
studentId string (uuid) path Yes
pickupPersonId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (200)

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';

const { data, error } = await attendanceStaff.removePickupPersonAssignment({
  path: { studentId: "...", pickupPersonId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listStudentPickupPersons()

List all pickup persons assigned to a student

GET /api/attendance/students/{studentId}/pickup-persons

Parameters:

Name Type In Required Description
studentId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StudentPickupPersonResponse[] (200)

Field Type Description Example
id string (uuid) Assignment ID "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonId string (uuid) ID of the pickup person "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Full name of the pickup person "John Doe"
pickupPersonPhone string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
authorisationMode "GENERAL" | "DAY_SPECIFIC" How pickup authorisation is verified: PIN, QR_CODE, FACE_ID "GENERAL"
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Permission scope: ALWAYS, SCHEDULED "DROPOFF_ONLY"
monday boolean Whether pickup is allowed on Mondays
tuesday boolean Whether pickup is allowed on Tuesdays
wednesday boolean Whether pickup is allowed on Wednesdays
thursday boolean Whether pickup is allowed on Thursdays
friday boolean Whether pickup is allowed on Fridays
createdAt string (date-time) When the assignment was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the assignment was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';

const { data, error } = await attendanceStaff.listStudentPickupPersons({
  path: { studentId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as StudentPickupPersonResponse[]

assignPickupPerson()

Assign a pickup person to a student

POST /api/attendance/students/{studentId}/pickup-persons

Parameters:

Name Type In Required Description
studentId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: AssignPickupPersonRequest

Field Type Required Description
pickupPersonId string (uuid) Yes ID of the pickup person to assign
authorisationMode "GENERAL" | "DAY_SPECIFIC" Yes Authorisation mode
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Yes Permission type
monday boolean No Authorised on Monday (only for DAY_SPECIFIC)
tuesday boolean No Authorised on Tuesday (only for DAY_SPECIFIC)
wednesday boolean No Authorised on Wednesday (only for DAY_SPECIFIC)
thursday boolean No Authorised on Thursday (only for DAY_SPECIFIC)
friday boolean No Authorised on Friday (only for DAY_SPECIFIC)

Response: StudentPickupPersonResponse (200)

Field Type Description Example
id string (uuid) Assignment ID "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonId string (uuid) ID of the pickup person "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Full name of the pickup person "John Doe"
pickupPersonPhone string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
authorisationMode "GENERAL" | "DAY_SPECIFIC" How pickup authorisation is verified: PIN, QR_CODE, FACE_ID "GENERAL"
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Permission scope: ALWAYS, SCHEDULED "DROPOFF_ONLY"
monday boolean Whether pickup is allowed on Mondays
tuesday boolean Whether pickup is allowed on Tuesdays
wednesday boolean Whether pickup is allowed on Wednesdays
thursday boolean Whether pickup is allowed on Thursdays
friday boolean Whether pickup is allowed on Fridays
createdAt string (date-time) When the assignment was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the assignment was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zAssignPickupPersonRequest } from '@smartsapp/sdk/staff';
import type { AssignPickupPersonRequest, StudentPickupPersonResponse } from '@smartsapp/sdk/staff';

const input: AssignPickupPersonRequest = {
  pickupPersonId: "550e8400-...",
  authorisationMode: "GENERAL",
  permissionType: "BOTH",
  monday: "..."
};

const parsed = zAssignPickupPersonRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: studentPickupPerson, error } = await attendanceStaff.assignPickupPerson({
  body: input,
  path: { studentId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// studentPickupPerson is typed as StudentPickupPersonResponse

Settings

getAttendanceSettings()

Get attendance settings for a school

GET /api/attendance/settings

Parameters:

Name Type In Required Description
schoolId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AttendanceSettingResponse (200)

Field Type Description Example
id string (uuid) Attendance setting ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school these settings belong to "550e8400-e29b-41d4-a716-446655440000"
parentSelfCheckInEnabled boolean Whether parents can self-check-in their children
attendanceMode "SCAN" | "MANUAL" | "BOTH" Attendance tracking mode: MANUAL, AUTOMATIC "SCAN"
selfCheckInStartTime string Earliest time parents may self-check-in "07:00:00"
selfCheckInEndTime string Latest time parents may self-check-in "09:00:00"
createdAt string (date-time) When the settings were created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the settings were last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';
import type { AttendanceSettingResponse } from '@smartsapp/sdk/staff';

const { data: attendanceSetting, error } = await attendanceStaff.getAttendanceSettings({
  query: { schoolId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceSetting is typed as AttendanceSettingResponse

updateAttendanceSettings()

Update attendance settings for a school

PUT /api/attendance/settings

Parameters:

Name Type In Required Description
schoolId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateAttendanceSettingRequest

Field Type Required Description
parentSelfCheckInEnabled boolean No Enable parent self-check-in via the Parent App
attendanceMode "SCAN" | "MANUAL" | "BOTH" Yes Attendance mode
selfCheckInStartTime string No Start time for parent self-check-in window
selfCheckInEndTime string No End time for parent self-check-in window

Response: AttendanceSettingResponse (200)

Field Type Description Example
id string (uuid) Attendance setting ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school these settings belong to "550e8400-e29b-41d4-a716-446655440000"
parentSelfCheckInEnabled boolean Whether parents can self-check-in their children
attendanceMode "SCAN" | "MANUAL" | "BOTH" Attendance tracking mode: MANUAL, AUTOMATIC "SCAN"
selfCheckInStartTime string Earliest time parents may self-check-in "07:00:00"
selfCheckInEndTime string Latest time parents may self-check-in "09:00:00"
createdAt string (date-time) When the settings were created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the settings were last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zUpdateAttendanceSettingRequest } from '@smartsapp/sdk/staff';
import type { UpdateAttendanceSettingRequest, AttendanceSettingResponse } from '@smartsapp/sdk/staff';

const input: UpdateAttendanceSettingRequest = {
  parentSelfCheckInEnabled: "...",
  attendanceMode: "BOTH",
  selfCheckInStartTime: "07:00",
  selfCheckInEndTime: "09:00"
};

const parsed = zUpdateAttendanceSettingRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: attendanceSetting, error } = await attendanceStaff.updateAttendanceSettings({
  body: input,
  query: { schoolId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceSetting is typed as AttendanceSettingResponse

Section Schedules

getSectionSchedule()

Get the attendance schedule for a section

GET /api/attendance/section-schedules/{sectionId}

Parameters:

Name Type In Required Description
sectionId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SectionScheduleResponse (200)

Field Type Description Example
id string (uuid) Section schedule ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section "550e8400-e29b-41d4-a716-446655440000"
startTime string Scheduled start time for the section "07:30:00"
endTime string Scheduled end time for the section "15:00:00"
lateThresholdMinutes integer (int32) Minutes after start time before a student is marked late 15
pickupLateThresholdMinutes integer (int32) Minutes after end time before a pickup is considered late 30
earlyDepartureThresholdMinutes integer (int32) Minutes before end time that counts as early departure 60
createdAt string (date-time) When the schedule was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the schedule was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';
import type { SectionScheduleResponse } from '@smartsapp/sdk/staff';

const { data: sectionSchedule, error } = await attendanceStaff.getSectionSchedule({
  path: { sectionId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// sectionSchedule is typed as SectionScheduleResponse

upsertSectionSchedule()

Create or update the attendance schedule for a section

PUT /api/attendance/section-schedules/{sectionId}

Parameters:

Name Type In Required Description
sectionId string (uuid) path Yes
schoolId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateSectionScheduleRequest

Field Type Required Description
startTime string Yes Section start time
endTime string Yes Section end time
lateThresholdMinutes integer (int32) Yes Minutes after start time to classify as late
pickupLateThresholdMinutes integer (int32) Yes Minutes after end time to classify pickup as late
earlyDepartureThresholdMinutes integer (int32) Yes Minutes before end time to classify as early departure

Response: SectionScheduleResponse (200)

Field Type Description Example
id string (uuid) Section schedule ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section "550e8400-e29b-41d4-a716-446655440000"
startTime string Scheduled start time for the section "07:30:00"
endTime string Scheduled end time for the section "15:00:00"
lateThresholdMinutes integer (int32) Minutes after start time before a student is marked late 15
pickupLateThresholdMinutes integer (int32) Minutes after end time before a pickup is considered late 30
earlyDepartureThresholdMinutes integer (int32) Minutes before end time that counts as early departure 60
createdAt string (date-time) When the schedule was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the schedule was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zUpdateSectionScheduleRequest } from '@smartsapp/sdk/staff';
import type { UpdateSectionScheduleRequest, SectionScheduleResponse } from '@smartsapp/sdk/staff';

const input: UpdateSectionScheduleRequest = {
  startTime: "08:00",
  endTime: "15:30",
  lateThresholdMinutes: 15,
  pickupLateThresholdMinutes: 30
};

const parsed = zUpdateSectionScheduleRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: sectionSchedule, error } = await attendanceStaff.upsertSectionSchedule({
  body: input,
  path: { sectionId: "..." },
  query: { schoolId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// sectionSchedule is typed as SectionScheduleResponse

listSectionSchedules()

List all section schedules for a school

GET /api/attendance/section-schedules

Parameters:

Name Type In Required Description
schoolId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SectionScheduleResponse[] (200)

Field Type Description Example
id string (uuid) Section schedule ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section "550e8400-e29b-41d4-a716-446655440000"
startTime string Scheduled start time for the section "07:30:00"
endTime string Scheduled end time for the section "15:00:00"
lateThresholdMinutes integer (int32) Minutes after start time before a student is marked late 15
pickupLateThresholdMinutes integer (int32) Minutes after end time before a pickup is considered late 30
earlyDepartureThresholdMinutes integer (int32) Minutes before end time that counts as early departure 60
createdAt string (date-time) When the schedule was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the schedule was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';

const { data, error } = await attendanceStaff.listSectionSchedules({
  query: { schoolId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as SectionScheduleResponse[]

Records

markStudentExcused()

Mark a student as excused for a date

PUT /api/attendance/records/mark-excused

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: MarkExcusedRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student
date string (date) Yes Date to mark as excused
reason string No Reason for the absence

Response: AttendanceRecordResponse (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zMarkExcusedRequest } from '@smartsapp/sdk/staff';
import type { MarkExcusedRequest, AttendanceRecordResponse } from '@smartsapp/sdk/staff';

const input: MarkExcusedRequest = {
  studentId: "550e8400-...",
  date: "...",
  reason: "Medical appointment"
};

const parsed = zMarkExcusedRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: attendanceRecord, error } = await attendanceStaff.markStudentExcused({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceRecord is typed as AttendanceRecordResponse

markStudentAbsent()

Mark a student as absent for a date

PUT /api/attendance/records/mark-absent

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: MarkAbsentRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student
date string (date) Yes Date to mark as absent

Response: AttendanceRecordResponse (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zMarkAbsentRequest } from '@smartsapp/sdk/staff';
import type { MarkAbsentRequest, AttendanceRecordResponse } from '@smartsapp/sdk/staff';

const input: MarkAbsentRequest = {
  studentId: "550e8400-...",
  date: "..."
};

const parsed = zMarkAbsentRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: attendanceRecord, error } = await attendanceStaff.markStudentAbsent({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceRecord is typed as AttendanceRecordResponse

massCheckInStudents()

Mass check-in all students in a class

POST /api/attendance/records/mass-check-in

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: MassCheckInRequest

Field Type Required Description
classroomId string (uuid) Yes ID of the classroom
performedById string (uuid) Yes ID of the admin performing the mass check-in
performedByName string Yes Name of the admin performing the mass check-in

Response: AttendanceRecordResponse[] (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zMassCheckInRequest } from '@smartsapp/sdk/staff';
import type { MassCheckInRequest } from '@smartsapp/sdk/staff';

const input: MassCheckInRequest = {
  classroomId: "550e8400-...",
  performedById: "550e8400-...",
  performedByName: "..."
};

const parsed = zMassCheckInRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data, error } = await attendanceStaff.massCheckInStudents({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as AttendanceRecordResponse[]

checkOutStudent()

Check out a student

POST /api/attendance/records/check-out

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CheckOutRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student
performedById string (uuid) Yes ID of the person performing the check-out
performedByName string Yes Name of the person performing the check-out
method "SCAN" | "MANUAL" Yes Check-out method
pickupPersonId string (uuid) No ID of the pickup person collecting the student
pickupPersonName string No Name of the pickup person (used when person is not in the system)

Response: AttendanceRecordResponse (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zCheckOutRequest } from '@smartsapp/sdk/staff';
import type { CheckOutRequest, AttendanceRecordResponse } from '@smartsapp/sdk/staff';

const input: CheckOutRequest = {
  studentId: "550e8400-...",
  performedById: "550e8400-...",
  performedByName: "...",
  method: "SCAN"
};

const parsed = zCheckOutRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: attendanceRecord, error } = await attendanceStaff.checkOutStudent({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceRecord is typed as AttendanceRecordResponse

checkInStudent()

Check in a student

POST /api/attendance/records/check-in

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CheckInRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student
performedById string (uuid) Yes ID of the person performing the check-in (staff or parent)
performedByName string Yes Name of the person performing the check-in
method "SCAN" | "MANUAL" Yes Check-in method
dropoffPersonId string (uuid) No ID of the pickup/dropoff person accompanying the student (nullable for unaccompanied)
dropoffPersonName string No Name of the dropoff person (used when person is not in the system)

Response: AttendanceRecordResponse (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zCheckInRequest } from '@smartsapp/sdk/staff';
import type { CheckInRequest, AttendanceRecordResponse } from '@smartsapp/sdk/staff';

const input: CheckInRequest = {
  studentId: "550e8400-e29b-41d4-a716-446655440000",
  performedById: "550e8400-e29b-41d4-a716-446655440001",
  performedByName: "Mrs. Adjei",
  method: "MANUAL"
};

const parsed = zCheckInRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: attendanceRecord, error } = await attendanceStaff.checkInStudent({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceRecord is typed as AttendanceRecordResponse

getAttendanceRecord()

Get an attendance record by ID

GET /api/attendance/records/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AttendanceRecordResponse (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';
import type { AttendanceRecordResponse } from '@smartsapp/sdk/staff';

const { data: attendanceRecord, error } = await attendanceStaff.getAttendanceRecord({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// attendanceRecord is typed as AttendanceRecordResponse

listAttendanceByClass()

List attendance records for a class on a date

GET /api/attendance/records/by-class

Parameters:

Name Type In Required Description
classroomId string (uuid) query Yes
date string (date) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AttendanceRecordResponse[] (200)

Field Type Description Example
id string (uuid) Attendance record ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the classroom "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date of the attendance record "2026-01-15"
checkInTime string (date-time) When the student was checked in "2026-01-15T07:45:00Z"
checkInPerformedById string (uuid) ID of the user who performed the check-in "550e8400-e29b-41d4-a716-446655440000"
checkInPerformedByName string Name of the user who performed the check-in "Jane Smith"
checkInMethod "SCAN" | "MANUAL" Method used for check-in: MANUAL, QR_CODE, NFC "SCAN"
checkOutTime string (date-time) When the student was checked out "2026-01-15T15:30:00Z"
checkOutPerformedById string (uuid) ID of the user who performed the check-out "550e8400-e29b-41d4-a716-446655440000"
checkOutPerformedByName string Name of the user who performed the check-out "Jane Smith"
checkOutMethod "SCAN" | "MANUAL" Method used for check-out: MANUAL, QR_CODE, NFC "SCAN"
dropoffPersonId string (uuid) ID of the person who dropped off the student "550e8400-e29b-41d4-a716-446655440000"
dropoffPersonName string Name of the person who dropped off the student "John Doe"
pickupPersonId string (uuid) ID of the person who picked up the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Name of the person who picked up the student "John Doe"
arrivalClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's arrival: ON_TIME, LATE "EARLY"
departureClassification "EARLY" | "ON_TIME" | "LATE" Classification of the student's departure: ON_TIME, EARLY "EARLY"
status "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" Attendance status: PRESENT, ABSENT, EXCUSED "PRESENT"
excuseReason string Reason for excused absence "Doctor appointment"
isUnaccompanied boolean Whether the student arrived or departed without an accompanying adult
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';

const { data, error } = await attendanceStaff.listAttendanceByClass({
  query: { classroomId: "...", date: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as AttendanceRecordResponse[]

Pickup Persons

getPickupPerson()

Get a pickup person by ID

GET /api/attendance/pickup-persons/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PickupPersonResponse (200)

Field Type Description Example
id string (uuid) Pickup person ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
fullName string Full name of the pickup person "John Doe"
phoneNumber string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
photoUrl string URL of the pickup person's photo "https://storage.example.com/photos/abc.jpg"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';
import type { PickupPersonResponse } from '@smartsapp/sdk/staff';

const { data: pickupPerson, error } = await attendanceStaff.getPickupPerson({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// pickupPerson is typed as PickupPersonResponse

updatePickupPerson()

Update a pickup person

PUT /api/attendance/pickup-persons/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdatePickupPersonRequest

Field Type Required Description
fullName string No Full name of the pickup person
relationship string No Relationship to the student
photoUrl string No URL of the person's photo

Response: PickupPersonResponse (200)

Field Type Description Example
id string (uuid) Pickup person ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
fullName string Full name of the pickup person "John Doe"
phoneNumber string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
photoUrl string URL of the pickup person's photo "https://storage.example.com/photos/abc.jpg"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zUpdatePickupPersonRequest } from '@smartsapp/sdk/staff';
import type { UpdatePickupPersonRequest, PickupPersonResponse } from '@smartsapp/sdk/staff';

const input: UpdatePickupPersonRequest = {
  fullName: "...",
  relationship: "...",
  photoUrl: "..."
};

const parsed = zUpdatePickupPersonRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: pickupPerson, error } = await attendanceStaff.updatePickupPerson({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// pickupPerson is typed as PickupPersonResponse

listPickupPersons()

List pickup persons for a school

GET /api/attendance/pickup-persons

Parameters:

Name Type In Required Description
schoolId string (uuid) query Yes
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponsePickupPersonResponse (200)

Field Type Description Example
content PickupPersonResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

PickupPersonResponse fields:

Field Type Description Example
id string (uuid) Pickup person ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
fullName string Full name of the pickup person "John Doe"
phoneNumber string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
photoUrl string URL of the pickup person's photo "https://storage.example.com/photos/abc.jpg"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';
import type { PagedResponsePickupPersonResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await attendanceStaff.listPickupPersons({
  query: { schoolId: "...", page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const pickupPersons = result.content;           // PickupPersonResponse[]
const { page, totalPages, totalElements, last } = result;

createPickupPerson()

Create or find a pickup person (deduplicated by phone number)

POST /api/attendance/pickup-persons

Parameters:

Name Type In Required Description
schoolId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreatePickupPersonRequest

Field Type Required Description
fullName string Yes Full name of the pickup person
phoneNumber string Yes Phone number (unique identifier)
relationship string Yes Relationship to the student
photoUrl string No URL of the person's photo

Response: PickupPersonResponse (200)

Field Type Description Example
id string (uuid) Pickup person ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
fullName string Full name of the pickup person "John Doe"
phoneNumber string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
photoUrl string URL of the pickup person's photo "https://storage.example.com/photos/abc.jpg"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff, zCreatePickupPersonRequest } from '@smartsapp/sdk/staff';
import type { CreatePickupPersonRequest, PickupPersonResponse } from '@smartsapp/sdk/staff';

const input: CreatePickupPersonRequest = {
  fullName: "Ama Mensah",
  phoneNumber: "+233241234567",
  relationship: "Grandmother",
  photoUrl: "..."
};

const parsed = zCreatePickupPersonRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: pickupPerson, error } = await attendanceStaff.createPickupPerson({
  body: input,
  query: { schoolId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// pickupPerson is typed as PickupPersonResponse

reverseLookupPickupPerson()

Reverse lookup: list all students assigned to a pickup person

GET /api/attendance/pickup-persons/{id}/students

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StudentPickupPersonResponse[] (200)

Field Type Description Example
id string (uuid) Assignment ID "550e8400-e29b-41d4-a716-446655440000"
studentId string (uuid) ID of the student "550e8400-e29b-41d4-a716-446655440000"
pickupPersonId string (uuid) ID of the pickup person "550e8400-e29b-41d4-a716-446655440000"
pickupPersonName string Full name of the pickup person "John Doe"
pickupPersonPhone string Phone number of the pickup person "+233501234567"
relationship string Relationship to the student "Uncle"
authorisationMode "GENERAL" | "DAY_SPECIFIC" How pickup authorisation is verified: PIN, QR_CODE, FACE_ID "GENERAL"
permissionType "DROPOFF_ONLY" | "PICKUP_ONLY" | "BOTH" Permission scope: ALWAYS, SCHEDULED "DROPOFF_ONLY"
monday boolean Whether pickup is allowed on Mondays
tuesday boolean Whether pickup is allowed on Tuesdays
wednesday boolean Whether pickup is allowed on Wednesdays
thursday boolean Whether pickup is allowed on Thursdays
friday boolean Whether pickup is allowed on Fridays
createdAt string (date-time) When the assignment was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the assignment was last updated "2026-01-15T10:30:00Z"

Example:

import { attendanceStaff } from '@smartsapp/sdk/staff';

const { data, error } = await attendanceStaff.reverseLookupPickupPerson({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as StudentPickupPersonResponse[]


Canteen (canteenStaff)

Users

getCanteenUser()

Get a canteen user by ID

GET /api/canteen/users/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: CanteenUserResponse (200)

Field Type Description Example
id string (uuid) Canteen user ID "550e8400-e29b-41d4-a716-446655440000"
userId string (uuid) ID of the platform user account "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the assigned catering service "550e8400-e29b-41d4-a716-446655440000"
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" Role within the canteen: ADMIN, OPERATOR, VIEWER "CANTEEN_ADMIN"
active boolean Whether the canteen user account is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { CanteenUserResponse } from '@smartsapp/sdk/staff';

const { data: canteenUser, error } = await canteenStaff.getCanteenUser({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// canteenUser is typed as CanteenUserResponse

updateCanteenUser()

Update a canteen user

PUT /api/canteen/users/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateCanteenUserRequest

Field Type Required Description
cateringServiceId string (uuid) No ID of the catering service
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" No Role of the canteen user
active boolean No Whether the canteen user is active

Response: CanteenUserResponse (200)

Field Type Description Example
id string (uuid) Canteen user ID "550e8400-e29b-41d4-a716-446655440000"
userId string (uuid) ID of the platform user account "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the assigned catering service "550e8400-e29b-41d4-a716-446655440000"
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" Role within the canteen: ADMIN, OPERATOR, VIEWER "CANTEEN_ADMIN"
active boolean Whether the canteen user account is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateCanteenUserRequest } from '@smartsapp/sdk/staff';
import type { UpdateCanteenUserRequest, CanteenUserResponse } from '@smartsapp/sdk/staff';

const input: UpdateCanteenUserRequest = {
  cateringServiceId: "550e8400-e29b-41d4-a716-446655440001",
  role: "MANAGER",
  active: true
};

const parsed = zUpdateCanteenUserRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: canteenUser, error } = await canteenStaff.updateCanteenUser({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// canteenUser is typed as CanteenUserResponse

deleteCanteenUser()

Delete a canteen user

DELETE /api/canteen/users/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteCanteenUser({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listCanteenUsers()

List canteen users with pagination

GET /api/canteen/users

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseCanteenUserResponse (200)

Field Type Description Example
content CanteenUserResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

CanteenUserResponse fields:

Field Type Description Example
id string (uuid) Canteen user ID "550e8400-e29b-41d4-a716-446655440000"
userId string (uuid) ID of the platform user account "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the assigned catering service "550e8400-e29b-41d4-a716-446655440000"
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" Role within the canteen: ADMIN, OPERATOR, VIEWER "CANTEEN_ADMIN"
active boolean Whether the canteen user account is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseCanteenUserResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listCanteenUsers({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const canteenUsers = result.content;           // CanteenUserResponse[]
const { page, totalPages, totalElements, last } = result;

createCanteenUser()

Create a new canteen user

POST /api/canteen/users

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateCanteenUserRequest

Field Type Required Description
userId string (uuid) Yes ID of the user
cateringServiceId string (uuid) Yes ID of the catering service
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" Yes Role of the canteen user

Response: CanteenUserResponse (201)

Field Type Description Example
id string (uuid) Canteen user ID "550e8400-e29b-41d4-a716-446655440000"
userId string (uuid) ID of the platform user account "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the assigned catering service "550e8400-e29b-41d4-a716-446655440000"
role "CANTEEN_ADMIN" | "CANTEEN_MANAGER" | "POS_OPERATOR" Role within the canteen: ADMIN, OPERATOR, VIEWER "CANTEEN_ADMIN"
active boolean Whether the canteen user account is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateCanteenUserRequest } from '@smartsapp/sdk/staff';
import type { CreateCanteenUserRequest, CanteenUserResponse } from '@smartsapp/sdk/staff';

const input: CreateCanteenUserRequest = {
  userId: "550e8400-e29b-41d4-a716-446655440000",
  cateringServiceId: "550e8400-e29b-41d4-a716-446655440001",
  role: "MANAGER"
};

const parsed = zCreateCanteenUserRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: canteenUser, error } = await canteenStaff.createCanteenUser({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// canteenUser is typed as CanteenUserResponse

Settings

updateCanteenSettings()

Update canteen settings

PUT /api/canteen/settings/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateCanteenSettingRequest

Field Type Required Description
redemptionMode "AUTO_REDEEM" | "AUTO_REDEEM_PRESENT" | "SCAN_TO_REDEEM" Yes Redemption mode for the canteen

Response: CanteenSettingResponse (200)

Field Type Description Example
id string (uuid) Setting ID "550e8400-e29b-41d4-a716-446655440000"
redemptionMode "AUTO_REDEEM" | "AUTO_REDEEM_PRESENT" | "SCAN_TO_REDEEM" How orders are redeemed: ORDER_LEVEL, ITEM_LEVEL "AUTO_REDEEM"
createdAt string (date-time) When the settings were created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the settings were last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateCanteenSettingRequest } from '@smartsapp/sdk/staff';
import type { UpdateCanteenSettingRequest, CanteenSettingResponse } from '@smartsapp/sdk/staff';

const input: UpdateCanteenSettingRequest = {
  redemptionMode: "QR_CODE"
};

const parsed = zUpdateCanteenSettingRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: canteenSetting, error } = await canteenStaff.updateCanteenSettings({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// canteenSetting is typed as CanteenSettingResponse

getCanteenSettings()

Get canteen settings

GET /api/canteen/settings

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: CanteenSettingResponse (200)

Field Type Description Example
id string (uuid) Setting ID "550e8400-e29b-41d4-a716-446655440000"
redemptionMode "AUTO_REDEEM" | "AUTO_REDEEM_PRESENT" | "SCAN_TO_REDEEM" How orders are redeemed: ORDER_LEVEL, ITEM_LEVEL "AUTO_REDEEM"
createdAt string (date-time) When the settings were created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the settings were last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { CanteenSettingResponse } from '@smartsapp/sdk/staff';

const { data: canteenSetting, error } = await canteenStaff.getCanteenSettings();

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// canteenSetting is typed as CanteenSettingResponse

Orders

redeemOrder()

Redeem an entire order (mark all items as served)

PUT /api/canteen/orders/{id}/redeem

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: OrderResponse (200)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
studentId string (uuid) ID of the student the order is for "550e8400-e29b-41d4-a716-446655440000"
mealTicketId string (uuid) ID of the meal ticket used for payment "550e8400-e29b-41d4-a716-446655440000"
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
createdBy string (uuid) ID of the user who created the order "550e8400-e29b-41d4-a716-446655440000"
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { OrderResponse } from '@smartsapp/sdk/staff';

const { data: order, error } = await canteenStaff.redeemOrder({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// order is typed as OrderResponse

serveOrderItem()

Mark a single item in an order as served

PUT /api/canteen/orders/{id}/items/{orderItemId}/serve

Parameters:

Name Type In Required Description
id string (uuid) path Yes
orderItemId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: OrderDetailResponse (200)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
student StudentSummary Student summary for order context
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
items OrderItemDetailResponse[] Items included in this order
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

StudentSummary fields:

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
firstName string Student's first name "Kofi"
lastName string Student's last name "Asante"
className string Name of the student's class "Grade 3A"

OrderItemDetailResponse fields:

Field Type Description Example
id string (uuid) Order item ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the ordered item "550e8400-e29b-41d4-a716-446655440000"
itemName string Name of the ordered item "Jollof Rice"
variantId string (uuid) ID of the selected variant "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the selected variant "Large"
menuSectionId string (uuid) ID of the menu section this item was ordered from "550e8400-e29b-41d4-a716-446655440000"
sectionName string Name of the menu section "Lunch Main Course"
quantity integer (int32) Quantity ordered 2
unitPrice number Unit price at time of order 12.5
currency string Currency code "GHS"
served boolean Whether this item has been served
servedAt string (date-time) When the item was served "2026-01-15T12:30:00Z"
servedBy integer (int64) ID of the user who served the item 42
servedByName string Name of the user who served the item "Abena Mensah"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { OrderDetailResponse } from '@smartsapp/sdk/staff';

const { data: orderDetail, error } = await canteenStaff.serveOrderItem({
  path: { id: "...", orderItemId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// orderDetail is typed as OrderDetailResponse

cancelOrder()

Cancel an order

PUT /api/canteen/orders/{id}/cancel

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: OrderResponse (200)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
studentId string (uuid) ID of the student the order is for "550e8400-e29b-41d4-a716-446655440000"
mealTicketId string (uuid) ID of the meal ticket used for payment "550e8400-e29b-41d4-a716-446655440000"
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
createdBy string (uuid) ID of the user who created the order "550e8400-e29b-41d4-a716-446655440000"
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { OrderResponse } from '@smartsapp/sdk/staff';

const { data: order, error } = await canteenStaff.cancelOrder({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// order is typed as OrderResponse

listOrders()

List orders with items and student info

GET /api/canteen/orders

Parameters:

Name Type In Required Description
startDate string (date) query No
endDate string (date) query No
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" query No
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseOrderDetailResponse (200)

Field Type Description Example
content OrderDetailResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

OrderDetailResponse fields:

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
student StudentSummary Student summary for order context
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
items OrderItemDetailResponse[] Items included in this order
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseOrderDetailResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listOrders({
  query: { startDate: "2026-01-01", endDate: "2026-01-01", status: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const orderDetails = result.content;           // OrderDetailResponse[]
const { page, totalPages, totalElements, last } = result;

createOrder()

Create a new order

POST /api/canteen/orders

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateOrderRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student placing the order
mealTicketId string (uuid) No ID of the meal ticket used for the order
orderType "TICKET" | "PRE_ORDER" | "POS" Yes Type of order
totalPrice number Yes Total price of the order
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" Yes Payment mode for the order
scheduledDate string (date) Yes Scheduled date for the order
createdBy string (uuid) Yes ID of the user creating the order
items CreateOrderItemRequest[] Yes List of order items

CreateOrderItemRequest fields:

Field Type Required Description
itemId string (uuid) Yes ID of the item
variantId string (uuid) No ID of the item variant
quantity integer (int32) No Quantity of the item
unitPrice number Yes Unit price of the item

Response: OrderResponse (201)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
studentId string (uuid) ID of the student the order is for "550e8400-e29b-41d4-a716-446655440000"
mealTicketId string (uuid) ID of the meal ticket used for payment "550e8400-e29b-41d4-a716-446655440000"
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
createdBy string (uuid) ID of the user who created the order "550e8400-e29b-41d4-a716-446655440000"
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateOrderRequest } from '@smartsapp/sdk/staff';
import type { CreateOrderRequest, OrderResponse } from '@smartsapp/sdk/staff';

const input: CreateOrderRequest = {
  studentId: "550e8400-e29b-41d4-a716-446655440000",
  mealTicketId: "550e8400-e29b-41d4-a716-446655440001",
  orderType: "SCHEDULED",
  totalPrice: 25.0
};

const parsed = zCreateOrderRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: order, error } = await canteenStaff.createOrder({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// order is typed as OrderResponse

getOrder()

Get an order with items and student info

GET /api/canteen/orders/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: OrderDetailResponse (200)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
student StudentSummary Student summary for order context
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date) Date the order is scheduled for "2026-01-15"
items OrderItemDetailResponse[] Items included in this order
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
cancelledAt string (date-time) When the order was cancelled "2026-01-15T10:00:00Z"
cancelledBy string (uuid) ID of the user who cancelled the order "550e8400-e29b-41d4-a716-446655440000"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

StudentSummary fields:

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
firstName string Student's first name "Kofi"
lastName string Student's last name "Asante"
className string Name of the student's class "Grade 3A"

OrderItemDetailResponse fields:

Field Type Description Example
id string (uuid) Order item ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the ordered item "550e8400-e29b-41d4-a716-446655440000"
itemName string Name of the ordered item "Jollof Rice"
variantId string (uuid) ID of the selected variant "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the selected variant "Large"
menuSectionId string (uuid) ID of the menu section this item was ordered from "550e8400-e29b-41d4-a716-446655440000"
sectionName string Name of the menu section "Lunch Main Course"
quantity integer (int32) Quantity ordered 2
unitPrice number Unit price at time of order 12.5
currency string Currency code "GHS"
served boolean Whether this item has been served
servedAt string (date-time) When the item was served "2026-01-15T12:30:00Z"
servedBy integer (int64) ID of the user who served the item 42
servedByName string Name of the user who served the item "Abena Mensah"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { OrderDetailResponse } from '@smartsapp/sdk/staff';

const { data: orderDetail, error } = await canteenStaff.getOrder({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// orderDetail is typed as OrderDetailResponse

updateMenuSection()

Update a menu section

PUT /api/canteen/menus/{menuId}/sections/{sectionId}

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateMenuSectionRequest

Field Type Required Description
name string No Name of the section
servingStartTime string No Start of serving window
servingEndTime string No End of serving window
selectionMode "SINGLE" | "MULTIPLE" No Selection mode: SINGLE (one item per order) or MULTIPLE (many items per order)
themeColor string No Hex color code for theming

Response: MenuSectionResponse (200)

Field Type Description Example
id string (uuid) Menu section ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the parent menu "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Lunch Main Course"
servingStartTime string Start of serving window "12:00:00"
servingEndTime string End of serving window "13:30:00"
selectionMode "SINGLE" | "MULTIPLE" How students select items: SINGLE or MULTIPLE "SINGLE"
themeColor string Hex colour code for theming "#FF5733"
createdAt string (date-time) When the section was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the section was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateMenuSectionRequest } from '@smartsapp/sdk/staff';
import type { UpdateMenuSectionRequest, MenuSectionResponse } from '@smartsapp/sdk/staff';

const input: UpdateMenuSectionRequest = {
  name: "Lunch",
  servingStartTime: "12:00:00",
  servingEndTime: "13:30:00",
  selectionMode: "SINGLE"
};

const parsed = zUpdateMenuSectionRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: menuSection, error } = await canteenStaff.updateMenuSection({
  body: input,
  path: { menuId: "...", sectionId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menuSection is typed as MenuSectionResponse

deleteMenuSection()

Delete a menu section

DELETE /api/canteen/menus/{menuId}/sections/{sectionId}

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteMenuSection({
  path: { menuId: "...", sectionId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listMenuSections()

List sections for a menu

GET /api/canteen/menus/{menuId}/sections

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuSectionResponse[] (200)

Field Type Description Example
id string (uuid) Menu section ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the parent menu "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Lunch Main Course"
servingStartTime string Start of serving window "12:00:00"
servingEndTime string End of serving window "13:30:00"
selectionMode "SINGLE" | "MULTIPLE" How students select items: SINGLE or MULTIPLE "SINGLE"
themeColor string Hex colour code for theming "#FF5733"
createdAt string (date-time) When the section was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the section was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.listMenuSections({
  path: { menuId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as MenuSectionResponse[]

createMenuSection()

Add a section to a menu

POST /api/canteen/menus/{menuId}/sections

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateMenuSectionRequest

Field Type Required Description
name string Yes Name of the section
servingStartTime string No Start of serving window
servingEndTime string No End of serving window
selectionMode "SINGLE" | "MULTIPLE" Yes Selection mode: SINGLE (one item per order) or MULTIPLE (many items per order)
themeColor string No Hex color code for theming

Response: MenuSectionResponse (201)

Field Type Description Example
id string (uuid) Menu section ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the parent menu "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Lunch Main Course"
servingStartTime string Start of serving window "12:00:00"
servingEndTime string End of serving window "13:30:00"
selectionMode "SINGLE" | "MULTIPLE" How students select items: SINGLE or MULTIPLE "SINGLE"
themeColor string Hex colour code for theming "#FF5733"
createdAt string (date-time) When the section was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the section was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateMenuSectionRequest } from '@smartsapp/sdk/staff';
import type { CreateMenuSectionRequest, MenuSectionResponse } from '@smartsapp/sdk/staff';

const input: CreateMenuSectionRequest = {
  name: "Lunch",
  servingStartTime: "12:00:00",
  servingEndTime: "13:30:00",
  selectionMode: "SINGLE"
};

const parsed = zCreateMenuSectionRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: menuSection, error } = await canteenStaff.createMenuSection({
  body: input,
  path: { menuId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menuSection is typed as MenuSectionResponse

getMenu()

Get a menu by ID

GET /api/canteen/menus/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuResponse (200)

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { MenuResponse } from '@smartsapp/sdk/staff';

const { data: menu, error } = await canteenStaff.getMenu({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menu is typed as MenuResponse

updateMenu()

Update a menu

PUT /api/canteen/menus/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateMenuRequest

Field Type Required Description
name string Yes Name of the menu
description string No Description of the menu
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Yes Purpose of the menu: PARENTS_CAN_ORDER (ordering enabled) or INFO_ONLY (view only)
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" No Payment type for the menu. Only applies when purpose is PARENTS_CAN_ORDER.
startDate string (date) Yes Start date of the menu
endDate string (date) Yes End date of the menu
orderingDeadlineType "DAILY" | "WEEKLY" No Type of ordering deadline. Only applies when purpose is PARENTS_CAN_ORDER.
dailyCutoffTime string No Daily cutoff time for orders. Only applies when orderingDeadlineType is DAILY.
dailyCutoffDays integer (int32) No Number of days before the meal day the daily cutoff applies. Only applies when orderingDeadlineType is DAILY. Null or 0 means same-day cutoff.
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" No Weekly cutoff day for orders. Only applies when orderingDeadlineType is WEEKLY.
weeklyCutoffTime string No Weekly cutoff time of day. Only applies when orderingDeadlineType is WEEKLY.
orderCancellationHours integer (int32) No Hours before which an order can be cancelled. Only applies when purpose is PARENTS_CAN_ORDER.
audience "ALL" | "SPECIFIC" Yes Who can see this menu: ALL or SPECIFIC
targetCampusIds string (uuid)[] No Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] No Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] No Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] No Individual student IDs to exclude from this menu
visibilityDays integer (int32) Yes How many days ahead of today parents can see this menu in the Parent App. Range 1–30.

Response: MenuResponse (200)

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateMenuRequest } from '@smartsapp/sdk/staff';
import type { UpdateMenuRequest, MenuResponse } from '@smartsapp/sdk/staff';

const input: UpdateMenuRequest = {
  name: "Weekly Lunch Menu",
  description: "Standard weekly lunch offerings",
  purpose: "PARENTS_CAN_ORDER",
  paymentType: "ORDER_AND_PAY_ITEM_PRICING"
};

const parsed = zUpdateMenuRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: menu, error } = await canteenStaff.updateMenu({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menu is typed as MenuResponse

deleteMenu()

Delete a menu

DELETE /api/canteen/menus/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteMenu({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

unpublishMenu()

Unpublish a menu

PUT /api/canteen/menus/{id}/unpublish

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuResponse (200)

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { MenuResponse } from '@smartsapp/sdk/staff';

const { data: menu, error } = await canteenStaff.unpublishMenu({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menu is typed as MenuResponse

publishMenu()

Publish a menu

PUT /api/canteen/menus/{id}/publish

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuResponse (200)

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { MenuResponse } from '@smartsapp/sdk/staff';

const { data: menu, error } = await canteenStaff.publishMenu({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menu is typed as MenuResponse

listMenus()

List menus with pagination

GET /api/canteen/menus

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseMenuResponse (200)

Field Type Description Example
content MenuResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

MenuResponse fields:

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseMenuResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listMenus({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const menus = result.content;           // MenuResponse[]
const { page, totalPages, totalElements, last } = result;

createMenu()

Create a new menu

POST /api/canteen/menus

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateMenuRequest

Field Type Required Description
name string Yes Name of the menu
description string No Description of the menu
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Yes Purpose of the menu: PARENTS_CAN_ORDER (ordering enabled) or INFO_ONLY (view only)
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" No Payment type for the menu. Only applies when purpose is PARENTS_CAN_ORDER.
startDate string (date) Yes Start date of the menu
endDate string (date) Yes End date of the menu
orderingDeadlineType "DAILY" | "WEEKLY" No Type of ordering deadline. Only applies when purpose is PARENTS_CAN_ORDER.
dailyCutoffTime string No Daily cutoff time for orders. Only applies when orderingDeadlineType is DAILY.
dailyCutoffDays integer (int32) No Number of days before the meal day the daily cutoff applies. Only applies when orderingDeadlineType is DAILY. Null or 0 means same-day cutoff.
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" No Weekly cutoff day for orders. Only applies when orderingDeadlineType is WEEKLY.
weeklyCutoffTime string No Weekly cutoff time of day. Only applies when orderingDeadlineType is WEEKLY.
orderCancellationHours integer (int32) No Hours before which an order can be cancelled. Only applies when purpose is PARENTS_CAN_ORDER.
audience "ALL" | "SPECIFIC" Yes Who can see this menu: ALL or SPECIFIC
targetCampusIds string (uuid)[] No Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] No Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] No Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] No Individual student IDs to exclude from this menu, even if they belong to a targeted campus/class
visibilityDays integer (int32) Yes How many days ahead of today parents can see this menu in the Parent App. Range 1–30.

Response: MenuResponse (201)

Field Type Description Example
id string (uuid) Menu ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the menu "Term 1 Lunch Menu"
description string Description of the menu "Daily lunch options for Term 1"
purpose "INFO_ONLY" | "PARENTS_CAN_ORDER" Purpose of the menu: LUNCH, BREAKFAST, SNACK "INFO_ONLY"
paymentType "ORDER_AND_PAY_ITEM_PRICING" | "ORDER_ONLY_NO_PAYMENT" | "ORDER_AND_PAY_TICKET_PRICING" Payment type: PREPAID, POSTPAID "ORDER_AND_PAY_ITEM_PRICING"
startDate string (date) First day the menu is active "2026-01-06"
endDate string (date) Last day the menu is active "2026-03-28"
orderingDeadlineType "DAILY" | "WEEKLY" Deadline type for ordering: DAILY, WEEKLY, NONE "DAILY"
dailyCutoffTime string Daily cutoff time for pre-orders "08:00:00"
dailyCutoffDays integer (int32) Number of days before the meal day the daily cutoff applies 2
weeklyCutoffDay "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY" Weekly cutoff day for pre-orders "MONDAY"
weeklyCutoffTime string Weekly cutoff time of day "23:59:00"
orderCancellationHours integer (int32) Hours before scheduled date that cancellation is allowed 24
published boolean Whether the menu is published and visible to parents
audience "ALL" | "SPECIFIC" Who can see this menu: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetSectionIds string (uuid)[] Target section IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom/grade IDs when audience is SPECIFIC
excludedStudentIds string (uuid)[] Individual student IDs excluded from this menu
visibilityDays integer (int32) How many days ahead of today parents can see this menu in the Parent App 30
updatedBy string (uuid) ID of the user who last updated this menu "550e8400-e29b-41d4-a716-446655440000"
updatedByName string Name of the user who last updated this menu "Abena Mensah"
createdAt string (date-time) When the menu was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the menu was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateMenuRequest } from '@smartsapp/sdk/staff';
import type { CreateMenuRequest, MenuResponse } from '@smartsapp/sdk/staff';

const input: CreateMenuRequest = {
  name: "Weekly Lunch Menu",
  description: "Standard weekly lunch offerings",
  purpose: "PARENTS_CAN_ORDER",
  paymentType: "ORDER_AND_PAY_ITEM_PRICING"
};

const parsed = zCreateMenuRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: menu, error } = await canteenStaff.createMenu({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menu is typed as MenuResponse

getFullMenuSchedule()

Get full menu schedule

GET /api/canteen/menus/{id}/schedule

Parameters:

Name Type In Required Description
id string (uuid) path Yes
startDate string (date) query Yes
endDate string (date) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuFullScheduleResponse (200)

Field Type Description Example
menuId string (uuid) ID of the menu "550e8400-e29b-41d4-a716-446655440000"
sections SectionScheduleResponse[] Sections with their scheduled items

SectionScheduleResponse fields:

Field Type Description Example
sectionId string (uuid) ID of the menu section "550e8400-e29b-41d4-a716-446655440000"
sectionName string Name of the menu section "Lunch Main Course"
servingStartTime string Serving start time "11:30:00"
servingEndTime string Serving end time "13:30:00"
selectionMode "SINGLE" | "MULTIPLE" How students select items: SINGLE or MULTIPLE "SINGLE"
schedule MenuScheduleGroupedResponse[] Schedule entries grouped by date

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { MenuFullScheduleResponse } from '@smartsapp/sdk/staff';

const { data: menuFullSchedule, error } = await canteenStaff.getFullMenuSchedule({
  path: { id: "..." },
  query: { startDate: "2026-01-01", endDate: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menuFullSchedule is typed as MenuFullScheduleResponse

Meal Tickets

getMealTicket()

Get a meal ticket by ID

GET /api/canteen/meal-tickets/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MealTicketResponse (200)

Field Type Description Example
id string (uuid) Meal ticket ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the menu this ticket is linked to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the meal ticket "Term 1 Lunch Pass"
academicTermId string (uuid) ID of the academic term "550e8400-e29b-41d4-a716-446655440000"
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" How the ticket price is calculated: UNIFORM, ITEM_BASED "DAILY"
pricingScheme "UNIFORM" | "DIFFERENTIAL" Pricing scheme: PER_MEAL, FLAT_RATE "UNIFORM"
uniformPrice number Uniform price when pricing method is UNIFORM 500.0
active boolean Whether the meal ticket is currently active
createdAt string (date-time) When the ticket was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the ticket was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { MealTicketResponse } from '@smartsapp/sdk/staff';

const { data: mealTicket, error } = await canteenStaff.getMealTicket({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// mealTicket is typed as MealTicketResponse

updateMealTicket()

Update a meal ticket

PUT /api/canteen/meal-tickets/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateMealTicketRequest

Field Type Required Description
menuId string (uuid) No ID of the associated menu
name string No Name of the meal ticket
academicTermId string (uuid) No ID of the academic term
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" No Pricing method for the meal ticket
pricingScheme "UNIFORM" | "DIFFERENTIAL" No Pricing scheme for the meal ticket
uniformPrice number No Uniform price if applicable

Response: MealTicketResponse (200)

Field Type Description Example
id string (uuid) Meal ticket ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the menu this ticket is linked to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the meal ticket "Term 1 Lunch Pass"
academicTermId string (uuid) ID of the academic term "550e8400-e29b-41d4-a716-446655440000"
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" How the ticket price is calculated: UNIFORM, ITEM_BASED "DAILY"
pricingScheme "UNIFORM" | "DIFFERENTIAL" Pricing scheme: PER_MEAL, FLAT_RATE "UNIFORM"
uniformPrice number Uniform price when pricing method is UNIFORM 500.0
active boolean Whether the meal ticket is currently active
createdAt string (date-time) When the ticket was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the ticket was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateMealTicketRequest } from '@smartsapp/sdk/staff';
import type { UpdateMealTicketRequest, MealTicketResponse } from '@smartsapp/sdk/staff';

const input: UpdateMealTicketRequest = {
  menuId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Term 1 Lunch Pass",
  academicTermId: "550e8400-e29b-41d4-a716-446655440001",
  pricingMethod: "UNIFORM"
};

const parsed = zUpdateMealTicketRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: mealTicket, error } = await canteenStaff.updateMealTicket({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// mealTicket is typed as MealTicketResponse

deleteMealTicket()

Delete a meal ticket

DELETE /api/canteen/meal-tickets/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteMealTicket({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listMealTickets()

List meal tickets with pagination

GET /api/canteen/meal-tickets

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseMealTicketResponse (200)

Field Type Description Example
content MealTicketResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

MealTicketResponse fields:

Field Type Description Example
id string (uuid) Meal ticket ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the menu this ticket is linked to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the meal ticket "Term 1 Lunch Pass"
academicTermId string (uuid) ID of the academic term "550e8400-e29b-41d4-a716-446655440000"
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" How the ticket price is calculated: UNIFORM, ITEM_BASED "DAILY"
pricingScheme "UNIFORM" | "DIFFERENTIAL" Pricing scheme: PER_MEAL, FLAT_RATE "UNIFORM"
uniformPrice number Uniform price when pricing method is UNIFORM 500.0
active boolean Whether the meal ticket is currently active
createdAt string (date-time) When the ticket was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the ticket was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseMealTicketResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listMealTickets({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const mealTickets = result.content;           // MealTicketResponse[]
const { page, totalPages, totalElements, last } = result;

createMealTicket()

Create a new meal ticket

POST /api/canteen/meal-tickets

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateMealTicketRequest

Field Type Required Description
menuId string (uuid) Yes ID of the associated menu
name string Yes Name of the meal ticket
academicTermId string (uuid) Yes ID of the academic term
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" Yes Pricing method for the meal ticket
pricingScheme "UNIFORM" | "DIFFERENTIAL" Yes Pricing scheme for the meal ticket
uniformPrice number No Uniform price if applicable

Response: MealTicketResponse (201)

Field Type Description Example
id string (uuid) Meal ticket ID "550e8400-e29b-41d4-a716-446655440000"
menuId string (uuid) ID of the menu this ticket is linked to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the meal ticket "Term 1 Lunch Pass"
academicTermId string (uuid) ID of the academic term "550e8400-e29b-41d4-a716-446655440000"
pricingMethod "DAILY" | "MONTHLY" | "TERMLY" How the ticket price is calculated: UNIFORM, ITEM_BASED "DAILY"
pricingScheme "UNIFORM" | "DIFFERENTIAL" Pricing scheme: PER_MEAL, FLAT_RATE "UNIFORM"
uniformPrice number Uniform price when pricing method is UNIFORM 500.0
active boolean Whether the meal ticket is currently active
createdAt string (date-time) When the ticket was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the ticket was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateMealTicketRequest } from '@smartsapp/sdk/staff';
import type { CreateMealTicketRequest, MealTicketResponse } from '@smartsapp/sdk/staff';

const input: CreateMealTicketRequest = {
  menuId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Term 1 Lunch Pass",
  academicTermId: "550e8400-e29b-41d4-a716-446655440001",
  pricingMethod: "UNIFORM"
};

const parsed = zCreateMealTicketRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: mealTicket, error } = await canteenStaff.createMealTicket({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// mealTicket is typed as MealTicketResponse

Item Variants

updateItemVariant()

Update a variant

PUT /api/canteen/items/{itemId}/variants/{variantId}

Parameters:

Name Type In Required Description
itemId string (uuid) path Yes
variantId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateItemVariantRequest

Field Type Required Description
variantName string No Variant name
price number No Variant price
audience "ALL" | "SPECIFIC" No Audience scope
targetCampusIds string (uuid)[] No Campus IDs this variant is available to. Required when audience is SPECIFIC.
targetClassroomIds string (uuid)[] No Class/grade IDs this variant is available to. Required when audience is SPECIFIC.

Response: ItemVariantResponse (200)

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateItemVariantRequest } from '@smartsapp/sdk/staff';
import type { UpdateItemVariantRequest, ItemVariantResponse } from '@smartsapp/sdk/staff';

const input: UpdateItemVariantRequest = {
  variantName: "Small",
  price: 5.0,
  audience: "ALL",
  targetCampusIds: []
};

const parsed = zUpdateItemVariantRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: itemVariant, error } = await canteenStaff.updateItemVariant({
  body: input,
  path: { itemId: "...", variantId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemVariant is typed as ItemVariantResponse

deleteItemVariant()

Delete a variant

DELETE /api/canteen/items/{itemId}/variants/{variantId}

Parameters:

Name Type In Required Description
itemId string (uuid) path Yes
variantId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteItemVariant({
  path: { itemId: "...", variantId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listItemVariants()

List variants for an item

GET /api/canteen/items/{itemId}/variants

Parameters:

Name Type In Required Description
itemId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ItemVariantResponse[] (200)

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.listItemVariants({
  path: { itemId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as ItemVariantResponse[]

createItemVariant()

Add a variant to an item

POST /api/canteen/items/{itemId}/variants

Parameters:

Name Type In Required Description
itemId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateItemVariantRequest

Field Type Required Description
variantName string Yes Variant name
price number Yes Variant price
audience "ALL" | "SPECIFIC" Yes Audience scope
targetCampusIds string (uuid)[] No Campus IDs this variant is available to. Required when audience is SPECIFIC.
targetClassroomIds string (uuid)[] No Class/grade IDs this variant is available to. Required when audience is SPECIFIC.

Response: ItemVariantResponse (201)

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateItemVariantRequest } from '@smartsapp/sdk/staff';
import type { CreateItemVariantRequest, ItemVariantResponse } from '@smartsapp/sdk/staff';

const input: CreateItemVariantRequest = {
  variantName: "Small",
  price: 5.0,
  audience: "ALL",
  targetCampusIds: []
};

const parsed = zCreateItemVariantRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: itemVariant, error } = await canteenStaff.createItemVariant({
  body: input,
  path: { itemId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemVariant is typed as ItemVariantResponse

Items

getItem()

Get a item by ID

GET /api/canteen/items/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ItemResponse (200)

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

ItemVariantResponse fields:

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

CreatedBySummary fields:

Field Type Description Example
id string (uuid) User ID of the creator "550e8400-e29b-41d4-a716-446655440000"
firstName string Creator's first name "Abena"
lastName string Creator's last name "Mensah"
type string Creator type: STAFF or PARENT "STAFF"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { ItemResponse } from '@smartsapp/sdk/staff';

const { data: item, error } = await canteenStaff.getItem({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// item is typed as ItemResponse

updateItem()

Update a item

PUT /api/canteen/items/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateItemRequest

Field Type Required Description
cateringServiceId string (uuid) No ID of the catering service
itemCategoryId string (uuid) No ID of the item category
name string No Name of the item
image string No URL of the item image
description string No Description of the item
allergens string No Allergen information
maxQuantityPerDay integer (int32) No Maximum quantity of this item a single student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap).
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" No Pricing style for the item
defaultPrice number No Default price of the item
variants CreateItemVariantRequest[] No Variants for VARIANT pricing style. Ignored for FIXED/NO_PRICE.

CreateItemVariantRequest fields:

Field Type Required Description
variantName string Yes Variant name
price number Yes Variant price
audience "ALL" | "SPECIFIC" Yes Audience scope
targetCampusIds string (uuid)[] No Campus IDs this variant is available to. Required when audience is SPECIFIC.
targetClassroomIds string (uuid)[] No Class/grade IDs this variant is available to. Required when audience is SPECIFIC.

Response: ItemResponse (200)

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

ItemVariantResponse fields:

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

CreatedBySummary fields:

Field Type Description Example
id string (uuid) User ID of the creator "550e8400-e29b-41d4-a716-446655440000"
firstName string Creator's first name "Abena"
lastName string Creator's last name "Mensah"
type string Creator type: STAFF or PARENT "STAFF"

Example:

import { canteenStaff, zUpdateItemRequest } from '@smartsapp/sdk/staff';
import type { UpdateItemRequest, ItemResponse } from '@smartsapp/sdk/staff';

const input: UpdateItemRequest = {
  cateringServiceId: "550e8400-e29b-41d4-a716-446655440000",
  itemCategoryId: "550e8400-e29b-41d4-a716-446655440001",
  name: "Jollof Rice",
  image: "https://example.com/jollof.png"
};

const parsed = zUpdateItemRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: item, error } = await canteenStaff.updateItem({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// item is typed as ItemResponse

deleteItem()

Delete a item

DELETE /api/canteen/items/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteItem({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listItems()

List items with pagination and optional filters

GET /api/canteen/items

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
cateringServiceId string (uuid) query No Filter by catering service
itemCategoryId string (uuid) query No Filter by item category
search string query No Search by item name
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseItemResponse (200)

Field Type Description Example
content ItemResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

ItemResponse fields:

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseItemResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listItems({
  query: { page: 0, size: 0, cateringServiceId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const items = result.content;           // ItemResponse[]
const { page, totalPages, totalElements, last } = result;

createItem()

Create a new item

POST /api/canteen/items

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateItemRequest

Field Type Required Description
cateringServiceId string (uuid) Yes ID of the catering service
itemCategoryId string (uuid) Yes ID of the item category
name string Yes Name of the item
image string No URL of the item image
description string No Description of the item
allergens string No Allergen information
maxQuantityPerDay integer (int32) No Maximum quantity of this item a single student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap).
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" Yes Pricing style for the item
defaultPrice number No Default price of the item
variants CreateItemVariantRequest[] No Variants for VARIANT pricing style. Ignored for FIXED/NO_PRICE.

CreateItemVariantRequest fields:

Field Type Required Description
variantName string Yes Variant name
price number Yes Variant price
audience "ALL" | "SPECIFIC" Yes Audience scope
targetCampusIds string (uuid)[] No Campus IDs this variant is available to. Required when audience is SPECIFIC.
targetClassroomIds string (uuid)[] No Class/grade IDs this variant is available to. Required when audience is SPECIFIC.

Response: ItemResponse (201)

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

ItemVariantResponse fields:

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

CreatedBySummary fields:

Field Type Description Example
id string (uuid) User ID of the creator "550e8400-e29b-41d4-a716-446655440000"
firstName string Creator's first name "Abena"
lastName string Creator's last name "Mensah"
type string Creator type: STAFF or PARENT "STAFF"

Example:

import { canteenStaff, zCreateItemRequest } from '@smartsapp/sdk/staff';
import type { CreateItemRequest, ItemResponse } from '@smartsapp/sdk/staff';

const input: CreateItemRequest = {
  cateringServiceId: "550e8400-e29b-41d4-a716-446655440000",
  itemCategoryId: "550e8400-e29b-41d4-a716-446655440001",
  name: "Jollof Rice",
  image: "https://example.com/jollof.png"
};

const parsed = zCreateItemRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: item, error } = await canteenStaff.createItem({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// item is typed as ItemResponse

listRecentlyUsedItems()

List items recently scheduled on menus (last 30 days)

GET /api/canteen/items/recently-used

Parameters:

Name Type In Required Description
limit integer (int32) query No Max number of items to return
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ItemResponse[] (200)

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

ItemVariantResponse fields:

Field Type Description Example
id string (uuid) Variant ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the parent item "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the variant "Large"
price number Price of this variant 15.0
audience "ALL" | "SPECIFIC" Who can see this variant: ALL or SPECIFIC "ALL"
targetCampusIds string (uuid)[] Target campus IDs when audience is SPECIFIC
targetClassroomIds string (uuid)[] Target classroom IDs when audience is SPECIFIC
createdAt string (date-time) When the variant was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the variant was last updated "2026-01-15T10:30:00Z"

CreatedBySummary fields:

Field Type Description Example
id string (uuid) User ID of the creator "550e8400-e29b-41d4-a716-446655440000"
firstName string Creator's first name "Abena"
lastName string Creator's last name "Mensah"
type string Creator type: STAFF or PARENT "STAFF"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.listRecentlyUsedItems({
  query: { limit: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as ItemResponse[]

getItemLibrary()

Get item library with recently used items and items grouped by category

GET /api/canteen/items/library

Parameters:

Name Type In Required Description
cateringServiceId string (uuid) query No Filter by catering service
search string query No Search by item name
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ItemLibraryResponse (200)

Field Type Description Example
recentlyUsed ItemResponse[] Items recently scheduled on menus (last 30 days)
categories CategoryGroup[] All items grouped by category

ItemResponse fields:

Field Type Description Example
id string (uuid) Item ID "550e8400-e29b-41d4-a716-446655440000"
cateringServiceId string (uuid) ID of the catering service that supplies this item "550e8400-e29b-41d4-a716-446655440000"
itemCategoryId string (uuid) ID of the item's category "550e8400-e29b-41d4-a716-446655440000"
categoryName string Name of the item's category "Beverages"
name string Name of the item "Jollof Rice"
image string URL of the item image "https://storage.example.com/items/jollof.jpg"
description string Description of the item "Spicy tomato-based rice dish"
allergens string Comma-separated list of allergens "gluten, peanuts"
maxQuantityPerDay integer (int32) Maximum quantity a student can order per day (cumulative across all orders for the same date). Null means unlimited (no daily cap). 3
pricingStyle "FIXED" | "VARIANT" | "NO_PRICE" How this item is priced: UNIFORM or VARIANT "FIXED"
defaultPrice number Default price when pricing style is UNIFORM 12.5
currency string Currency code "GHS"
variants ItemVariantResponse[] Available variants for this item
createdBy CreatedBySummary Summary of who created the order
createdAt string (date-time) When the item was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the item was last updated "2026-01-15T10:30:00Z"

CategoryGroup fields:

Field Type Description Example
id string (uuid) Category ID "550e8400-e29b-41d4-a716-446655440000"
name string Category name "Beverages"
themeColor string Theme colour hex code for the category "#FF5733"
items ItemResponse[] Items belonging to this category

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { ItemLibraryResponse } from '@smartsapp/sdk/staff';

const { data: itemLibrary, error } = await canteenStaff.getItemLibrary({
  query: { cateringServiceId: "...", search: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemLibrary is typed as ItemLibraryResponse

Item Categories

getItemCategory()

Get an item category by ID

GET /api/canteen/item-categories/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ItemCategoryResponse (200)

Field Type Description Example
id string (uuid) Item category ID "550e8400-e29b-41d4-a716-446655440000"
name string Category name "Beverages"
description string Description of the category "All drink items"
themeColor string Theme colour hex code "#FF5733"
totalItems integer (int64) Number of items in this category 12
createdAt string (date-time) When the category was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the category was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { ItemCategoryResponse } from '@smartsapp/sdk/staff';

const { data: itemCategory, error } = await canteenStaff.getItemCategory({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemCategory is typed as ItemCategoryResponse

updateItemCategory()

Update an item category

PUT /api/canteen/item-categories/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateItemCategoryRequest

Field Type Required Description
name string No Name of the item category
description string No Description of the item category
themeColor string No Theme color hex code

Response: ItemCategoryResponse (200)

Field Type Description Example
id string (uuid) Item category ID "550e8400-e29b-41d4-a716-446655440000"
name string Category name "Beverages"
description string Description of the category "All drink items"
themeColor string Theme colour hex code "#FF5733"
totalItems integer (int64) Number of items in this category 12
createdAt string (date-time) When the category was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the category was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateItemCategoryRequest } from '@smartsapp/sdk/staff';
import type { UpdateItemCategoryRequest, ItemCategoryResponse } from '@smartsapp/sdk/staff';

const input: UpdateItemCategoryRequest = {
  name: "Beverages",
  description: "Drinks and refreshments",
  themeColor: "#FF5733"
};

const parsed = zUpdateItemCategoryRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: itemCategory, error } = await canteenStaff.updateItemCategory({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemCategory is typed as ItemCategoryResponse

deleteItemCategory()

Delete an item category

DELETE /api/canteen/item-categories/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteItemCategory({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listItemCategories()

List item categories with pagination

GET /api/canteen/item-categories

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseItemCategoryResponse (200)

Field Type Description Example
content ItemCategoryResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

ItemCategoryResponse fields:

Field Type Description Example
id string (uuid) Item category ID "550e8400-e29b-41d4-a716-446655440000"
name string Category name "Beverages"
description string Description of the category "All drink items"
themeColor string Theme colour hex code "#FF5733"
totalItems integer (int64) Number of items in this category 12
createdAt string (date-time) When the category was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the category was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseItemCategoryResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listItemCategories({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const itemCategorys = result.content;           // ItemCategoryResponse[]
const { page, totalPages, totalElements, last } = result;

createItemCategory()

Create a new item category

POST /api/canteen/item-categories

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateItemCategoryRequest

Field Type Required Description
name string Yes Name of the item category
description string No Description of the item category
themeColor string No Theme color hex code

Response: ItemCategoryResponse (201)

Field Type Description Example
id string (uuid) Item category ID "550e8400-e29b-41d4-a716-446655440000"
name string Category name "Beverages"
description string Description of the category "All drink items"
themeColor string Theme colour hex code "#FF5733"
totalItems integer (int64) Number of items in this category 12
createdAt string (date-time) When the category was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the category was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateItemCategoryRequest } from '@smartsapp/sdk/staff';
import type { CreateItemCategoryRequest, ItemCategoryResponse } from '@smartsapp/sdk/staff';

const input: CreateItemCategoryRequest = {
  name: "Beverages",
  description: "Drinks and refreshments",
  themeColor: "#FF5733"
};

const parsed = zCreateItemCategoryRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: itemCategory, error } = await canteenStaff.createItemCategory({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// itemCategory is typed as ItemCategoryResponse

Feeding List

bulkRedeemOrders()

Bulk redeem multiple orders

PUT /api/canteen/feeding-list/bulk-redeem

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: BulkRedeemRequest

Field Type Required Description
orderIds string (uuid)[] Yes List of order IDs to redeem

Response: FeedingListEntryResponse[] (200)

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
student StudentSummary Student summary for order context
createdBy CreatedBySummary Summary of who created the order
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
currency string Currency code "GHS"
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date-time) Date and time the order is scheduled for "2026-01-15T12:00:00"
items OrderItemDetailResponse[] Items included in this order
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

StudentSummary fields:

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
firstName string Student's first name "Kofi"
lastName string Student's last name "Asante"
className string Name of the student's class "Grade 3A"

CreatedBySummary fields:

Field Type Description Example
id string (uuid) User ID of the creator "550e8400-e29b-41d4-a716-446655440000"
firstName string Creator's first name "Abena"
lastName string Creator's last name "Mensah"
type string Creator type: STAFF or PARENT "STAFF"

OrderItemDetailResponse fields:

Field Type Description Example
id string (uuid) Order item ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the ordered item "550e8400-e29b-41d4-a716-446655440000"
itemName string Name of the ordered item "Jollof Rice"
variantId string (uuid) ID of the selected variant "550e8400-e29b-41d4-a716-446655440000"
variantName string Name of the selected variant "Large"
menuSectionId string (uuid) ID of the menu section this item was ordered from "550e8400-e29b-41d4-a716-446655440000"
sectionName string Name of the menu section "Lunch Main Course"
quantity integer (int32) Quantity ordered 2
unitPrice number Unit price at time of order 12.5
currency string Currency code "GHS"
served boolean Whether this item has been served
servedAt string (date-time) When the item was served "2026-01-15T12:30:00Z"
servedBy integer (int64) ID of the user who served the item 42
servedByName string Name of the user who served the item "Abena Mensah"

Example:

import { canteenStaff, zBulkRedeemRequest } from '@smartsapp/sdk/staff';
import type { BulkRedeemRequest } from '@smartsapp/sdk/staff';

const input: BulkRedeemRequest = {
  orderIds: []
};

const parsed = zBulkRedeemRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data, error } = await canteenStaff.bulkRedeemOrders({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as FeedingListEntryResponse[]

listFeedingEntries()

List feeding list entries with pagination and filters

GET /api/canteen/feeding-list

Parameters:

Name Type In Required Description
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED"[] query No
orderType "TICKET" | "PRE_ORDER" | "POS"[] query No
dateFrom string (date) query No
dateTo string (date) query No
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION"[] query No
personnelId string (uuid) query No
studentName string query No
itemName string query No
classroomId string (uuid) query No
sectionId string (uuid) query No
campusId string (uuid) query No
menuId string (uuid) query No
categoryId string (uuid) query No
cateringServiceId string (uuid) query No
attendanceStatus "PRESENT" | "ABSENT" | "LATE" | "EXCUSED" query No
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseFeedingListEntryResponse (200)

Field Type Description Example
content FeedingListEntryResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

FeedingListEntryResponse fields:

Field Type Description Example
id string (uuid) Order ID "550e8400-e29b-41d4-a716-446655440000"
orderNumber string Human-readable order number "ORD-20260115-001"
student StudentSummary Student summary for order context
createdBy CreatedBySummary Summary of who created the order
orderType "TICKET" | "PRE_ORDER" | "POS" Type of order: WALK_IN or PRE_ORDER "TICKET"
totalPrice number Total price of the order 25.0
currency string Currency code "GHS"
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" How the order was paid: CASH, MEAL_TICKET, MOBILE_MONEY "SIKA_ID"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status: DRAFT, CONFIRMED, SERVED, CANCELLED "DRAFT"
scheduledDate string (date-time) Date and time the order is scheduled for "2026-01-15T12:00:00"
items OrderItemDetailResponse[] Items included in this order
redeemedAt string (date-time) When the order was redeemed/served "2026-01-15T12:30:00Z"
createdAt string (date-time) When the order was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the order was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseFeedingListEntryResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listFeedingEntries({
  query: { status: "...", orderType: "...", dateFrom: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const feedingListEntrys = result.content;           // FeedingListEntryResponse[]
const { page, totalPages, totalElements, last } = result;

exportFeedingList()

Export feeding list as Excel

GET /api/canteen/feeding-list/export

Parameters:

Name Type In Required Description
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED"[] query No
orderType "TICKET" | "PRE_ORDER" | "POS"[] query No
dateFrom string (date) query No
dateTo string (date) query No
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION"[] query No
personnelId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportFeedingList({
  query: { status: "...", orderType: "...", dateFrom: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

Catering Services

getCateringService()

Get a catering service by ID

GET /api/canteen/catering-services/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: CateringServiceResponse (200)

Field Type Description Example
id string (uuid) Catering service ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the catering service "ABC Catering"
logo string URL of the catering service logo "https://storage.example.com/logos/abc.png"
email string Contact email address "[email protected]"
phone string Contact phone number "+233501234567"
settlementAccountType "BANK" | "MOBILE_MONEY" Settlement account type (null if not configured) "BANK"
settlementAccountName string Account holder name on the settlement account "ABC Catering Ltd"
settlementAccountNumber string Bank account number or mobile money number 1234567890
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" Bank (when settlementAccountType=BANK) "GCB_BANK"
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" Mobile money provider (when settlementAccountType=MOBILE_MONEY) "MTN"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { CateringServiceResponse } from '@smartsapp/sdk/staff';

const { data: cateringService, error } = await canteenStaff.getCateringService({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// cateringService is typed as CateringServiceResponse

updateCateringService()

Update a catering service

PUT /api/canteen/catering-services/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateCateringServiceRequest

Field Type Required Description
name string No Name of the catering service
logo string No URL of the catering service logo
email string No Contact email address
phone string No Contact phone number
settlementAccountType "BANK" | "MOBILE_MONEY" No Settlement account type. Null clears settlement details.
settlementAccountName string No Account holder name on the settlement account
settlementAccountNumber string No Bank account number or mobile money number
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" No Bank (required when settlementAccountType=BANK)
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" No Mobile money provider (required when settlementAccountType=MOBILE_MONEY)

Response: CateringServiceResponse (200)

Field Type Description Example
id string (uuid) Catering service ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the catering service "ABC Catering"
logo string URL of the catering service logo "https://storage.example.com/logos/abc.png"
email string Contact email address "[email protected]"
phone string Contact phone number "+233501234567"
settlementAccountType "BANK" | "MOBILE_MONEY" Settlement account type (null if not configured) "BANK"
settlementAccountName string Account holder name on the settlement account "ABC Catering Ltd"
settlementAccountNumber string Bank account number or mobile money number 1234567890
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" Bank (when settlementAccountType=BANK) "GCB_BANK"
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" Mobile money provider (when settlementAccountType=MOBILE_MONEY) "MTN"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateCateringServiceRequest } from '@smartsapp/sdk/staff';
import type { UpdateCateringServiceRequest, CateringServiceResponse } from '@smartsapp/sdk/staff';

const input: UpdateCateringServiceRequest = {
  name: "Fresh Bites Catering",
  logo: "https://example.com/logo.png",
  email: "[email protected]",
  phone: "+233201234567"
};

const parsed = zUpdateCateringServiceRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: cateringService, error } = await canteenStaff.updateCateringService({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// cateringService is typed as CateringServiceResponse

deleteCateringService()

Delete a catering service

DELETE /api/canteen/catering-services/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteCateringService({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listCateringServices()

List catering services with pagination

GET /api/canteen/catering-services

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseCateringServiceResponse (200)

Field Type Description Example
content CateringServiceResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

CateringServiceResponse fields:

Field Type Description Example
id string (uuid) Catering service ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the catering service "ABC Catering"
logo string URL of the catering service logo "https://storage.example.com/logos/abc.png"
email string Contact email address "[email protected]"
phone string Contact phone number "+233501234567"
settlementAccountType "BANK" | "MOBILE_MONEY" Settlement account type (null if not configured) "BANK"
settlementAccountName string Account holder name on the settlement account "ABC Catering Ltd"
settlementAccountNumber string Bank account number or mobile money number 1234567890
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" Bank (when settlementAccountType=BANK) "GCB_BANK"
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" Mobile money provider (when settlementAccountType=MOBILE_MONEY) "MTN"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { PagedResponseCateringServiceResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await canteenStaff.listCateringServices({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const cateringServices = result.content;           // CateringServiceResponse[]
const { page, totalPages, totalElements, last } = result;

createCateringService()

Create a new catering service

POST /api/canteen/catering-services

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateCateringServiceRequest

Field Type Required Description
name string Yes Name of the catering service
logo string No URL of the catering service logo
email string Yes Contact email address
phone string Yes Contact phone number
settlementAccountType "BANK" | "MOBILE_MONEY" No Settlement account type. Optional on create — can be configured later.
settlementAccountName string No Account holder name on the settlement account
settlementAccountNumber string No Bank account number or mobile money number
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" No Bank (required when settlementAccountType=BANK)
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" No Mobile money provider (required when settlementAccountType=MOBILE_MONEY)

Response: CateringServiceResponse (201)

Field Type Description Example
id string (uuid) Catering service ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the catering service "ABC Catering"
logo string URL of the catering service logo "https://storage.example.com/logos/abc.png"
email string Contact email address "[email protected]"
phone string Contact phone number "+233501234567"
settlementAccountType "BANK" | "MOBILE_MONEY" Settlement account type (null if not configured) "BANK"
settlementAccountName string Account holder name on the settlement account "ABC Catering Ltd"
settlementAccountNumber string Bank account number or mobile money number 1234567890
settlementBank "ABSA_BANK_GHANA" | "ACCESS_BANK_GHANA" | "AGRICULTURAL_DEVELOPMENT_BANK" | "BANK_OF_AFRICA_GHANA" | "CALBANK" | "CONSOLIDATED_BANK_GHANA" | "ECOBANK_GHANA" | "FBN_BANK_GHANA" | "FIDELITY_BANK_GHANA" | "FIRST_ATLANTIC_BANK" | "FIRST_NATIONAL_BANK_GHANA" | "GCB_BANK" | "GUARANTY_TRUST_BANK_GHANA" | "NATIONAL_INVESTMENT_BANK" | "OMNIBSIC_BANK_GHANA" | "PRUDENTIAL_BANK" | "REPUBLIC_BANK_GHANA" | "SOCIETE_GENERALE_GHANA" | "STANBIC_BANK_GHANA" | "STANDARD_CHARTERED_BANK_GHANA" | "UNITED_BANK_FOR_AFRICA_GHANA" | "UNIVERSAL_MERCHANT_BANK" | "ZENITH_BANK_GHANA" Bank (when settlementAccountType=BANK) "GCB_BANK"
settlementMobileMoneyProvider "MTN" | "TELECEL" | "AIRTELTIGO" Mobile money provider (when settlementAccountType=MOBILE_MONEY) "MTN"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateCateringServiceRequest } from '@smartsapp/sdk/staff';
import type { CreateCateringServiceRequest, CateringServiceResponse } from '@smartsapp/sdk/staff';

const input: CreateCateringServiceRequest = {
  name: "Fresh Bites Catering",
  logo: "https://example.com/logo.png",
  email: "[email protected]",
  phone: "+233201234567"
};

const parsed = zCreateCateringServiceRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: cateringService, error } = await canteenStaff.createCateringService({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// cateringService is typed as CateringServiceResponse

listScheduleEntries()

List schedule entries for a section, grouped by date

GET /api/canteen/menus/{menuId}/sections/{sectionId}/schedules

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
startDate string (date) query Yes
endDate string (date) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: MenuScheduleGroupedResponse[] (200)

Field Type Description Example
date string (date) Scheduled date "2026-01-15"
items MenuScheduleEntryResponse[] Items scheduled for this date

MenuScheduleEntryResponse fields:

Field Type Description Example
id string (uuid) Schedule entry ID "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the scheduled item "550e8400-e29b-41d4-a716-446655440000"
itemName string Name of the scheduled item "Jollof Rice"
defaultPrice number Default price of the item 12.5
currency string Currency code "GHS"
scheduledViaCategoryId string (uuid) The category ID used to schedule this item, or null if scheduled directly "550e8400-e29b-41d4-a716-446655440000"
categoryName string Category name when scheduled via a category "Beverages"
variants ScheduleItemVariantResponse[] Available variants for this scheduled item
stockAvailable integer (int32) Stock available for this item on this day. Null means unlimited (no stock cap). 40
recurrenceRule "SINGLE_DAY" | "EVERY_DAY" | "EVERY_WEEKDAY" | "SPECIFIC_DAYS" How this row was created — mirrors the request-time SchedulePattern. Lets the planner inspector show the correct repeat option when re-opened on a cell. "SPECIFIC_DAYS"
createdAt string (date-time) When the schedule entry was created "2026-01-15T10:30:00Z"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.listScheduleEntries({
  path: { menuId: "...", sectionId: "..." },
  query: { startDate: "2026-01-01", endDate: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as MenuScheduleGroupedResponse[]

scheduleItems()

Schedule items to a section

POST /api/canteen/menus/{menuId}/sections/{sectionId}/schedules

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateMenuScheduleRequest

Field Type Required Description
itemId string (uuid) No ID of the item to schedule. If categoryId is also provided, the categoryId is attached as a provenance tag to every created entry rather than triggering a category-batch schedule. At least one of itemId or categoryId is required.
categoryId string (uuid) No ID of the category. When provided alone, every item in the category is scheduled. When provided alongside itemId, it acts as a provenance tag applied to each created entry (used by the planner's delete-subsequent flow to find recurring expansions of a category-sourced item). At least one of itemId or categoryId is required.
excludeItemIds string (uuid)[] No Item IDs to exclude when scheduling by category. Only used with categoryId.
date string (date) No The specific date to schedule. Required when pattern is SINGLE_DAY.
pattern "SINGLE_DAY" | "EVERY_DAY" | "EVERY_WEEKDAY" | "SPECIFIC_DAYS" Yes Scheduling pattern: SINGLE_DAY, EVERY_DAY, EVERY_WEEKDAY, or SPECIFIC_DAYS.
days "MONDAY" | "TUESDAY" | "WEDNESDAY" | "THURSDAY" | "FRIDAY" | "SATURDAY" | "SUNDAY"[] No Days of the week to schedule. Required when pattern is SPECIFIC_DAYS.
stockAvailable integer (int32) No Stock available applied to every schedule entry created from this request (for multi-day patterns the same value is applied to each generated day). Null means unlimited (no stock cap).

Response: MenuScheduleResponse[] (200)

Field Type Description Example
id string (uuid) Schedule entry ID "550e8400-e29b-41d4-a716-446655440000"
menuSectionId string (uuid) ID of the menu section "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the scheduled item "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date the item is scheduled for "2026-01-15"
scheduledViaCategoryId string (uuid) The category ID used to schedule this item, or null if scheduled directly "550e8400-e29b-41d4-a716-446655440000"
stockAvailable integer (int32) Stock available for this item on this day. Null means unlimited (no stock cap). 40
recurrenceRule "SINGLE_DAY" | "EVERY_DAY" | "EVERY_WEEKDAY" | "SPECIFIC_DAYS" How this row was created — mirrors the request-time SchedulePattern. Lets the planner inspector show the correct repeat option when re-opened on a cell. "SPECIFIC_DAYS"
createdAt string (date-time) When the schedule entry was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the schedule entry was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zCreateMenuScheduleRequest } from '@smartsapp/sdk/staff';
import type { CreateMenuScheduleRequest } from '@smartsapp/sdk/staff';

const input: CreateMenuScheduleRequest = {
  itemId: "550e8400-...",
  categoryId: "550e8400-...",
  excludeItemIds: [],
  date: "2026-04-07"
};

const parsed = zCreateMenuScheduleRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data, error } = await canteenStaff.scheduleItems({
  body: input,
  path: { menuId: "...", sectionId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as MenuScheduleResponse[]

bulkDeleteScheduleEntries()

Bulk delete schedule entries by item or category and date range

DELETE /api/canteen/menus/{menuId}/sections/{sectionId}/schedules

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
itemId string (uuid) query No
categoryId string (uuid) query No
startDate string (date) query Yes
endDate string (date) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.bulkDeleteScheduleEntries({
  path: { menuId: "...", sectionId: "..." },
  query: { itemId: "...", categoryId: "...", startDate: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

deleteScheduleEntry()

Remove a single schedule entry

DELETE /api/canteen/menus/{menuId}/sections/{sectionId}/schedules/{scheduleId}

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
scheduleId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.deleteScheduleEntry({
  path: { menuId: "...", sectionId: "...", scheduleId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

updateScheduleEntry()

Update a schedule entry (stock available for the day)

PATCH /api/canteen/menus/{menuId}/sections/{sectionId}/schedules/{scheduleId}

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
scheduleId string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateMenuScheduleRequest

Field Type Required Description
stockAvailable integer (int32) No Stock available for this day. Null means unlimited (no stock cap).

Response: MenuScheduleResponse (200)

Field Type Description Example
id string (uuid) Schedule entry ID "550e8400-e29b-41d4-a716-446655440000"
menuSectionId string (uuid) ID of the menu section "550e8400-e29b-41d4-a716-446655440000"
itemId string (uuid) ID of the scheduled item "550e8400-e29b-41d4-a716-446655440000"
date string (date) Date the item is scheduled for "2026-01-15"
scheduledViaCategoryId string (uuid) The category ID used to schedule this item, or null if scheduled directly "550e8400-e29b-41d4-a716-446655440000"
stockAvailable integer (int32) Stock available for this item on this day. Null means unlimited (no stock cap). 40
recurrenceRule "SINGLE_DAY" | "EVERY_DAY" | "EVERY_WEEKDAY" | "SPECIFIC_DAYS" How this row was created — mirrors the request-time SchedulePattern. Lets the planner inspector show the correct repeat option when re-opened on a cell. "SPECIFIC_DAYS"
createdAt string (date-time) When the schedule entry was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the schedule entry was last updated "2026-01-15T10:30:00Z"

Example:

import { canteenStaff, zUpdateMenuScheduleRequest } from '@smartsapp/sdk/staff';
import type { UpdateMenuScheduleRequest, MenuScheduleResponse } from '@smartsapp/sdk/staff';

const input: UpdateMenuScheduleRequest = {
  stockAvailable: 40
};

const parsed = zUpdateMenuScheduleRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: menuSchedule, error } = await canteenStaff.updateScheduleEntry({
  body: input,
  path: { menuId: "...", sectionId: "...", scheduleId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// menuSchedule is typed as MenuScheduleResponse

bulkUpdateStock()

Apply a stock cap (or clear it) to many schedule entries at once

PATCH /api/canteen/menus/{menuId}/sections/{sectionId}/schedules/bulk-stock

Parameters:

Name Type In Required Description
menuId string (uuid) path Yes
sectionId string (uuid) path Yes
itemId string (uuid) query No
categoryId string (uuid) query No
startDate string (date) query Yes
endDate string (date) query Yes
stockAvailable integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.bulkUpdateStock({
  path: { menuId: "...", sectionId: "..." },
  query: { itemId: "...", categoryId: "...", startDate: "2026-01-01" }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

Student Directory

listStudentDirectory()

List students with canteen data (balance, tickets, menus, allergies)

GET /api/canteen/students

Parameters:

Name Type In Required Description
search string query No
classroomId string (uuid) query No
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StudentDirectoryResponse (200)

Field Type Description Example
directory PagedResponseStudentDirectoryRowResponse Generic wrapper for paginated API responses
stats StudentDirectoryStatsResponse KPI stats for the student directory header

PagedResponseStudentDirectoryRowResponse fields:

Field Type Description Example
content StudentDirectoryRowResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

StudentDirectoryStatsResponse fields:

Field Type Description Example
totalStudents integer (int64) Total active students in the school 338
activePlans integer (int64) Students with active meal ticket plans 284
debtAlerts integer (int64) Students with negative Sika ID balance 12
safetyFlags integer (int64) Students with recorded allergies or dietary restrictions 8

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { StudentDirectoryResponse } from '@smartsapp/sdk/staff';

const { data: studentDirectory, error } = await canteenStaff.listStudentDirectory({
  query: { search: "...", classroomId: "...", page: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// studentDirectory is typed as StudentDirectoryResponse

Reports

getTicketsReport()

Get tickets report

GET /api/canteen/reports/tickets

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
campusId string (uuid) query No
compare boolean query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: TicketsReportResponse (200)

Field Type Description Example
purchased integer (int64) Total tickets purchased 120
redeemed integer (int64) Total tickets redeemed 89
unredeemed integer (int64) Total tickets not yet redeemed 31
breakdown TicketBreakdownEntry[]

TicketBreakdownEntry fields:

Field Type Description Example
ticketName string Name of the ticket type "Weekly Lunch Pass"
numberSold integer (int64) Number of tickets sold 60
numberRedeemed integer (int64) Number of tickets redeemed 48
redemptionRate number (double) Redemption rate as a decimal 0.8

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { TicketsReportResponse } from '@smartsapp/sdk/staff';

const { data: ticketsReport, error } = await canteenStaff.getTicketsReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// ticketsReport is typed as TicketsReportResponse

exportTicketsReport()

Export tickets report as Excel

GET /api/canteen/reports/tickets/export

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
campusId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportTicketsReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

getSikaIdReport()

Get Sika ID report

GET /api/canteen/reports/sika-id

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
campusId string (uuid) query No
compare boolean query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SikaIdReportResponse (200)

Field Type Description Example
todayDeposit TodayDeposit
outstandingDebt OutstandingDebt
activeUsers ActiveUsers
transactions SikaIdTransactionEntry[] Individual transactions within the period

TodayDeposit fields:

Field Type Description Example
amount number Deposit total 8500.0
currency string ISO 4217 currency code "GHS"

OutstandingDebt fields:

Field Type Description Example
amount number Debt total 350.0
currency string ISO 4217 currency code "GHS"
recoveredTodayPercent number Percent of yesterday's debt recovered today 0

ActiveUsers fields:

Field Type Description Example
count integer (int32) Distinct students with Sika ID activity 24

SikaIdTransactionEntry fields:

Field Type Description Example
id string Transaction ID (backed by the canteen order ID) "550e8400-e29b-41d4-a716-446655440000"
studentId string Student UUID "660e8400-e29b-41d4-a716-446655440000"
studentName string Student full name "Kwame Asante"
studentGrade string Student grade / classroom name "Grade 5"
studentInitials string Two-letter initials derived from studentName "KA"
transactionType "posPurchase" | "walletTopUp" | "mealRedemption" | "refund" | "allocation" Frontend transaction-type enum "mealRedemption"
transactionTypeLabel string Human-readable transaction-type label "Meal Redemption"
platform "offlinePos" | "onlinePortal" | "mobileApp" | "canteenTerminal" Frontend platform enum "canteenTerminal"
platformLabel string Human-readable platform label "Canteen Terminal"
status string Raw order status (frontend maps to success/failed/pending) "SERVED"
amount number Transaction amount 50.0
currency string ISO 4217 currency code "GHS"
date string (date-time) Transaction timestamp "2026-03-01T10:15:00Z"
processedBy string UUID of the user who processed the transaction

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { SikaIdReportResponse } from '@smartsapp/sdk/staff';

const { data: sikaIdReport, error } = await canteenStaff.getSikaIdReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// sikaIdReport is typed as SikaIdReportResponse

exportSikaIdReport()

Export Sika ID report as Excel

GET /api/canteen/reports/sika-id/export

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
campusId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportSikaIdReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

getSalesReport()

Get sales report

GET /api/canteen/reports/sales

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
personnelId string (uuid) query No
campusId string (uuid) query No
compare boolean query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SalesReportResponse (200)

Field Type Description Example
totalRevenue number Total revenue for the period 4520.5
creditSales number Total credit sales 1200.0
customerCount integer (int64) Number of unique customers 78
currency string ISO currency code "GHS"
refunds RefundSummary Total refunds (cancelled orders) for the period
revenueChart RevenueBarEntry[] Revenue time-series bars for the period
salesByType SalesByTypeEntry[] Sales breakdown by payment method
transactions SalesTransactionEntry[]

RefundSummary fields:

Field Type Description Example
amount number Total refunded amount 125.5
count integer (int64) Number of refunded (cancelled) orders 3

RevenueBarEntry fields:

Field Type Description Example
label string Bucket label (e.g. day, month) "Mar"
value number Revenue in this bucket 4520.5

SalesByTypeEntry fields:

Field Type Description Example
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" Payment method "SIKA_ID"
amount number Total amount for this payment method 1850.0

SalesTransactionEntry fields:

Field Type Description Example
orderNumber string Order reference number "ORD-20260301-001"
studentName string Name of the student "Kwame Asante"
studentGrade string Classroom / grade of the student "Primary 5"
payer string Primary guardian paying for the order "Mary Asante"
createdByName string Name of the staff who created the order "Ama Mensah"
amount number Transaction amount 25.5
currency string ISO currency code "GHS"
paymentMode "SIKA_ID" | "ONLINE_PAYMENT" | "CREDIT" | "CASH" | "ALLOCATION" Payment method used "SIKA_ID"
itemSummary string Comma-separated list of items "Jollof Rice x1, Chicken x1"
date string (date) Date of the transaction "2026-03-01"
time string (date-time) Timestamp of the transaction "2026-03-01T12:30:00Z"
status "DRAFT" | "PAID" | "SERVED" | "PARTIALLY_SERVED" | "CANCELLED" Current order status "DRAFT"

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { SalesReportResponse } from '@smartsapp/sdk/staff';

const { data: salesReport, error } = await canteenStaff.getSalesReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", personnelId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// salesReport is typed as SalesReportResponse

exportSalesReport()

Export sales report as Excel

GET /api/canteen/reports/sales/export

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
personnelId string (uuid) query No
campusId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportSalesReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", personnelId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

getOrdersReport()

Get orders report

GET /api/canteen/reports/orders

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
personnelId string (uuid) query No
campusId string (uuid) query No
compare boolean query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: OrdersReportResponse (200)

Field Type Description Example
orderCount integer (int64) Total number of orders 152
totalAmount number Total order amount 4520.5
currency string ISO currency code "GHS"
cancelledOrders integer (int64) Number of cancelled orders 5
trend OrderVolumeTrendEntry[]
itemRanking ItemPerformanceEntry[]
orderFrequency OrderFrequencyBucket[] Order frequency breakdown by time-of-day slot

OrderVolumeTrendEntry fields:

Field Type Description Example
date string (date) Date "2026-03-01"
count integer (int64) Number of orders on this date 24

ItemPerformanceEntry fields:

Field Type Description Example
itemName string Name of the menu item "Jollof Rice"
orderCount integer (int64) Total orders for this item 45
revenue number Total revenue from this item 675.0

OrderFrequencyBucket fields:

Field Type Description Example
timeSlot string Time slot label "11am-1pm"
preOrders integer (int64) Number of pre-orders (ticket-based) in this slot 18
walkIns integer (int64) Number of walk-ins (POS) in this slot 25

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { OrdersReportResponse } from '@smartsapp/sdk/staff';

const { data: ordersReport, error } = await canteenStaff.getOrdersReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", personnelId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// ordersReport is typed as OrdersReportResponse

exportOrdersReport()

Export orders report as Excel

GET /api/canteen/reports/orders/export

Parameters:

Name Type In Required Description
dateFrom string (date) query Yes
dateTo string (date) query Yes
personnelId string (uuid) query No
campusId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportOrdersReport({
  query: { dateFrom: "2026-01-01", dateTo: "2026-01-01", personnelId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

Dashboard

getCanteenDashboard()

Get dashboard metrics for a date range

GET /api/canteen/dashboard

Parameters:

Name Type In Required Description
from string (date) query No
to string (date) query No
campusId string (uuid) query No
cateringServiceId string (uuid) query No
personnelId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: DashboardResponse (200)

Field Type Description Example
totalStudentsOnFeedingList integer (int64) Total distinct students on the feeding list
studentsPresentOnFeedingList integer (int64) Students marked present and on the feeding list
studentsAbsentOnFeedingList integer (int64) Students marked absent but on the feeding list
totalMeals integer (int64) Total meals to be redeemed (non-cancelled orders)
mealsRedeemed integer (int64) Meals with status SERVED
mealsUnredeemed integer (int64) Meals with status PAID or PARTIALLY_SERVED
ordersByItem OrderByItemEntry[] Order breakdown by item
ordersByCategory OrderByCategoryEntry[] Order breakdown by category

OrderByItemEntry fields:

Field Type Description Example
itemName string Name of the item
categoryId string (uuid) Category ID of the item "550e8400-..."
imageUrl string URL of the item image, if set
totalQuantity integer (int32) Total quantity ordered across all variants
variants VariantQuantityEntry[] Breakdown by variant (empty list if item has no variants)

OrderByCategoryEntry fields:

Field Type Description Example
categoryId string (uuid) ID of the item category "550e8400-..."
categoryName string Name of the item category "Beverages"
count integer (int32) Number of orders in this category 42

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';
import type { DashboardResponse } from '@smartsapp/sdk/staff';

const { data: dashboard, error } = await canteenStaff.getCanteenDashboard({
  query: { from: "2026-01-01", to: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// dashboard is typed as DashboardResponse

exportDashboardOrders()

Export orders for a date range as Excel

GET /api/canteen/dashboard/export

Parameters:

Name Type In Required Description
from string (date) query No
to string (date) query No
campusId string (uuid) query No
cateringServiceId string (uuid) query No
personnelId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: string (byte) (200)

Example:

import { canteenStaff } from '@smartsapp/sdk/staff';

const { data, error } = await canteenStaff.exportDashboardOrders({
  query: { from: "2026-01-01", to: "2026-01-01", campusId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}


Academic Report (academicReport)

Not yet implemented

This module is planned but not yet available.


Invoice (invoice)

Not yet implemented

This module is planned but not yet available.


School (school)

Students

getStudent()

Get a student by ID

GET /api/school/students/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StudentResponse (200)

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school the student belongs to "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the student's classroom "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the student's family "550e8400-e29b-41d4-a716-446655440000"
studentIdNumber string School-assigned student ID number "STU-2026-001"
firstName string Student's first name "Kofi"
middleName string Student's middle name "Mensah"
lastName string Student's last name "Asante"
dateOfBirth string (date) Student's date of birth "2015-03-20"
gender "MALE" | "FEMALE" | "OTHER" Student's gender "MALE"
profilePhotoUrl string URL of the student's profile photo "https://storage.example.com/photos/student.jpg"
nationality string Student's nationality "Ghanaian"
religion string Student's religion "Christian"
bloodGroup string Student's blood group "O+"
medicalNotes string Medical notes or allergies "Allergic to peanuts"
enrollmentDate string (date) Date the student enrolled "2026-01-10"
status "ACTIVE" | "INACTIVE" | "GRADUATED" | "WITHDRAWN" | "SUSPENDED" Current enrollment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { StudentResponse } from '@smartsapp/sdk/staff';

const { data: student, error } = await school.getStudent({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// student is typed as StudentResponse

updateStudent()

Update a student

PUT /api/school/students/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateStudentRequest

Field Type Required Description
schoolId string (uuid) No ID of the school
classroomId string (uuid) No ID of the classroom
familyId string (uuid) No ID of the family (optional)
studentIdNumber string No Student identification number
firstName string No First name of the student
middleName string No Middle name of the student
lastName string No Last name of the student
dateOfBirth string (date) No Date of birth
gender "MALE" | "FEMALE" | "OTHER" No Gender of the student
profilePhotoUrl string No URL of the profile photo
nationality string No Nationality of the student
religion string No Religion of the student
bloodGroup string No Blood group of the student
medicalNotes string No Medical notes for the student
enrollmentDate string (date) No Date of enrollment
status "ACTIVE" | "INACTIVE" | "GRADUATED" | "WITHDRAWN" | "SUSPENDED" No Status of the student

Response: StudentResponse (200)

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school the student belongs to "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the student's classroom "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the student's family "550e8400-e29b-41d4-a716-446655440000"
studentIdNumber string School-assigned student ID number "STU-2026-001"
firstName string Student's first name "Kofi"
middleName string Student's middle name "Mensah"
lastName string Student's last name "Asante"
dateOfBirth string (date) Student's date of birth "2015-03-20"
gender "MALE" | "FEMALE" | "OTHER" Student's gender "MALE"
profilePhotoUrl string URL of the student's profile photo "https://storage.example.com/photos/student.jpg"
nationality string Student's nationality "Ghanaian"
religion string Student's religion "Christian"
bloodGroup string Student's blood group "O+"
medicalNotes string Medical notes or allergies "Allergic to peanuts"
enrollmentDate string (date) Date the student enrolled "2026-01-10"
status "ACTIVE" | "INACTIVE" | "GRADUATED" | "WITHDRAWN" | "SUSPENDED" Current enrollment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateStudentRequest } from '@smartsapp/sdk/staff';
import type { UpdateStudentRequest, StudentResponse } from '@smartsapp/sdk/staff';

const input: UpdateStudentRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  classroomId: "550e8400-e29b-41d4-a716-446655440001",
  familyId: "550e8400-e29b-41d4-a716-446655440002",
  studentIdNumber: "STU-2024-001"
};

const parsed = zUpdateStudentRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: student, error } = await school.updateStudent({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// student is typed as StudentResponse

deleteStudent()

Delete a student

DELETE /api/school/students/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteStudent({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listStudents()

List students with pagination

GET /api/school/students

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseStudentResponse (200)

Field Type Description Example
content StudentResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

StudentResponse fields:

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school the student belongs to "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the student's classroom "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the student's family "550e8400-e29b-41d4-a716-446655440000"
studentIdNumber string School-assigned student ID number "STU-2026-001"
firstName string Student's first name "Kofi"
middleName string Student's middle name "Mensah"
lastName string Student's last name "Asante"
dateOfBirth string (date) Student's date of birth "2015-03-20"
gender "MALE" | "FEMALE" | "OTHER" Student's gender "MALE"
profilePhotoUrl string URL of the student's profile photo "https://storage.example.com/photos/student.jpg"
nationality string Student's nationality "Ghanaian"
religion string Student's religion "Christian"
bloodGroup string Student's blood group "O+"
medicalNotes string Medical notes or allergies "Allergic to peanuts"
enrollmentDate string (date) Date the student enrolled "2026-01-10"
status "ACTIVE" | "INACTIVE" | "GRADUATED" | "WITHDRAWN" | "SUSPENDED" Current enrollment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseStudentResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listStudents({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const students = result.content;           // StudentResponse[]
const { page, totalPages, totalElements, last } = result;

createStudent()

Create a new student

POST /api/school/students

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateStudentRequest

Field Type Required Description
schoolId string (uuid) Yes ID of the school
classroomId string (uuid) Yes ID of the classroom
familyId string (uuid) No ID of the family (optional)
studentIdNumber string No Student identification number
firstName string Yes First name of the student
middleName string No Middle name of the student
lastName string Yes Last name of the student
dateOfBirth string (date) No Date of birth
gender "MALE" | "FEMALE" | "OTHER" No Gender of the student
profilePhotoUrl string No URL of the profile photo
nationality string No Nationality of the student
religion string No Religion of the student
bloodGroup string No Blood group of the student
medicalNotes string No Medical notes for the student
enrollmentDate string (date) No Date of enrollment

Response: StudentResponse (201)

Field Type Description Example
id string (uuid) Student ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school the student belongs to "550e8400-e29b-41d4-a716-446655440000"
classroomId string (uuid) ID of the student's classroom "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the student's family "550e8400-e29b-41d4-a716-446655440000"
studentIdNumber string School-assigned student ID number "STU-2026-001"
firstName string Student's first name "Kofi"
middleName string Student's middle name "Mensah"
lastName string Student's last name "Asante"
dateOfBirth string (date) Student's date of birth "2015-03-20"
gender "MALE" | "FEMALE" | "OTHER" Student's gender "MALE"
profilePhotoUrl string URL of the student's profile photo "https://storage.example.com/photos/student.jpg"
nationality string Student's nationality "Ghanaian"
religion string Student's religion "Christian"
bloodGroup string Student's blood group "O+"
medicalNotes string Medical notes or allergies "Allergic to peanuts"
enrollmentDate string (date) Date the student enrolled "2026-01-10"
status "ACTIVE" | "INACTIVE" | "GRADUATED" | "WITHDRAWN" | "SUSPENDED" Current enrollment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateStudentRequest } from '@smartsapp/sdk/staff';
import type { CreateStudentRequest, StudentResponse } from '@smartsapp/sdk/staff';

const input: CreateStudentRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  classroomId: "550e8400-e29b-41d4-a716-446655440001",
  familyId: "550e8400-e29b-41d4-a716-446655440002",
  studentIdNumber: "STU-2024-001"
};

const parsed = zCreateStudentRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: student, error } = await school.createStudent({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// student is typed as StudentResponse

Staff

getStaffMember()

Get a staff member by ID

GET /api/school/staff/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StaffResponse (200)

Field Type Description Example
id string (uuid) Staff member ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus the staff member is assigned to "550e8400-e29b-41d4-a716-446655440000"
staffIdNumber string Staff ID number "STF-2026-001"
firstName string First name "Abena"
middleName string Middle name "Osei"
lastName string Last name "Mensah"
email string Email address "[email protected]"
phone string Phone number "+233501234567"
dateOfBirth string (date) Date of birth "1985-06-15"
gender "MALE" | "FEMALE" | "OTHER" Gender "MALE"
profilePhotoUrl string URL of the staff member's profile photo "https://storage.example.com/photos/staff.jpg"
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" Staff role: TEACHER, ADMIN, PRINCIPAL, etc. "TEACHER"
department string Department name "Mathematics"
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" Employment type: FULL_TIME, PART_TIME, CONTRACT "FULL_TIME"
hireDate string (date) Date the staff member was hired "2024-09-01"
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" Employment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { StaffResponse } from '@smartsapp/sdk/staff';

const { data: staff, error } = await school.getStaffMember({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// staff is typed as StaffResponse

updateStaffMember()

Update a staff member

PUT /api/school/staff/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateStaffRequest

Field Type Required Description
schoolId string (uuid) No ID of the school
campusId string (uuid) No ID of the campus (optional)
staffIdNumber string No Staff identification number
firstName string No First name of the staff member
middleName string No Middle name of the staff member
lastName string No Last name of the staff member
email string No Email address
phone string No Phone number
dateOfBirth string (date) No Date of birth
gender "MALE" | "FEMALE" | "OTHER" No Gender of the staff member
profilePhotoUrl string No URL of the profile photo
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" No Role of the staff member
department string No Department of the staff member
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" No Employment type
hireDate string (date) No Date of hire
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" No Status of the staff member

Response: StaffResponse (200)

Field Type Description Example
id string (uuid) Staff member ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus the staff member is assigned to "550e8400-e29b-41d4-a716-446655440000"
staffIdNumber string Staff ID number "STF-2026-001"
firstName string First name "Abena"
middleName string Middle name "Osei"
lastName string Last name "Mensah"
email string Email address "[email protected]"
phone string Phone number "+233501234567"
dateOfBirth string (date) Date of birth "1985-06-15"
gender "MALE" | "FEMALE" | "OTHER" Gender "MALE"
profilePhotoUrl string URL of the staff member's profile photo "https://storage.example.com/photos/staff.jpg"
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" Staff role: TEACHER, ADMIN, PRINCIPAL, etc. "TEACHER"
department string Department name "Mathematics"
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" Employment type: FULL_TIME, PART_TIME, CONTRACT "FULL_TIME"
hireDate string (date) Date the staff member was hired "2024-09-01"
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" Employment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateStaffRequest } from '@smartsapp/sdk/staff';
import type { UpdateStaffRequest, StaffResponse } from '@smartsapp/sdk/staff';

const input: UpdateStaffRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  campusId: "550e8400-e29b-41d4-a716-446655440001",
  staffIdNumber: "STF-2024-001",
  firstName: "Jane"
};

const parsed = zUpdateStaffRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: staff, error } = await school.updateStaffMember({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// staff is typed as StaffResponse

deleteStaffMember()

Delete a staff member

DELETE /api/school/staff/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteStaffMember({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listStaff()

List staff with pagination

GET /api/school/staff

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseStaffResponse (200)

Field Type Description Example
content StaffResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

StaffResponse fields:

Field Type Description Example
id string (uuid) Staff member ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus the staff member is assigned to "550e8400-e29b-41d4-a716-446655440000"
staffIdNumber string Staff ID number "STF-2026-001"
firstName string First name "Abena"
middleName string Middle name "Osei"
lastName string Last name "Mensah"
email string Email address "[email protected]"
phone string Phone number "+233501234567"
dateOfBirth string (date) Date of birth "1985-06-15"
gender "MALE" | "FEMALE" | "OTHER" Gender "MALE"
profilePhotoUrl string URL of the staff member's profile photo "https://storage.example.com/photos/staff.jpg"
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" Staff role: TEACHER, ADMIN, PRINCIPAL, etc. "TEACHER"
department string Department name "Mathematics"
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" Employment type: FULL_TIME, PART_TIME, CONTRACT "FULL_TIME"
hireDate string (date) Date the staff member was hired "2024-09-01"
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" Employment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseStaffResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listStaff({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const staffs = result.content;           // StaffResponse[]
const { page, totalPages, totalElements, last } = result;

createStaff()

Create a new staff member

POST /api/school/staff

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateStaffRequest

Field Type Required Description
schoolId string (uuid) Yes ID of the school
campusId string (uuid) No ID of the campus (optional)
staffIdNumber string No Staff identification number
firstName string Yes First name of the staff member
middleName string No Middle name of the staff member
lastName string Yes Last name of the staff member
email string No Email address
phone string No Phone number
dateOfBirth string (date) No Date of birth
gender "MALE" | "FEMALE" | "OTHER" No Gender of the staff member
profilePhotoUrl string No URL of the profile photo
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" No Role of the staff member
department string No Department of the staff member
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" No Employment type
hireDate string (date) No Date of hire

Response: StaffResponse (201)

Field Type Description Example
id string (uuid) Staff member ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus the staff member is assigned to "550e8400-e29b-41d4-a716-446655440000"
staffIdNumber string Staff ID number "STF-2026-001"
firstName string First name "Abena"
middleName string Middle name "Osei"
lastName string Last name "Mensah"
email string Email address "[email protected]"
phone string Phone number "+233501234567"
dateOfBirth string (date) Date of birth "1985-06-15"
gender "MALE" | "FEMALE" | "OTHER" Gender "MALE"
profilePhotoUrl string URL of the staff member's profile photo "https://storage.example.com/photos/staff.jpg"
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" Staff role: TEACHER, ADMIN, PRINCIPAL, etc. "TEACHER"
department string Department name "Mathematics"
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" Employment type: FULL_TIME, PART_TIME, CONTRACT "FULL_TIME"
hireDate string (date) Date the staff member was hired "2024-09-01"
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" Employment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateStaffRequest } from '@smartsapp/sdk/staff';
import type { CreateStaffRequest, StaffResponse } from '@smartsapp/sdk/staff';

const input: CreateStaffRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  campusId: "550e8400-e29b-41d4-a716-446655440001",
  staffIdNumber: "STF-2024-001",
  firstName: "Jane"
};

const parsed = zCreateStaffRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: staff, error } = await school.createStaff({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// staff is typed as StaffResponse

Sections

getSection()

Get a section by ID

GET /api/school/sections/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SectionResponse (200)

Field Type Description Example
id string (uuid) Section ID "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus this section belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Primary School"
code string Short unique code for the section "PRI"
levelOrder integer (int32) Sort order within the campus 1
description string Description of the section "Grades 1 through 6"
isActive boolean Whether the section is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { SectionResponse } from '@smartsapp/sdk/staff';

const { data: section, error } = await school.getSection({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// section is typed as SectionResponse

updateSection()

Update a section

PUT /api/school/sections/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateSectionRequest

Field Type Required Description
campusId string (uuid) No ID of the campus this section belongs to
name string No Name of the section
code string No Unique code for the section
levelOrder integer (int32) No Order level of the section
description string No Description of the section
isActive boolean No Whether the section is active

Response: SectionResponse (200)

Field Type Description Example
id string (uuid) Section ID "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus this section belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Primary School"
code string Short unique code for the section "PRI"
levelOrder integer (int32) Sort order within the campus 1
description string Description of the section "Grades 1 through 6"
isActive boolean Whether the section is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateSectionRequest } from '@smartsapp/sdk/staff';
import type { UpdateSectionRequest, SectionResponse } from '@smartsapp/sdk/staff';

const input: UpdateSectionRequest = {
  campusId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Primary",
  code: "PRI",
  levelOrder: 1
};

const parsed = zUpdateSectionRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: section, error } = await school.updateSection({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// section is typed as SectionResponse

deleteSection()

Delete a section

DELETE /api/school/sections/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteSection({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listSections()

List sections with pagination

GET /api/school/sections

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseSectionResponse (200)

Field Type Description Example
content SectionResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

SectionResponse fields:

Field Type Description Example
id string (uuid) Section ID "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus this section belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Primary School"
code string Short unique code for the section "PRI"
levelOrder integer (int32) Sort order within the campus 1
description string Description of the section "Grades 1 through 6"
isActive boolean Whether the section is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseSectionResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listSections({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const sections = result.content;           // SectionResponse[]
const { page, totalPages, totalElements, last } = result;

createSection()

Create a new section

POST /api/school/sections

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateSectionRequest

Field Type Required Description
campusId string (uuid) Yes ID of the campus this section belongs to
name string Yes Name of the section
code string No Unique code for the section
levelOrder integer (int32) No Order level of the section
description string No Description of the section

Response: SectionResponse (201)

Field Type Description Example
id string (uuid) Section ID "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus this section belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the section "Primary School"
code string Short unique code for the section "PRI"
levelOrder integer (int32) Sort order within the campus 1
description string Description of the section "Grades 1 through 6"
isActive boolean Whether the section is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateSectionRequest } from '@smartsapp/sdk/staff';
import type { CreateSectionRequest, SectionResponse } from '@smartsapp/sdk/staff';

const input: CreateSectionRequest = {
  campusId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Primary",
  code: "PRI",
  levelOrder: 1
};

const parsed = zCreateSectionRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: section, error } = await school.createSection({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// section is typed as SectionResponse

Schools

getSchool()

Get a school by ID

GET /api/school/schools/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SchoolResponse (200)

Field Type Description Example
id string (uuid) School ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the school "Lincoln International Academy"
code string Short unique code for the school "LIA"
logoUrl string URL of the school logo "https://storage.example.com/logos/lia.png"
address string Physical address of the school 12
phone string Contact phone number "+233302123456"
email string Contact email address "[email protected]"
website string School website URL "https://lincolnacademy.edu"
accreditationNumber string Government accreditation number "ACC-2024-00123"
defaultCurrency string Default currency code for the school "GHS"
isActive boolean Whether the school is currently active
createdAt string (date-time) When the school was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the school was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { SchoolResponse } from '@smartsapp/sdk/staff';

const { data: school, error } = await school.getSchool({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// school is typed as SchoolResponse

updateSchool()

Update a school

PUT /api/school/schools/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateSchoolRequest

Field Type Required Description
name string No Official name of the school
code string No Unique code for the school
logoUrl string No URL of the school logo
address string No Physical address of the school
phone string No Contact phone number
email string No Contact email address
website string No School website URL
accreditationNumber string No Accreditation number
defaultCurrency string No ISO 4217 currency code for all financial operations
isActive boolean No Whether the school is active

Response: SchoolResponse (200)

Field Type Description Example
id string (uuid) School ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the school "Lincoln International Academy"
code string Short unique code for the school "LIA"
logoUrl string URL of the school logo "https://storage.example.com/logos/lia.png"
address string Physical address of the school 12
phone string Contact phone number "+233302123456"
email string Contact email address "[email protected]"
website string School website URL "https://lincolnacademy.edu"
accreditationNumber string Government accreditation number "ACC-2024-00123"
defaultCurrency string Default currency code for the school "GHS"
isActive boolean Whether the school is currently active
createdAt string (date-time) When the school was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the school was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateSchoolRequest } from '@smartsapp/sdk/staff';
import type { UpdateSchoolRequest, SchoolResponse } from '@smartsapp/sdk/staff';

const input: UpdateSchoolRequest = {
  name: "Accra Academy",
  code: "ACAD",
  logoUrl: "https://example.com/logo.png",
  address: 123
};

const parsed = zUpdateSchoolRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: school, error } = await school.updateSchool({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// school is typed as SchoolResponse

deleteSchool()

Delete a school

DELETE /api/school/schools/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteSchool({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listSchools()

List schools with pagination

GET /api/school/schools

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseSchoolResponse (200)

Field Type Description Example
content SchoolResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

SchoolResponse fields:

Field Type Description Example
id string (uuid) School ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the school "Lincoln International Academy"
code string Short unique code for the school "LIA"
logoUrl string URL of the school logo "https://storage.example.com/logos/lia.png"
address string Physical address of the school 12
phone string Contact phone number "+233302123456"
email string Contact email address "[email protected]"
website string School website URL "https://lincolnacademy.edu"
accreditationNumber string Government accreditation number "ACC-2024-00123"
defaultCurrency string Default currency code for the school "GHS"
isActive boolean Whether the school is currently active
createdAt string (date-time) When the school was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the school was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseSchoolResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listSchools({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const schools = result.content;           // SchoolResponse[]
const { page, totalPages, totalElements, last } = result;

createSchool()

Create a new school

POST /api/school/schools

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateSchoolRequest

Field Type Required Description
name string Yes Official name of the school
code string No Unique code for the school
logoUrl string No URL of the school logo
address string No Physical address of the school
phone string No Contact phone number
email string No Contact email address
website string No School website URL
accreditationNumber string No Accreditation number
defaultCurrency string No ISO 4217 currency code for all financial operations

Response: SchoolResponse (201)

Field Type Description Example
id string (uuid) School ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the school "Lincoln International Academy"
code string Short unique code for the school "LIA"
logoUrl string URL of the school logo "https://storage.example.com/logos/lia.png"
address string Physical address of the school 12
phone string Contact phone number "+233302123456"
email string Contact email address "[email protected]"
website string School website URL "https://lincolnacademy.edu"
accreditationNumber string Government accreditation number "ACC-2024-00123"
defaultCurrency string Default currency code for the school "GHS"
isActive boolean Whether the school is currently active
createdAt string (date-time) When the school was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the school was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateSchoolRequest } from '@smartsapp/sdk/staff';
import type { CreateSchoolRequest, SchoolResponse } from '@smartsapp/sdk/staff';

const input: CreateSchoolRequest = {
  name: "Accra Academy",
  code: "ACAD",
  logoUrl: "https://example.com/logo.png",
  address: 123
};

const parsed = zCreateSchoolRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: school, error } = await school.createSchool({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// school is typed as SchoolResponse

Guardians

getGuardian()

Get a guardian by ID

GET /api/school/guardians/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: GuardianResponse (200)

Field Type Description Example
id string (uuid) Guardian ID "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the family this guardian belongs to "550e8400-e29b-41d4-a716-446655440000"
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" Type of guardian: FATHER, MOTHER, LEGAL_GUARDIAN, OTHER "FATHER"
firstName string Guardian's first name "Kwame"
middleName string Guardian's middle name "Mensah"
lastName string Guardian's last name "Asante"
email string Guardian's email address "[email protected]"
phonePrimary string Primary phone number "+233501234567"
phoneSecondary string Secondary phone number "+233509876543"
occupation string Guardian's occupation "Software Engineer"
employer string Guardian's employer "TechCorp Ltd"
address string Guardian's residential address 15
nationalId string National identification number "GHA-123456789"
profilePhotoUrl string URL of the guardian's profile photo "https://storage.example.com/photos/guardian.jpg"
isEmergencyContact boolean Whether this guardian is an emergency contact
canPickupStudent boolean Whether this guardian is authorised to pick up the student
isPrimaryContact boolean Whether this guardian is the primary contact for the family
isActive boolean Whether this guardian record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { GuardianResponse } from '@smartsapp/sdk/staff';

const { data: guardian, error } = await school.getGuardian({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// guardian is typed as GuardianResponse

updateGuardian()

Update a guardian

PUT /api/school/guardians/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateGuardianRequest

Field Type Required Description
familyId string (uuid) No ID of the family (optional)
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" No Type of guardian
firstName string No First name of the guardian
middleName string No Middle name of the guardian
lastName string No Last name of the guardian
email string No Email address
phonePrimary string No Primary phone number
phoneSecondary string No Secondary phone number
occupation string No Occupation of the guardian
employer string No Employer of the guardian
address string No Address of the guardian
nationalId string No National ID number
profilePhotoUrl string No URL of the profile photo
isEmergencyContact boolean No Whether this guardian is an emergency contact
canPickupStudent boolean No Whether this guardian can pick up the student
isPrimaryContact boolean No Whether this is the primary contact
isActive boolean No Whether the guardian is active

Response: GuardianResponse (200)

Field Type Description Example
id string (uuid) Guardian ID "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the family this guardian belongs to "550e8400-e29b-41d4-a716-446655440000"
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" Type of guardian: FATHER, MOTHER, LEGAL_GUARDIAN, OTHER "FATHER"
firstName string Guardian's first name "Kwame"
middleName string Guardian's middle name "Mensah"
lastName string Guardian's last name "Asante"
email string Guardian's email address "[email protected]"
phonePrimary string Primary phone number "+233501234567"
phoneSecondary string Secondary phone number "+233509876543"
occupation string Guardian's occupation "Software Engineer"
employer string Guardian's employer "TechCorp Ltd"
address string Guardian's residential address 15
nationalId string National identification number "GHA-123456789"
profilePhotoUrl string URL of the guardian's profile photo "https://storage.example.com/photos/guardian.jpg"
isEmergencyContact boolean Whether this guardian is an emergency contact
canPickupStudent boolean Whether this guardian is authorised to pick up the student
isPrimaryContact boolean Whether this guardian is the primary contact for the family
isActive boolean Whether this guardian record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateGuardianRequest } from '@smartsapp/sdk/staff';
import type { UpdateGuardianRequest, GuardianResponse } from '@smartsapp/sdk/staff';

const input: UpdateGuardianRequest = {
  familyId: "550e8400-e29b-41d4-a716-446655440000",
  guardianType: "FATHER",
  firstName: "James",
  middleName: "Robert"
};

const parsed = zUpdateGuardianRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: guardian, error } = await school.updateGuardian({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// guardian is typed as GuardianResponse

deleteGuardian()

Delete a guardian

DELETE /api/school/guardians/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteGuardian({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listGuardians()

List guardians with pagination

GET /api/school/guardians

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseGuardianResponse (200)

Field Type Description Example
content GuardianResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

GuardianResponse fields:

Field Type Description Example
id string (uuid) Guardian ID "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the family this guardian belongs to "550e8400-e29b-41d4-a716-446655440000"
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" Type of guardian: FATHER, MOTHER, LEGAL_GUARDIAN, OTHER "FATHER"
firstName string Guardian's first name "Kwame"
middleName string Guardian's middle name "Mensah"
lastName string Guardian's last name "Asante"
email string Guardian's email address "[email protected]"
phonePrimary string Primary phone number "+233501234567"
phoneSecondary string Secondary phone number "+233509876543"
occupation string Guardian's occupation "Software Engineer"
employer string Guardian's employer "TechCorp Ltd"
address string Guardian's residential address 15
nationalId string National identification number "GHA-123456789"
profilePhotoUrl string URL of the guardian's profile photo "https://storage.example.com/photos/guardian.jpg"
isEmergencyContact boolean Whether this guardian is an emergency contact
canPickupStudent boolean Whether this guardian is authorised to pick up the student
isPrimaryContact boolean Whether this guardian is the primary contact for the family
isActive boolean Whether this guardian record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseGuardianResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listGuardians({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const guardians = result.content;           // GuardianResponse[]
const { page, totalPages, totalElements, last } = result;

createGuardian()

Create a new guardian

POST /api/school/guardians

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateGuardianRequest

Field Type Required Description
familyId string (uuid) No ID of the family (optional)
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" No Type of guardian
firstName string Yes First name of the guardian
middleName string No Middle name of the guardian
lastName string Yes Last name of the guardian
email string No Email address
phonePrimary string Yes Primary phone number
phoneSecondary string No Secondary phone number
occupation string No Occupation of the guardian
employer string No Employer of the guardian
address string No Address of the guardian
nationalId string No National ID number
profilePhotoUrl string No URL of the profile photo
isEmergencyContact boolean No Whether this guardian is an emergency contact
canPickupStudent boolean No Whether this guardian can pick up the student
isPrimaryContact boolean No Whether this is the primary contact

Response: GuardianResponse (201)

Field Type Description Example
id string (uuid) Guardian ID "550e8400-e29b-41d4-a716-446655440000"
familyId string (uuid) ID of the family this guardian belongs to "550e8400-e29b-41d4-a716-446655440000"
guardianType "FATHER" | "MOTHER" | "STEPFATHER" | "STEPMOTHER" | "GRANDFATHER" | "GRANDMOTHER" | "UNCLE" | "AUNT" | "OLDER_SIBLING" | "LEGAL_GUARDIAN" | "FOSTER_PARENT" | "RELATIVE" | "FAMILY_FRIEND" | "OTHER" Type of guardian: FATHER, MOTHER, LEGAL_GUARDIAN, OTHER "FATHER"
firstName string Guardian's first name "Kwame"
middleName string Guardian's middle name "Mensah"
lastName string Guardian's last name "Asante"
email string Guardian's email address "[email protected]"
phonePrimary string Primary phone number "+233501234567"
phoneSecondary string Secondary phone number "+233509876543"
occupation string Guardian's occupation "Software Engineer"
employer string Guardian's employer "TechCorp Ltd"
address string Guardian's residential address 15
nationalId string National identification number "GHA-123456789"
profilePhotoUrl string URL of the guardian's profile photo "https://storage.example.com/photos/guardian.jpg"
isEmergencyContact boolean Whether this guardian is an emergency contact
canPickupStudent boolean Whether this guardian is authorised to pick up the student
isPrimaryContact boolean Whether this guardian is the primary contact for the family
isActive boolean Whether this guardian record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateGuardianRequest } from '@smartsapp/sdk/staff';
import type { CreateGuardianRequest, GuardianResponse } from '@smartsapp/sdk/staff';

const input: CreateGuardianRequest = {
  familyId: "550e8400-e29b-41d4-a716-446655440000",
  guardianType: "FATHER",
  firstName: "James",
  middleName: "Robert"
};

const parsed = zCreateGuardianRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: guardian, error } = await school.createGuardian({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// guardian is typed as GuardianResponse

Families

getFamily()

Get a family by ID

GET /api/school/families/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: FamilyResponse (200)

Field Type Description Example
id string (uuid) Family ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this family belongs to "550e8400-e29b-41d4-a716-446655440000"
familyName string Family surname "Asante"
familyCode string Unique family code "FAM-001"
primaryAddress string Primary residential address 15
primaryPhone string Primary contact phone number "+233501234567"
primaryEmail string Primary contact email "[email protected]"
notes string Additional notes about the family "Two children enrolled"
isActive boolean Whether the family record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { FamilyResponse } from '@smartsapp/sdk/staff';

const { data: family, error } = await school.getFamily({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// family is typed as FamilyResponse

updateFamily()

Update a family

PUT /api/school/families/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateFamilyRequest

Field Type Required Description
schoolId string (uuid) No ID of the school
familyName string No Name of the family
familyCode string No Unique family code
primaryAddress string No Primary address of the family
primaryPhone string No Primary phone number
primaryEmail string No Primary email address
notes string No Additional notes
isActive boolean No Whether the family is active

Response: FamilyResponse (200)

Field Type Description Example
id string (uuid) Family ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this family belongs to "550e8400-e29b-41d4-a716-446655440000"
familyName string Family surname "Asante"
familyCode string Unique family code "FAM-001"
primaryAddress string Primary residential address 15
primaryPhone string Primary contact phone number "+233501234567"
primaryEmail string Primary contact email "[email protected]"
notes string Additional notes about the family "Two children enrolled"
isActive boolean Whether the family record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateFamilyRequest } from '@smartsapp/sdk/staff';
import type { UpdateFamilyRequest, FamilyResponse } from '@smartsapp/sdk/staff';

const input: UpdateFamilyRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  familyName: "Doe Family",
  familyCode: "FAM-2024-001",
  primaryAddress: 123
};

const parsed = zUpdateFamilyRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: family, error } = await school.updateFamily({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// family is typed as FamilyResponse

deleteFamily()

Delete a family

DELETE /api/school/families/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteFamily({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listFamilies()

List families with pagination

GET /api/school/families

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseFamilyResponse (200)

Field Type Description Example
content FamilyResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

FamilyResponse fields:

Field Type Description Example
id string (uuid) Family ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this family belongs to "550e8400-e29b-41d4-a716-446655440000"
familyName string Family surname "Asante"
familyCode string Unique family code "FAM-001"
primaryAddress string Primary residential address 15
primaryPhone string Primary contact phone number "+233501234567"
primaryEmail string Primary contact email "[email protected]"
notes string Additional notes about the family "Two children enrolled"
isActive boolean Whether the family record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseFamilyResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listFamilies({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const familys = result.content;           // FamilyResponse[]
const { page, totalPages, totalElements, last } = result;

createFamily()

Create a new family

POST /api/school/families

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateFamilyRequest

Field Type Required Description
schoolId string (uuid) Yes ID of the school
familyName string Yes Name of the family
familyCode string No Unique family code
primaryAddress string No Primary address of the family
primaryPhone string No Primary phone number
primaryEmail string No Primary email address
notes string No Additional notes

Response: FamilyResponse (201)

Field Type Description Example
id string (uuid) Family ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this family belongs to "550e8400-e29b-41d4-a716-446655440000"
familyName string Family surname "Asante"
familyCode string Unique family code "FAM-001"
primaryAddress string Primary residential address 15
primaryPhone string Primary contact phone number "+233501234567"
primaryEmail string Primary contact email "[email protected]"
notes string Additional notes about the family "Two children enrolled"
isActive boolean Whether the family record is active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateFamilyRequest } from '@smartsapp/sdk/staff';
import type { CreateFamilyRequest, FamilyResponse } from '@smartsapp/sdk/staff';

const input: CreateFamilyRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  familyName: "Doe Family",
  familyCode: "FAM-2024-001",
  primaryAddress: 123
};

const parsed = zCreateFamilyRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: family, error } = await school.createFamily({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// family is typed as FamilyResponse

Classrooms

getClassroom()

Get a classroom by ID

GET /api/school/classrooms/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: ClassroomResponse (200)

Field Type Description Example
id string (uuid) Classroom ID "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section this classroom belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the classroom "Grade 3A"
code string Short unique code for the classroom "G3A"
academicYear string Academic year the classroom is associated with "2025/2026"
capacity integer (int32) Maximum student capacity 35
classTeacherId string (uuid) ID of the assigned class teacher "550e8400-e29b-41d4-a716-446655440000"
roomNumber string Physical room number "B-204"
isActive boolean Whether the classroom is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { ClassroomResponse } from '@smartsapp/sdk/staff';

const { data: classroom, error } = await school.getClassroom({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// classroom is typed as ClassroomResponse

updateClassroom()

Update a classroom

PUT /api/school/classrooms/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateClassroomRequest

Field Type Required Description
sectionId string (uuid) No ID of the section this classroom belongs to
name string No Name of the classroom
code string No Unique code for the classroom
academicYear string No Academic year
capacity integer (int32) No Maximum student capacity
classTeacherId string (uuid) No ID of the class teacher
roomNumber string No Room number
isActive boolean No Whether the classroom is active

Response: ClassroomResponse (200)

Field Type Description Example
id string (uuid) Classroom ID "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section this classroom belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the classroom "Grade 3A"
code string Short unique code for the classroom "G3A"
academicYear string Academic year the classroom is associated with "2025/2026"
capacity integer (int32) Maximum student capacity 35
classTeacherId string (uuid) ID of the assigned class teacher "550e8400-e29b-41d4-a716-446655440000"
roomNumber string Physical room number "B-204"
isActive boolean Whether the classroom is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateClassroomRequest } from '@smartsapp/sdk/staff';
import type { UpdateClassroomRequest, ClassroomResponse } from '@smartsapp/sdk/staff';

const input: UpdateClassroomRequest = {
  sectionId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Class 1A",
  code: "CLS-1A",
  academicYear: "2024-2025"
};

const parsed = zUpdateClassroomRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: classroom, error } = await school.updateClassroom({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// classroom is typed as ClassroomResponse

deleteClassroom()

Delete a classroom

DELETE /api/school/classrooms/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteClassroom({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listClassrooms()

List classrooms with pagination

GET /api/school/classrooms

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseClassroomResponse (200)

Field Type Description Example
content ClassroomResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

ClassroomResponse fields:

Field Type Description Example
id string (uuid) Classroom ID "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section this classroom belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the classroom "Grade 3A"
code string Short unique code for the classroom "G3A"
academicYear string Academic year the classroom is associated with "2025/2026"
capacity integer (int32) Maximum student capacity 35
classTeacherId string (uuid) ID of the assigned class teacher "550e8400-e29b-41d4-a716-446655440000"
roomNumber string Physical room number "B-204"
isActive boolean Whether the classroom is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseClassroomResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listClassrooms({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const classrooms = result.content;           // ClassroomResponse[]
const { page, totalPages, totalElements, last } = result;

createClassroom()

Create a new classroom

POST /api/school/classrooms

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateClassroomRequest

Field Type Required Description
sectionId string (uuid) Yes ID of the section this classroom belongs to
name string Yes Name of the classroom
code string No Unique code for the classroom
academicYear string No Academic year
capacity integer (int32) No Maximum student capacity
classTeacherId string (uuid) No ID of the class teacher
roomNumber string No Room number

Response: ClassroomResponse (201)

Field Type Description Example
id string (uuid) Classroom ID "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section this classroom belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the classroom "Grade 3A"
code string Short unique code for the classroom "G3A"
academicYear string Academic year the classroom is associated with "2025/2026"
capacity integer (int32) Maximum student capacity 35
classTeacherId string (uuid) ID of the assigned class teacher "550e8400-e29b-41d4-a716-446655440000"
roomNumber string Physical room number "B-204"
isActive boolean Whether the classroom is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateClassroomRequest } from '@smartsapp/sdk/staff';
import type { CreateClassroomRequest, ClassroomResponse } from '@smartsapp/sdk/staff';

const input: CreateClassroomRequest = {
  sectionId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Class 1A",
  code: "CLS-1A",
  academicYear: "2024-2025"
};

const parsed = zCreateClassroomRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: classroom, error } = await school.createClassroom({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// classroom is typed as ClassroomResponse

Campuses

getCampus()

Get a campus by ID

GET /api/school/campuses/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: CampusResponse (200)

Field Type Description Example
id string (uuid) Campus ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this campus belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the campus "East Campus"
code string Short unique code for the campus "EAST"
address string Physical address of the campus 45
phone string Contact phone number "+233302654321"
email string Contact email address "[email protected]"
principalName string Name of the campus principal "Dr. Ama Darko"
isActive boolean Whether the campus is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { CampusResponse } from '@smartsapp/sdk/staff';

const { data: campus, error } = await school.getCampus({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// campus is typed as CampusResponse

updateCampus()

Update a campus

PUT /api/school/campuses/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateCampusRequest

Field Type Required Description
schoolId string (uuid) No ID of the school this campus belongs to
name string No Name of the campus
code string No Unique code for the campus
address string No Physical address of the campus
phone string No Contact phone number
email string No Contact email address
principalName string No Name of the campus principal
isActive boolean No Whether the campus is active

Response: CampusResponse (200)

Field Type Description Example
id string (uuid) Campus ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this campus belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the campus "East Campus"
code string Short unique code for the campus "EAST"
address string Physical address of the campus 45
phone string Contact phone number "+233302654321"
email string Contact email address "[email protected]"
principalName string Name of the campus principal "Dr. Ama Darko"
isActive boolean Whether the campus is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateCampusRequest } from '@smartsapp/sdk/staff';
import type { UpdateCampusRequest, CampusResponse } from '@smartsapp/sdk/staff';

const input: UpdateCampusRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Main Campus",
  code: "MAIN",
  address: 456
};

const parsed = zUpdateCampusRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: campus, error } = await school.updateCampus({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// campus is typed as CampusResponse

deleteCampus()

Delete a campus

DELETE /api/school/campuses/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteCampus({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listCampuses()

List campuses with pagination

GET /api/school/campuses

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseCampusResponse (200)

Field Type Description Example
content CampusResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

CampusResponse fields:

Field Type Description Example
id string (uuid) Campus ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this campus belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the campus "East Campus"
code string Short unique code for the campus "EAST"
address string Physical address of the campus 45
phone string Contact phone number "+233302654321"
email string Contact email address "[email protected]"
principalName string Name of the campus principal "Dr. Ama Darko"
isActive boolean Whether the campus is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseCampusResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listCampuses({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const campus = result.content;           // CampusResponse[]
const { page, totalPages, totalElements, last } = result;

createCampus()

Create a new campus

POST /api/school/campuses

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateCampusRequest

Field Type Required Description
schoolId string (uuid) Yes ID of the school this campus belongs to
name string Yes Name of the campus
code string No Unique code for the campus
address string No Physical address of the campus
phone string No Contact phone number
email string No Contact email address
principalName string No Name of the campus principal

Response: CampusResponse (201)

Field Type Description Example
id string (uuid) Campus ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school this campus belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the campus "East Campus"
code string Short unique code for the campus "EAST"
address string Physical address of the campus 45
phone string Contact phone number "+233302654321"
email string Contact email address "[email protected]"
principalName string Name of the campus principal "Dr. Ama Darko"
isActive boolean Whether the campus is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateCampusRequest } from '@smartsapp/sdk/staff';
import type { CreateCampusRequest, CampusResponse } from '@smartsapp/sdk/staff';

const input: CreateCampusRequest = {
  schoolId: "550e8400-e29b-41d4-a716-446655440000",
  name: "Main Campus",
  code: "MAIN",
  address: 456
};

const parsed = zCreateCampusRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: campus, error } = await school.createCampus({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// campus is typed as CampusResponse

Academic Years

getAcademicYear()

Get an academic year by ID

GET /api/school/academic-years/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicYearResponse (200)

Field Type Description Example
id string (uuid) Academic year ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus (null for school-wide) "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section (null for campus-wide or school-wide) "550e8400-e29b-41d4-a716-446655440000"
name string Name of the academic year "2025/2026"
startDate string (date) Start date of the academic year "2025-09-01"
endDate string (date) End date of the academic year "2026-07-15"
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" How the year is divided: TERM, SEMESTER, QUARTER "TERM"
numberOfPeriods integer (int32) Number of periods in the academic year 3
isActive boolean Whether this academic year is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { AcademicYearResponse } from '@smartsapp/sdk/staff';

const { data: academicYear, error } = await school.getAcademicYear({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicYear is typed as AcademicYearResponse

updateAcademicYear()

Update an academic year

PUT /api/school/academic-years/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateAcademicYearRequest

Field Type Required Description
campusId string (uuid) No Campus ID for campus-level override (null for school-wide)
sectionId string (uuid) No Section ID for section-level override (null to inherit from campus/school)
name string No Name of the academic year
startDate string (date) No Start date of the academic year
endDate string (date) No End date of the academic year
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" No Type of periods used
isActive boolean No Whether the academic year is active

Response: AcademicYearResponse (200)

Field Type Description Example
id string (uuid) Academic year ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus (null for school-wide) "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section (null for campus-wide or school-wide) "550e8400-e29b-41d4-a716-446655440000"
name string Name of the academic year "2025/2026"
startDate string (date) Start date of the academic year "2025-09-01"
endDate string (date) End date of the academic year "2026-07-15"
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" How the year is divided: TERM, SEMESTER, QUARTER "TERM"
numberOfPeriods integer (int32) Number of periods in the academic year 3
isActive boolean Whether this academic year is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateAcademicYearRequest } from '@smartsapp/sdk/staff';
import type { UpdateAcademicYearRequest, AcademicYearResponse } from '@smartsapp/sdk/staff';

const input: UpdateAcademicYearRequest = {
  campusId: "550e8400-...",
  sectionId: "550e8400-...",
  name: "2025-2026",
  startDate: "2025-09-01"
};

const parsed = zUpdateAcademicYearRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicYear, error } = await school.updateAcademicYear({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicYear is typed as AcademicYearResponse

deleteAcademicYear()

Delete an academic year

DELETE /api/school/academic-years/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteAcademicYear({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listAcademicYears()

List academic years with pagination

GET /api/school/academic-years

Parameters:

Name Type In Required Description
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseAcademicYearResponse (200)

Field Type Description Example
content AcademicYearResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

AcademicYearResponse fields:

Field Type Description Example
id string (uuid) Academic year ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus (null for school-wide) "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section (null for campus-wide or school-wide) "550e8400-e29b-41d4-a716-446655440000"
name string Name of the academic year "2025/2026"
startDate string (date) Start date of the academic year "2025-09-01"
endDate string (date) End date of the academic year "2026-07-15"
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" How the year is divided: TERM, SEMESTER, QUARTER "TERM"
numberOfPeriods integer (int32) Number of periods in the academic year 3
isActive boolean Whether this academic year is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { PagedResponseAcademicYearResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await school.listAcademicYears({
  query: { page: 0, size: 0 }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const academicYears = result.content;           // AcademicYearResponse[]
const { page, totalPages, totalElements, last } = result;

createAcademicYear()

Create a new academic year

POST /api/school/academic-years

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateAcademicYearRequest

Field Type Required Description
campusId string (uuid) No Campus ID for campus-level override (null for school-wide)
sectionId string (uuid) No Section ID for section-level override (null to inherit from campus/school)
name string Yes Name of the academic year
startDate string (date) Yes Start date of the academic year
endDate string (date) Yes End date of the academic year
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" Yes Type of periods used

Response: AcademicYearResponse (201)

Field Type Description Example
id string (uuid) Academic year ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus (null for school-wide) "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section (null for campus-wide or school-wide) "550e8400-e29b-41d4-a716-446655440000"
name string Name of the academic year "2025/2026"
startDate string (date) Start date of the academic year "2025-09-01"
endDate string (date) End date of the academic year "2026-07-15"
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" How the year is divided: TERM, SEMESTER, QUARTER "TERM"
numberOfPeriods integer (int32) Number of periods in the academic year 3
isActive boolean Whether this academic year is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateAcademicYearRequest } from '@smartsapp/sdk/staff';
import type { CreateAcademicYearRequest, AcademicYearResponse } from '@smartsapp/sdk/staff';

const input: CreateAcademicYearRequest = {
  campusId: "550e8400-...",
  sectionId: "550e8400-...",
  name: "2025-2026",
  startDate: "2025-09-01"
};

const parsed = zCreateAcademicYearRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicYear, error } = await school.createAcademicYear({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicYear is typed as AcademicYearResponse

resolveAcademicYear()

Resolve the effective academic year with inheritance

GET /api/school/academic-years/resolve

Parameters:

Name Type In Required Description
campusId string (uuid) query No
sectionId string (uuid) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicYearResponse (200)

Field Type Description Example
id string (uuid) Academic year ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus (null for school-wide) "550e8400-e29b-41d4-a716-446655440000"
sectionId string (uuid) ID of the section (null for campus-wide or school-wide) "550e8400-e29b-41d4-a716-446655440000"
name string Name of the academic year "2025/2026"
startDate string (date) Start date of the academic year "2025-09-01"
endDate string (date) End date of the academic year "2026-07-15"
periodType "TERM" | "SEMESTER" | "QUARTER" | "TRIMESTER" How the year is divided: TERM, SEMESTER, QUARTER "TERM"
numberOfPeriods integer (int32) Number of periods in the academic year 3
isActive boolean Whether this academic year is currently active
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { AcademicYearResponse } from '@smartsapp/sdk/staff';

const { data: academicYear, error } = await school.resolveAcademicYear({
  query: { campusId: "...", sectionId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicYear is typed as AcademicYearResponse

Academic Periods

getAcademicPeriod()

Get an academic period by ID

GET /api/school/academic-periods/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicPeriodResponse (200)

Field Type Description Example
id string (uuid) Academic period ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year this period belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the period "Term 1"
startDate string (date) Start date of the period "2025-09-01"
endDate string (date) End date of the period "2025-12-15"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { AcademicPeriodResponse } from '@smartsapp/sdk/staff';

const { data: academicPeriod, error } = await school.getAcademicPeriod({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicPeriod is typed as AcademicPeriodResponse

updateAcademicPeriod()

Update an academic period

PUT /api/school/academic-periods/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateAcademicPeriodRequest

Field Type Required Description
academicYearId string (uuid) No ID of the academic year this period belongs to
name string No Name of the period
startDate string (date) No Start date of the period
endDate string (date) No End date of the period

Response: AcademicPeriodResponse (200)

Field Type Description Example
id string (uuid) Academic period ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year this period belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the period "Term 1"
startDate string (date) Start date of the period "2025-09-01"
endDate string (date) End date of the period "2025-12-15"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateAcademicPeriodRequest } from '@smartsapp/sdk/staff';
import type { UpdateAcademicPeriodRequest, AcademicPeriodResponse } from '@smartsapp/sdk/staff';

const input: UpdateAcademicPeriodRequest = {
  academicYearId: "550e8400-...",
  name: "Term 1",
  startDate: "2025-09-01",
  endDate: "2025-12-15"
};

const parsed = zUpdateAcademicPeriodRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicPeriod, error } = await school.updateAcademicPeriod({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicPeriod is typed as AcademicPeriodResponse

deleteAcademicPeriod()

Delete an academic period

DELETE /api/school/academic-periods/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteAcademicPeriod({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listAcademicPeriods()

List academic periods for an academic year

GET /api/school/academic-periods

Parameters:

Name Type In Required Description
academicYearId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicPeriodResponse[] (200)

Field Type Description Example
id string (uuid) Academic period ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year this period belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the period "Term 1"
startDate string (date) Start date of the period "2025-09-01"
endDate string (date) End date of the period "2025-12-15"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.listAcademicPeriods({
  query: { academicYearId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as AcademicPeriodResponse[]

createAcademicPeriod()

Create a new academic period

POST /api/school/academic-periods

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateAcademicPeriodRequest

Field Type Required Description
academicYearId string (uuid) Yes ID of the academic year this period belongs to
name string Yes Name of the period
startDate string (date) Yes Start date of the period
endDate string (date) Yes End date of the period

Response: AcademicPeriodResponse (201)

Field Type Description Example
id string (uuid) Academic period ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year this period belongs to "550e8400-e29b-41d4-a716-446655440000"
name string Name of the period "Term 1"
startDate string (date) Start date of the period "2025-09-01"
endDate string (date) End date of the period "2025-12-15"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateAcademicPeriodRequest } from '@smartsapp/sdk/staff';
import type { CreateAcademicPeriodRequest, AcademicPeriodResponse } from '@smartsapp/sdk/staff';

const input: CreateAcademicPeriodRequest = {
  academicYearId: "550e8400-...",
  name: "Term 1",
  startDate: "2025-09-01",
  endDate: "2025-12-15"
};

const parsed = zCreateAcademicPeriodRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicPeriod, error } = await school.createAcademicPeriod({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicPeriod is typed as AcademicPeriodResponse

Academic Holidays

getAcademicHoliday()

Get an academic holiday by ID

GET /api/school/academic-holidays/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicHolidayResponse (200)

Field Type Description Example
id string (uuid) Academic holiday ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year "550e8400-e29b-41d4-a716-446655440000"
academicPeriodId string (uuid) ID of the academic period this holiday falls within "550e8400-e29b-41d4-a716-446655440000"
name string Name of the holiday "Mid-term break"
startDate string (date) Start date of the holiday "2025-10-20"
endDate string (date) End date of the holiday "2025-10-24"
description string Additional details about the holiday "School closed for all students and staff"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { AcademicHolidayResponse } from '@smartsapp/sdk/staff';

const { data: academicHoliday, error } = await school.getAcademicHoliday({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicHoliday is typed as AcademicHolidayResponse

updateAcademicHoliday()

Update an academic holiday

PUT /api/school/academic-holidays/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: UpdateAcademicHolidayRequest

Field Type Required Description
academicYearId string (uuid) No ID of the academic year this holiday belongs to
academicPeriodId string (uuid) No ID of the academic period (null for year-level breaks)
name string No Name of the holiday
startDate string (date) No Start date of the holiday
endDate string (date) No End date of the holiday
description string No Description of the holiday

Response: AcademicHolidayResponse (200)

Field Type Description Example
id string (uuid) Academic holiday ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year "550e8400-e29b-41d4-a716-446655440000"
academicPeriodId string (uuid) ID of the academic period this holiday falls within "550e8400-e29b-41d4-a716-446655440000"
name string Name of the holiday "Mid-term break"
startDate string (date) Start date of the holiday "2025-10-20"
endDate string (date) End date of the holiday "2025-10-24"
description string Additional details about the holiday "School closed for all students and staff"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zUpdateAcademicHolidayRequest } from '@smartsapp/sdk/staff';
import type { UpdateAcademicHolidayRequest, AcademicHolidayResponse } from '@smartsapp/sdk/staff';

const input: UpdateAcademicHolidayRequest = {
  academicYearId: "550e8400-...",
  academicPeriodId: "550e8400-...",
  name: "Christmas Break",
  startDate: "2025-12-20"
};

const parsed = zUpdateAcademicHolidayRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicHoliday, error } = await school.updateAcademicHoliday({
  body: input,
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicHoliday is typed as AcademicHolidayResponse

deleteAcademicHoliday()

Delete an academic holiday

DELETE /api/school/academic-holidays/{id}

Parameters:

Name Type In Required Description
id string (uuid) path Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: void (204)

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.deleteAcademicHoliday({
  path: { id: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

listAcademicHolidays()

List academic holidays for an academic year

GET /api/school/academic-holidays

Parameters:

Name Type In Required Description
academicYearId string (uuid) query Yes
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: AcademicHolidayResponse[] (200)

Field Type Description Example
id string (uuid) Academic holiday ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year "550e8400-e29b-41d4-a716-446655440000"
academicPeriodId string (uuid) ID of the academic period this holiday falls within "550e8400-e29b-41d4-a716-446655440000"
name string Name of the holiday "Mid-term break"
startDate string (date) Start date of the holiday "2025-10-20"
endDate string (date) End date of the holiday "2025-10-24"
description string Additional details about the holiday "School closed for all students and staff"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';

const { data, error } = await school.listAcademicHolidays({
  query: { academicYearId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// data is typed as AcademicHolidayResponse[]

createAcademicHoliday()

Create a new academic holiday

POST /api/school/academic-holidays

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreateAcademicHolidayRequest

Field Type Required Description
academicYearId string (uuid) Yes ID of the academic year this holiday belongs to
academicPeriodId string (uuid) No ID of the academic period (null for year-level breaks)
name string Yes Name of the holiday
startDate string (date) Yes Start date of the holiday
endDate string (date) Yes End date of the holiday
description string No Description of the holiday

Response: AcademicHolidayResponse (201)

Field Type Description Example
id string (uuid) Academic holiday ID "550e8400-e29b-41d4-a716-446655440000"
academicYearId string (uuid) ID of the academic year "550e8400-e29b-41d4-a716-446655440000"
academicPeriodId string (uuid) ID of the academic period this holiday falls within "550e8400-e29b-41d4-a716-446655440000"
name string Name of the holiday "Mid-term break"
startDate string (date) Start date of the holiday "2025-10-20"
endDate string (date) End date of the holiday "2025-10-24"
description string Additional details about the holiday "School closed for all students and staff"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school, zCreateAcademicHolidayRequest } from '@smartsapp/sdk/staff';
import type { CreateAcademicHolidayRequest, AcademicHolidayResponse } from '@smartsapp/sdk/staff';

const input: CreateAcademicHolidayRequest = {
  academicYearId: "550e8400-...",
  academicPeriodId: "550e8400-...",
  name: "Christmas Break",
  startDate: "2025-12-20"
};

const parsed = zCreateAcademicHolidayRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data: academicHoliday, error } = await school.createAcademicHoliday({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// academicHoliday is typed as AcademicHolidayResponse

My Staff Profile

getMyStaffProfile()

Get the authenticated user's staff profile

GET /api/school/my-staff-profile

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: StaffResponse (200)

Field Type Description Example
id string (uuid) Staff member ID "550e8400-e29b-41d4-a716-446655440000"
schoolId string (uuid) ID of the school "550e8400-e29b-41d4-a716-446655440000"
campusId string (uuid) ID of the campus the staff member is assigned to "550e8400-e29b-41d4-a716-446655440000"
staffIdNumber string Staff ID number "STF-2026-001"
firstName string First name "Abena"
middleName string Middle name "Osei"
lastName string Last name "Mensah"
email string Email address "[email protected]"
phone string Phone number "+233501234567"
dateOfBirth string (date) Date of birth "1985-06-15"
gender "MALE" | "FEMALE" | "OTHER" Gender "MALE"
profilePhotoUrl string URL of the staff member's profile photo "https://storage.example.com/photos/staff.jpg"
role "TEACHER" | "ADMINISTRATOR" | "HEADMASTER" | "SUPPORT" | "OTHER" Staff role: TEACHER, ADMIN, PRINCIPAL, etc. "TEACHER"
department string Department name "Mathematics"
employmentType "FULL_TIME" | "PART_TIME" | "CONTRACT" Employment type: FULL_TIME, PART_TIME, CONTRACT "FULL_TIME"
hireDate string (date) Date the staff member was hired "2024-09-01"
status "ACTIVE" | "INACTIVE" | "ON_LEAVE" | "TERMINATED" Employment status "ACTIVE"
createdAt string (date-time) When the record was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the record was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { StaffResponse } from '@smartsapp/sdk/staff';

const { data: staff, error } = await school.getMyStaffProfile();

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// staff is typed as StaffResponse

My School

getMySchool()

Get the authenticated user's school

GET /api/school/my-school

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: SchoolResponse (200)

Field Type Description Example
id string (uuid) School ID "550e8400-e29b-41d4-a716-446655440000"
name string Name of the school "Lincoln International Academy"
code string Short unique code for the school "LIA"
logoUrl string URL of the school logo "https://storage.example.com/logos/lia.png"
address string Physical address of the school 12
phone string Contact phone number "+233302123456"
email string Contact email address "[email protected]"
website string School website URL "https://lincolnacademy.edu"
accreditationNumber string Government accreditation number "ACC-2024-00123"
defaultCurrency string Default currency code for the school "GHS"
isActive boolean Whether the school is currently active
createdAt string (date-time) When the school was created "2026-01-15T10:30:00Z"
updatedAt string (date-time) When the school was last updated "2026-01-15T10:30:00Z"

Example:

import { school } from '@smartsapp/sdk/staff';
import type { SchoolResponse } from '@smartsapp/sdk/staff';

const { data: school, error } = await school.getMySchool();

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}
// school is typed as SchoolResponse


Platform (shared)

These modules are available in both staff and parent SDKs.

Wallet (wallet)

Wallet

creditWallet()

Credit a student's Sika ID wallet

POST /api/wallet/credit

Parameters:

Name Type In Required Description
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Request Body: CreditWalletRequest

Field Type Required Description
studentId string (uuid) Yes ID of the student whose wallet is being credited
amount number Yes Amount to credit (positive)
currency string Yes ISO 4217 currency code

Response: void (200)

Example:

import { wallet, zCreditWalletRequest } from '@smartsapp/sdk/staff';
import type { CreditWalletRequest } from '@smartsapp/sdk/staff';

const input: CreditWalletRequest = {
  studentId: "00000000-0000-0000-0000-000000000001",
  amount: 150.0,
  currency: "GHS"
};

const parsed = zCreditWalletRequest.safeParse(input);
if (!parsed.success) {
  console.error(parsed.error.issues);
  // [{ path: ['fieldName'], message: 'Required', code: 'invalid_type' }, ...]
  return;
}

const { data, error } = await wallet.creditWallet({
  body: input
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

Audit (audit)

Audit Logs

listAuditEntries()

List audit log entries with optional filters

GET /api/platform/audit-logs

Parameters:

Name Type In Required Description
entityType string query No
entityId string query No
actorId string query No
page integer (int32) query No
size integer (int32) query No
X-Request-Id string (uuid) header No Optional client-generated request ID for tracing. Auto-generated if omitted.

Response: PagedResponseAuditLogResponse (200)

Field Type Description Example
content AuditLogResponse[] Items on the current page
page integer (int32) Current page number (0-based) 0
size integer (int32) Page size 20
totalElements integer (int64) Total number of elements 42
totalPages integer (int32) Total number of pages 3
last boolean Whether this is the last page

AuditLogResponse fields:

Field Type Description Example
id string (uuid) Audit log entry ID "550e8400-..."
entityType string Type of the audited entity "CanteenOrder"
entityId string ID of the audited entity
action "CREATE" | "UPDATE" | "DELETE" Action performed "CREATE"
actorId string ID of the user who performed the action
beforeState string Entity state before the action (JSON)
afterState string Entity state after the action (JSON)
createdAt string (date-time) When the action occurred "2026-01-01T08:00:00Z"

Example:

import { audit } from '@smartsapp/sdk/staff';
import type { PagedResponseAuditLogResponse } from '@smartsapp/sdk/staff';

const { data: result, error } = await audit.listAuditEntries({
  query: { entityType: "...", entityId: "...", actorId: "..." }
});

if (error) {
  // error is typed as ProblemDetail (RFC 9457)
  // { type, title, status, detail }
  console.error(error.title, error.detail);
  return;
}

const auditLogs = result.content;           // AuditLogResponse[]
const { page, totalPages, totalElements, last } = result;

Auth (auth)

Not yet implemented

This module is planned but not yet available.

Chat (chat)

Not yet implemented

This module is planned but not yet available.

Engagement (engagement)

Not yet implemented

This module is planned but not yet available.

Notifications (notifications)

Not yet implemented

This module is planned but not yet available.