TerraGo API

Users

All human accounts on the platform: parents, school administrators (Administrative Staff) and staff (drivers, bus minders, security, transport managers). Endpoints to self-sign-up or admin-register accounts, update profiles, list and filter by role/school, look up by phone, manage per-user notification channel preferences, assign zones/locations to staff, and trigger the internal parent↔supervisor re-sync.

13 endpoint(s)
GET List {{url}}/users

Retrieve a paginated list of all users in the system, across every role, with optional filtering and search. Primarily an admin/back-office listing endpoint.

Query Parameters

  • per_page (integer, optional, default 10, max 20): Page size.
  • page (integer, optional): Page number.
  • is_active (boolean, optional): Filter by active (1) / inactive (0).
  • role_id (string UUID, optional): Filter to a single role (matched by the role's UUID).
  • search (string, optional): Matches against full name, email, institution, or phone.

Response

Paginated collection of users (UserResource).

Notes

  • Unlike GET /users/staff and GET /users/parents, this is not role-scoped — it returns users of every role.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "data": [
        {
            "id": "a0dceac9-cf75-41fd-aed3-608510ade207",
            "first_name": "System",
            "middle_name": null,
            "last_name": "Admin",
            "phone": null,
            "email": "admin@application.com",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-03 22:10:21",
            "gender": null,
            "third_party_id": null,
            "is_active": true,
            "role": "System Admin",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-11-27 13:35:56"
        },
        {
            "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
            "first_name": "Collins",
            "middle_name": null,
            "last_name": "Muriuki",
            "phone": null,
            "email": "muriukicollins@gmail.com",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-03 22:10:21",
            "gender": null,
            "third_party_id": null,
            "is_active": true,
            "role": "System Admin",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-11-27 16:05:01"
        },
        {
            "id": "95db0ec4-83ab-4a7a-aff4-383e738e8d34",
            "first_name": "LaParent",
            "middle_name": null,
            "last_name": "Ente",
            "phone": "+254706347307",
            "email": "laparent@gmail.com",
            "identification_document": "national_id",
            "identification_number": "40123123",
            "dob": "1995-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "cccf3a09-62e2-4026-947d-97aedfa6d6a7",
            "is_active": true,
            "role": "Parent",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 01:14:03"
        },
        {
            "id": "c31727b0-0130-46f0-92f2-d2b0bec124ab",
            "first_name": "LaParent",
            "middle_name": null,
            "last_name": "Ente",
            "phone": "+2547063473076",
            "email": "laparent12@gmail.com",
            "identification_document": "passport",
            "identification_number": "401231239",
            "dob": "1995-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "f8af6128-9545-41d9-94bc-94bfacc78e66",
            "is_active": true,
            "role": "Parent",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 02:00:19"
        },
        {
            "id": "472df951-54eb-4b3b-b224-105d8b9428b4",
            "first_name": "Likg",
            "middle_name": "K",
            "last_name": "Last",
            "phone": "+254794237685",
            "email": "ling12@gmail.com",
            "identification_document": "passport",
            "identification_number": "123456712",
            "dob": "1996-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "83be7d0b-389c-4129-a0f3-3dbf45ba58b6",
            "is_active": true,
            "role": "Parent",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 02:09:26"
        },
        {
            "id": "9dcc2d36-5297-4c26-98db-660af8e00909",
            "first_name": "Le",
            "middle_name": null,
            "last_name": "Parent",
            "phone": "+254794237684",
            "email": "ling@gmqil.com",
            "identification_document": "national_id",
            "identification_number": "12312345",
            "dob": "1998-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "f92de02b-f29d-4a46-a442-313fbec8faa7",
            "is_active": true,
            "role": "Parent",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 02:16:38"
        },
        {
            "id": "c011772f-7677-4b6b-bd6e-21a2ba6d1841",
            "first_name": "Francis",
            "middle_name": "Njenga",
            "last_name": "Chege",
            "phone": "+254722626879",
            "email": "fchege2015ios@gmail.com",
            "identification_document": "national_id",
            "identification_number": "36898912",
            "dob": "2000-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "ddab60b7-cab6-4ff7-82ef-c8a2fe31698f",
            "is_active": true,
            "role": "Staff",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 12:58:11"
        }
    ],
    "links": {
        "first": "https://terragostg.terrasofthq.com/api/users?page=1",
        "last": "https://terragostg.terrasofthq.com/api/users?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "page": null,
                "active": false
            },
            {
                "url": "https://terragostg.terrasofthq.com/api/users?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "https://terragostg.terrasofthq.com/api/users",
        "per_page": 15,
        "to": 7,
        "total": 7
    },
    "status": 200,
    "message": "Accounts Retrieved Successfully"
}
POST Register {{url}}/users/register

Create a new user account as an authenticated admin (e.g. a school admin onboarding a driver, bus minder, parent, or other staff). Runs the shared CreateAccount action.

Request Body (common fields)

  • firstname, lastname (string, required); middle_name (string, optional).
  • email (string, required), phone (string, required, E.164 e.g. +254713452890).
  • identificationdocument / identificationnumber (string): required for role PARENT.
  • dob (string, DD-MM-YYYY), gender (MALE | FEMALE | OTHER | N/A).
  • role_id (string UUID, required): the role to assign.
  • beneficiary_id (string): required when creating Staff (drivers, bus minders).
  • School fields (school, school_type, location) where applicable.

Behavior

  • The account is created active and email-verified immediately (admin-created).
  • After creation the supervisor's onboarding setup status is refreshed (so the school's "staff / parents added" checklist updates).

Notes

  • Requires a bearer token (auth:api).
  • Differs from Signup, which is the public self-registration route and does not refresh supervisor setup status.

Response

The created user (data) — id (uuid), names, email, phone, role, school, is_active.

Auth
Bearer token
Request Body
{
    "first_name" : "Alex",
    "middle_name": "Kimani",
    "last_name" : "Maina",
    "email": "alex.kimani@example.com",
    "phone" : "+254713452890",
    "identification_document": "national_id",
    "identification_number": "42876543",
    "dob":"14-09-1998",
    "gender": "MALE", //only use: MALE, FEMALE, OTHER, N/A
    "school": "Ridgeways Academy", //optional
    "location": "Thika, Kenya", //optional
    "school_type": "KINDERGARTEN", //(optional) only use: PRIMARY_SCHOOL, SECONDARY_SCHOOL, HIGH_SCHOOL, KINDERGARTEN, INTERNATIONAL, N/A
    "role_id": "4583792c-7951-4bf5-ba5f-68c374a12420",
    "supervisor_id": "7b92e1e0-f73c-4c68-8873-ada9182dd3cc", //administrative staff id, required for creating staff i.e drivers/bus minders
    "staff_type": "BUS_MINDER", //optional but required for creating staff i.e drivers/bus minders only use: BUS_MINDER, TEACHER, SECURITY, DRIVER, OTHER, N/A
    "password": "SecurePass@2024", //optional
    "password_confirmation": "SecurePass@2024"
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "045b2bc0-c772-470e-ab34-88e795ad7226",
        "first_name": "Alex",
        "middle_name": "Kimani",
        "last_name": "Maina",
        "phone": "+254713452890",
        "email": "alex.kimani@example.com",
        "identification_document": "national_id",
        "identification_number": "42876543",
        "dob": "1998-09-14 00:00:00",
        "gender": "Male",
        "third_party_id": "9ae791d0-7b06-476c-bcab-f4a183469284",
        "is_active": true,
        "role": "Administrative Staff",
        "metadata": null,
        "image": null,
        "notes": null,
        "created_at": "2025-12-04 11:09:14"
    },
    "message": "Account Created Successfully"
}
POST Signup {{url}}/users/sign-up

Public self-registration — lets a new user create their own TerraGo account without being authenticated (no bearer token required). Supports roles such as PARENT and SCHOOL. Runs the shared CreateAccount action.

Request Body (common fields)

  • firstname, lastname (string, required); middle_name (string, optional).
  • email (string, required), phone (string, required, e.g. +254733556677).
  • identificationdocument / identificationnumber (string): required for role PARENT.
  • dob (string, DD-MM-YYYY), gender (MALE | FEMALE | OTHER | N/A).
  • role_id (string UUID, required).
  • School fields (school, school_type, location) for a school signup.

Behavior

  • The account is created active and email-verified.

Notes

  • This is the unauthenticated counterpart to Register. Use Register when an admin creates the account; use Signup for self-service.
  • Unlike Register, it does not refresh a supervisor's onboarding setup status.

Response

The newly created user (data) — same shape as Register.

Auth
None
Used On
Request Body
{
"first_name": "Kevin",
"middle_name": "Mwangi",
"last_name": "Kariuki",
"email": "kevin.kariuki@example.com",
"phone": "+254733556677",
"identification_document": "national_id", //(required) for role PARENT
"identification_number": "49283746",  //(required) for role PARENT
"dob": "22-03-1998",
"gender": "MALE", //only use: MALE, FEMALE, OTHER, N/A  ::   //(required) for role PARENT
"school": "Greenwood International School", //optional
"location": "Nakuru, Kenya", //optional
"school_type": "INTERNATIONAL", //(optional) only use: PRIMARY_SCHOOL, SECONDARY_SCHOOL, HIGH_SCHOOL, KINDERGARTEN, INTERNATIONAL, N/A
"role_id": "582c5dc9-4ef6-4238-98e3-7318c57349fb",
"supervisor_id": "7b92e1e0-f73c-4c68-8873-ada9182dd3cc", //administrative staff id, required for creating staff i.e drivers/bus minders
"password": "Password@2025", //optional
"password_confirmation": "Password@2025"
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "cf7a3821-e6be-490f-85b9-6f7ca3585aad",
        "first_name": "Kevin",
        "middle_name": "Mwangi",
        "last_name": "Kariuki",
        "phone": "+254733556677",
        "email": "kevin.kariuki@example.com",
        "identification_document": "national_id",
        "identification_number": "49283746",
        "dob": "1998-03-22 00:00:00",
        "gender": "Male",
        "third_party_id": "24521db0-7a8d-45fa-9306-d9efc8a8e8aa",
        "is_active": true,
        "role": "Parent",
        "metadata": null,
        "image": null,
        "notes": null,
        "created_at": "2025-12-05 12:47:21"
    },
    "message": "Account Created Successfully"
}
PUT Update {{url}}/users/update/448e2ae4-48b4-4842-84b1-a73c84d21de1

Purpose: This endpoint updates an existing user's profile information. It is used to modify user details such as name, contact information, identification, and role assignments.

Request Body: Send a JSON object with the following fields:

  • first_name (string, required): User's first name.
  • middle_name (string, required): User's middle name.
  • last_name (string, required): User's last name.
  • email (string, required): User's email address.
  • phone (string, required): User's phone number (e.g., +254713452890).
  • identificationdocument (string, required): Type of identification document (e.g., "nationalid").
  • identification_number (string, required): Identification document number.
  • dob (string, required): Date of birth (format: DD-MM-YYYY).
  • gender (string, required): Gender of the user. Allowed values: MALE, FEMALE, OTHER, N/A.
  • school (string, optional): Name of the user's school.
  • location (string, optional): User's location (e.g., city, country).
  • schooltype (string, optional): Type of school. Allowed values: PRIMARYSCHOOL, SECONDARYSCHOOL, HIGHSCHOOL, KINDERGARTEN, INTERNATIONAL, N/A.
  • role_id (string, required): Role identifier for the user.
  • beneficiary_id (string, required for staff): Beneficiary identifier. Required when creating staff (e.g., drivers, bus minders).

Expected Response:

  • On success, returns a JSON object with the updated user profile and a status code of 200 OK.
  • On error, returns an error message and the appropriate HTTP status code (e.g., 400 for validation errors).

Notes:

  • Ensure all required fields are provided.
  • Use only the allowed values for gender and school_type.
  • The endpoint URL requires the user's unique ID as a path parameter.

References:

Auth
Bearer token
Request Body
{
    "first_name" : "Alex",
    "middle_name": "Kimani",
    "last_name" : "Maina",
    "email": "alex.kimani@example.com",
    "phone" : "+254713452890",
    "identification_document": "national_id",
    "identification_number": "42876543",
    "dob":"14-09-1998",
    "gender": "MALE", //only use: MALE, FEMALE, OTHER, N/A
    "school": "Ridgeways Academy", //optional
    "location": "Thika, Kenya", //optional
    "school_type": "KINDERGARTEN", //(optional) only use: PRIMARY_SCHOOL, SECONDARY_SCHOOL, HIGH_SCHOOL, KINDERGARTEN, INTERNATIONAL, N/A
    "metadata" : {
        "assigned_zone" : {
            "id": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
            "name": "Terra Hq",
            "zone_type": null,
            "description": "nnn",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        }
    }
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "448e2ae4-48b4-4842-84b1-a73c84d21de1",
        "first_name": "Alex",
        "middle_name": "Kimani",
        "last_name": "Maina",
        "phone": "+254713452890",
        "email": "alex.kimani@example.com",
        "identification_document": "national_id",
        "identification_number": "42876543",
        "dob": "1998-09-14 00:00:00",
        "gender": "Male",
        "third_party_id": "503804f8-6a9b-495c-adb2-91e8228febbd",
        "is_active": true,
        "role": "Administrative Staff",
        "metadata": null,
        "image": null,
        "notes": null,
        "created_at": "2025-12-04 12:33:26"
    },
    "message": "Account Updated Successfully"
}
GET Show {{url}}/users/448e2ae4-48b4-4842-84b1-a73c84d21de1

Retrieve a single user by their UUID, including their supervisor relationship.

Path Parameters

  • id (string UUID, required): The user's UUID.

Response

The user profile (UserResource).

Notes

  • Returns 404 if no user matches the UUID.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "448e2ae4-48b4-4842-84b1-a73c84d21de1",
        "first_name": "Alex",
        "middle_name": "Kimani",
        "last_name": "Maina",
        "phone": "+254713452890",
        "email": "alex.kimani@example.com",
        "identification_document": "national_id",
        "identification_number": "42876543",
        "dob": "1998-09-14 00:00:00",
        "gender": "Male",
        "third_party_id": "503804f8-6a9b-495c-adb2-91e8228febbd",
        "is_active": true,
        "role": "Administrative Staff",
        "metadata": null,
        "image": null,
        "notes": null,
        "created_at": "2025-12-04 12:33:26"
    },
    "message": "Account Retrieved Successfully"
}
GET Show By Phone {{url}}/users/show-by-phone/+254713452890

Look up a user by phone number (path parameter, E.164 format e.g. +254713452890). The number is normalized server-side before matching, and the user's assigned zones/locations are eager-loaded. Handy for phone-first flows (e.g. resolving a caller/WhatsApp contact to an account).

Path Parameters

  • phone_number (string, required): Phone number in E.164 format.

Query Parameters

  • role (string, optional): Restrict the match to a specific role name (e.g. only match a Parent with this number).

Notes

  • Returns the first matching user; if role is supplied, only a user with that role is returned.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "448e2ae4-48b4-4842-84b1-a73c84d21de1",
        "first_name": "Alex",
        "middle_name": "Kimani",
        "last_name": "Maina",
        "phone": "+254713452890",
        "email": "alex.kimani@example.com",
        "identification_document": "national_id",
        "identification_number": "42876543",
        "dob": "1998-09-14 00:00:00",
        "gender": "Male",
        "third_party_id": "503804f8-6a9b-495c-adb2-91e8228febbd",
        "is_active": true,
        "role": "Administrative Staff",
        "metadata": null,
        "image": null,
        "notes": null,
        "created_at": "2025-12-04 12:33:26"
    },
    "message": "Account Retrieved Successfully"
}
GET List Staff Users {{url}}/users/staff

Retrieve a paginated list of Staff users (drivers, bus minders, security, transport managers, etc.) with optional filters. Useful for admin screens that need to assign a driver to a trip or filter by supervisor.

Query Parameters

  • per_page (integer, optional, default 10, max 20): Page size.
  • page (integer, optional): Page number.
  • is_active (boolean, optional): Filter by active/inactive status.
  • stafftype (string, optional): One of TEACHER, SECURITY, DRIVER, BUSMINDER, TRANSPORT_MANAGER, PRINCIPAL, DIRECTOR, OTHER, N/A.
  • supervisor_id (string UUID, optional): Only return staff supervised by this Administrative Staff (school admin).
  • search (string, optional): Matches against name, email, or phone.

Notes

  • Only returns users whose role is Staff.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Request Body
{
    "is_active": "true",  // true = active, false = deactivated
    "supervisor_id": "68b86410-e6e8-4b5f-9a3d-8265a7773c0e"  // School (Administrative Staff) UUID this belongs to
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "cff607d4-c366-4aa7-9335-4b3939f18350",
            "first_name": "Michael",
            "middle_name": null,
            "last_name": "Njoroge",
            "phone": "+254716436346",
            "email": "admin2@staff.co.ke",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-15 10:37:35",
            "gender": "Male",
            "third_party_id": "a6f12ff4-2815-4a66-978e-b6eb9bc39016",
            "is_active": true,
            "role": "Staff",
            "institution": null,
            "institution_type": null,
            "staff_type": "TEACHER",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-11 15:52:12"
        },
        {
            "id": "c011772f-7677-4b6b-bd6e-21a2ba6d1841",
            "first_name": "Francis",
            "middle_name": "Njenga",
            "last_name": "Chege",
            "phone": "+254722626879",
            "email": "fchege2015ios@gmail.com",
            "identification_document": "national_id",
            "identification_number": "36898912",
            "dob": "2000-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "ddab60b7-cab6-4ff7-82ef-c8a2fe31698f",
            "is_active": true,
            "role": "Staff",
            "institution": "Alliance High School",
            "institution_type": "High School",
            "staff_type": null,
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-03 12:58:11"
        },
        {
            "id": "8945d636-ee2a-45f6-929e-c817d20570ba",
            "first_name": "Last",
            "middle_name": "Custodian",
            "last_name": "Updated",
            "phone": "+254732452345",
            "email": "custon@gmail.com",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-15 10:37:35",
            "gender": "Male",
            "third_party_id": "fe948b43-f374-4c8a-afc2-84efcc3b886c",
            "is_active": true,
            "role": "Staff",
            "institution": null,
            "institution_type": null,
            "staff_type": "SECURITY",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-12 06:31:29"
        },
        {
            "id": "77653b68-3e8d-45c9-b333-bfefc8cc7363",
            "first_name": "Francis",
            "middle_name": "Njenga",
            "last_name": "Chege",
            "phone": "+254722626878",
            "email": "fchege2015i@gmail.com",
            "identification_document": "national_id",
            "identification_number": "36898911",
            "dob": "2000-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "a17fa9fa-1ae0-49af-b536-04ab72dfe983",
            "is_active": true,
            "role": "Staff",
            "institution": "Alliance High School",
            "institution_type": "High School",
            "staff_type": null,
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-04 13:00:59"
        },
        {
            "id": "787d8569-9fed-4d40-88cc-033f3f89d793",
            "first_name": "Last",
            "middle_name": "Custodian",
            "last_name": "Updated",
            "phone": "+254723542364",
            "email": "faithhello@gmail.com",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-15 10:37:35",
            "gender": "Male",
            "third_party_id": "4c1ae05b-5b66-4564-a255-a1db351d8f3d",
            "is_active": true,
            "role": "Staff",
            "institution": null,
            "institution_type": null,
            "staff_type": "DRIVER",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-11 15:59:00"
        },
        {
            "id": "d74abe30-7103-4df8-ae4f-5968d6843f79",
            "first_name": "Harry",
            "middle_name": null,
            "last_name": "K",
            "phone": "+254712311789",
            "email": "kuria.harry23@gmail.com",
            "identification_document": "national_id",
            "identification_number": "34543454",
            "dob": "1998-09-14 00:00:00",
            "gender": "Male",
            "third_party_id": "a51c73cf-273e-4769-b233-372ea92c249b",
            "is_active": true,
            "role": "Staff",
            "institution": "Ridgeways Academy",
            "institution_type": "Kindergarten",
            "staff_type": null,
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-09 10:48:12"
        },
        {
            "id": "79c4293f-e9b7-4dab-b3d7-afc1546e3878",
            "first_name": "New",
            "middle_name": "Year",
            "last_name": "Bonus",
            "phone": "+254724625442",
            "email": "newyear@gmail.com",
            "identification_document": null,
            "identification_number": null,
            "dob": "2025-12-15 10:37:35",
            "gender": "Male",
            "third_party_id": "5cc0960d-3fec-4e77-b1bc-a3f73ddce217",
            "is_active": true,
            "role": "Staff",
            "institution": null,
            "institution_type": null,
            "staff_type": "TEACHER",
            "metadata": null,
            "image": null,
            "notes": null,
            "created_at": "2025-12-12 06:30:54"
        }
    ],
    "links": {
        "first": "https://terragostg.terrasofthq.com/api/users/staff?page=1",
        "last": "https://terragostg.terrasofthq.com/api/users/staff?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "page": null,
                "active": false
            },
            {
                "url": "https://terragostg.terrasofthq.com/api/users/staff?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "https://terragostg.terrasofthq.com/api/users/staff",
        "per_page": 15,
        "to": 7,
        "total": 7
    },
    "status": 200,
    "message": "Staff Accounts Retrieved Successfully"
}
GET Get User Notification Settings {{url}}/settings/d23b811d-368c-44fd-a031-6663bed28fc0

Retrieve a user's notification preferences (whether they receive push, email, SMS, and WhatsApp notifications).

Path Parameters

  • id (string UUID, required): The user's UUID.

Response

Returns a single settings object with receivenotifications, receiveemailnotifications, receivesmsnotifications, receivewhatsapp_notifications (all booleans).

Notes

  • Each user has at most one settings record.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
        "receive_notifications": true,
        "receive_email_notifications": true,
        "receive_sms_notifications": true,
        "receive_whatsapp_notifications": true
    },
    "message": "User setting updated successfully"
}
POST Set User Notification Settings {{url}}/settings/add/d23b811d-368c-44fd-a031-6663bed28fc0

Create (or overwrite) a user's notification preferences, controlling which channels the platform is allowed to notify them on (e.g. trip alerts, roll call updates).

Path Parameters

  • id (string UUID, required): The user's UUID.

Request Body (all optional, default true)

  • receive_notifications (boolean): Master switch for in-app/push notifications.
  • receiveemailnotifications (boolean)
  • receivesmsnotifications (boolean)
  • receivewhatsappnotifications (boolean)

Notes

  • These preferences are read by the Communication endpoints (e.g. POST /communication/add) to decide which channel to use when notifying a parent.
  • Requires a bearer token (auth:api).

Response

The saved settings (data): receivenotifications, receiveemailnotifications, receivesmsnotifications, receivewhatsapp_notifications.

Auth
Bearer token
Used On
Request Body
{
    "receive_notifications":true,  // Master switch for in-app / push notifications
    "receive_email_notifications":true,  // Allow email notifications
    "receive_sms_notifications":true,  // Allow SMS notifications
    "receive_whatsapp_notifications":true  // Allow WhatsApp notifications
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
        "receive_notifications": true,
        "receive_email_notifications": true,
        "receive_sms_notifications": true,
        "receive_whatsapp_notifications": true
    },
    "message": "User setting created successfully"
}
POST Assign Zones/Locations to Staff {{url}}/users/staff/818e3ea7-543b-4739-9567-7a5a3e29e6c7/zones

Assign one or more zones/locations (vehicles/pickup areas) to a Staff member. This is a full replacement — any zones/locations previously assigned to the staff member that are not in this request are removed.

Path Parameters

  • staffUuid (string UUID, required): UUID of the staff member.

Request Body

  • zones/locations (array, required, min 1 item): List of zones/locations to assign.
  • zones/locations[].id (string, required): the registry zone/location UUID.
  • zones/locations[].name (string, required): Zone/Location display name.

Response

Returns staffid and the resulting assignedzones array.

Notes

  • The target user must exist and have the Staff role, otherwise a 404 is returned.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Request Body
{
  "zones": [  // List of zones/locations to assign
    { "id": "94e511b2-9a5f-45d2-ac5b-a53d356df6fb", "name": "Y Zone" },
    { "id": "b6b4c801-55ec-4b09-a894-e92794ceec2f", "name": "Test Zone" }
  ]
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "staff_id": "818e3ea7-543b-4739-9567-7a5a3e29e6c7",
        "assigned_zones": [
            {
                "id": "94e511b2-9a5f-45d2-ac5b-a53d356df6fb",
                "name": "Y Zone"
            },
            {
                "id": "b6b4c801-55ec-4b09-a894-e92794ceec2f",
                "name": "Test Zone"
            }
        ]
    },
    "message": "2 zone(s) assigned to staff successfully"
}
GET List Parents {{url}}/users/parents

Retrieve a paginated list of Parent users, including how many students (children) each parent has.

Query Parameters

  • per_page (integer, optional, default 10, max 20)
  • page (integer, optional)
  • is_active (boolean, optional)
  • supervisor_id (string UUID, optional): Filter to parents belonging to a specific school/Administrative Staff.
  • sourcechannel (string, optional): How the parent signed up — whatsapp, schoolcreation, or admin_upload.
  • search (string, optional): Matches name, email, or phone; supports multi-word search.

Response

Paginated list of parents, each including a dependants_count field.

Notes

  • Only returns users whose role is Parent.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Sample Response (200 OK)
{
    "data": [
        {
            "id": "95db0ec4-83ab-4a7a-aff4-383e738e8d34",
            "first_name": "LaParent",
            "middle_name": null,
            "last_name": "Ente",
            "phone": "+25470000001",
            "email": "laparent@gmail.com",
            "identification_document": "national_id",
            "identification_number": "40123123",
            "dob": "1995-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "cccf3a09-62e2-4026-947d-97aedfa6d6a7",
            "is_active": 1,
            "role": "Parent",
            "institution": "Alliance High School",
            "institution_type": "High School",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": "Nairobi, Kenya",
            "created_at": "2025-12-03 04:14:03",
            "dependants_count": 3
        },
        {
            "id": "c31727b0-0130-46f0-92f2-d2b0bec124ab",
            "first_name": "LaParent",
            "middle_name": null,
            "last_name": "Ente",
            "phone": "+2547063473076",
            "email": "laparent12@gmail.com",
            "identification_document": "passport",
            "identification_number": "401231239",
            "dob": "1995-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "f8af6128-9545-41d9-94bc-94bfacc78e66",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-03 05:00:19",
            "dependants_count": 2
        },
        {
            "id": "472df951-54eb-4b3b-b224-105d8b9428b4",
            "first_name": "Likg",
            "middle_name": "K",
            "last_name": "Last",
            "phone": "+254794237685",
            "email": "ling12@gmail.com",
            "identification_document": "passport",
            "identification_number": "123456712",
            "dob": "1996-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "83be7d0b-389c-4129-a0f3-3dbf45ba58b6",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-03 05:09:26",
            "dependants_count": 0
        },
        {
            "id": "9dcc2d36-5297-4c26-98db-660af8e00909",
            "first_name": "Le",
            "middle_name": null,
            "last_name": "Parent",
            "phone": "+254700000111",
            "email": "ling@gmqil.com",
            "identification_document": "national_id",
            "identification_number": "12312345",
            "dob": "1998-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "f92de02b-f29d-4a46-a442-313fbec8faa7",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-03 05:16:38",
            "dependants_count": 3
        },
        {
            "id": "418ebdb0-79db-4b57-99ab-7a54cfb3a365",
            "first_name": "Likg",
            "middle_name": "K",
            "last_name": "Last",
            "phone": "+254700000000",
            "email": "ling@gmail.com",
            "identification_document": "passport",
            "identification_number": "12345678",
            "dob": "1996-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "6b5e8655-d17c-474a-abd3-08008b3eec67",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-05 02:08:18",
            "dependants_count": 0
        },
        {
            "id": "cf7a3821-e6be-490f-85b9-6f7ca3585aad",
            "first_name": "Kevin",
            "middle_name": "Mwangi",
            "last_name": "Kariuki",
            "phone": "+254733556677",
            "email": "kevin.kariuki@example.com",
            "identification_document": "national_id",
            "identification_number": "49283746",
            "dob": "1998-03-22 00:00:00",
            "gender": "Male",
            "third_party_id": "24521db0-7a8d-45fa-9306-d9efc8a8e8aa",
            "is_active": 1,
            "role": "Parent",
            "institution": "Greenwood International School",
            "institution_type": "International",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": "Nakuru, Kenya",
            "created_at": "2025-12-05 15:47:21",
            "dependants_count": 1
        },
        {
            "id": "912823ed-97e9-4b0c-b4d4-34423726426c",
            "first_name": "Likg",
            "middle_name": "K",
            "last_name": "Last",
            "phone": "+254700000099",
            "email": "ling19@gmail.com",
            "identification_document": "passport",
            "identification_number": "12345679",
            "dob": "1996-12-03 00:00:00",
            "gender": "Male",
            "third_party_id": "5416b2a1-3b7e-4999-8a27-76e8e6c2a242",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-09 18:45:47",
            "dependants_count": 0
        },
        {
            "id": "2f41e784-9fe4-4bb3-9cae-c2592d8d0d6c",
            "first_name": "Linng",
            "middle_name": null,
            "last_name": "Ladt",
            "phone": "+2547063473071",
            "email": "blackling20+0011@gmail.com",
            "identification_document": "passport",
            "identification_number": "565677461",
            "dob": "1996-12-09 00:00:00",
            "gender": "Male",
            "third_party_id": "e1c51209-0107-4eeb-9ef0-44a2357583a9",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-09 19:11:03",
            "dependants_count": 1
        },
        {
            "id": "81ed76e7-bd5c-4cba-90d9-cffa34aa8dae",
            "first_name": "Kip",
            "middle_name": null,
            "last_name": "Ling",
            "phone": "+2547942376841",
            "email": "blackling20+00041@gmail.com",
            "identification_document": "passport",
            "identification_number": "251737281",
            "dob": "1995-12-11 00:00:00",
            "gender": "Male",
            "third_party_id": "d12ec6cd-faa0-4a58-893c-1f9b4132f372",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": {
                "assigned_zone": null
            },
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-11 15:15:18",
            "dependants_count": 8
        },
        {
            "id": "a92b3004-4628-4ae4-9621-35ebe372ab47",
            "first_name": "PM",
            "middle_name": null,
            "last_name": "Testing",
            "phone": "+254793453453",
            "email": "tessdufysdt@gmail.com",
            "identification_document": "national_id",
            "identification_number": "5435348",
            "dob": "1996-12-11 00:00:00",
            "gender": "Female",
            "third_party_id": "5c661a32-b115-453d-a7ac-801a05ecb958",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-11 17:06:29",
            "dependants_count": 3
        },
        {
            "id": "35438f0b-b488-4ea0-b69d-73e214910ab9",
            "first_name": "Erick",
            "middle_name": null,
            "last_name": "Mwinyi",
            "phone": "+254784976344",
            "email": "mwinyierick@gmail.com",
            "identification_document": "national_id",
            "identification_number": "25252525",
            "dob": "2000-12-11 00:00:00",
            "gender": "Male",
            "third_party_id": "b869289d-16f0-4045-bad5-a241286e5d0d",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": [],
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-11 17:27:18",
            "dependants_count": 1
        },
        {
            "id": "aafdc950-0a95-467a-8cc3-0ee8150c9c45",
            "first_name": "Meso",
            "middle_name": null,
            "last_name": "Wanjiru",
            "phone": "+254264263674",
            "email": "meso@gmail.com",
            "identification_document": "NATIONAL_ID",
            "identification_number": "24376462",
            "dob": "2002-01-07 00:00:00",
            "gender": "Female",
            "third_party_id": "584162fb-695c-4d2b-b8e4-147104fd383e",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": {
                "assigned_zone": null
            },
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-25 21:42:04",
            "dependants_count": 0
        },
        {
            "id": "23a1ee6e-0e74-4690-acdc-9c93a8207186",
            "first_name": "Wafula",
            "middle_name": null,
            "last_name": "Jacob",
            "phone": "+254713420225",
            "email": "wafula.jacob@ymail.com",
            "identification_document": "national_id",
            "identification_number": "28436278",
            "dob": "1989-12-06 00:00:00",
            "gender": "Male",
            "third_party_id": "818015aa-265a-4e67-b183-8bb7018ffa8c",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": {
                "assigned_zone": null
            },
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-28 14:43:36",
            "dependants_count": 0
        },
        {
            "id": "4c46ea3b-ec18-4339-9ab9-a8ce44c4dad7",
            "first_name": "Mat",
            "middle_name": "Nyaga",
            "last_name": "Kabinga",
            "phone": "+254720210128",
            "email": "matnyaga@gmail.com",
            "identification_document": "national_id",
            "identification_number": "27274494",
            "dob": "1989-06-16 00:00:00",
            "gender": "Male",
            "third_party_id": "b6de7f48-fc42-4745-a00b-b5935ec17ba0",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": {
                "assigned_zone": null
            },
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-28 18:24:55",
            "dependants_count": 0
        },
        {
            "id": "916c8cb7-5aae-4e97-bce6-b3172063a547",
            "first_name": "Leparentw",
            "middle_name": null,
            "last_name": "Kipli",
            "phone": "+254706347307",
            "email": "blackling206@gmail.com",
            "identification_document": "national_id",
            "identification_number": "62283585",
            "dob": "1997-12-29 00:00:00",
            "gender": "Male",
            "third_party_id": "d6cbf2c0-1ddb-4168-89da-70068d573d55",
            "is_active": 1,
            "role": "Parent",
            "staff_type": null,
            "supervisor_id": null,
            "addresses": [],
            "metadata": {
                "assigned_zone": null
            },
            "image": null,
            "notes": null,
            "location": null,
            "created_at": "2025-12-29 20:37:01",
            "dependants_count": 14
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8000/api/users/parents?page=1",
        "last": "http://127.0.0.1:8000/api/users/parents?page=37",
        "prev": null,
        "next": "http://127.0.0.1:8000/api/users/parents?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 37,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "page": null,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=2",
                "label": "2",
                "page": 2,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=3",
                "label": "3",
                "page": 3,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=4",
                "label": "4",
                "page": 4,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=5",
                "label": "5",
                "page": 5,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=6",
                "label": "6",
                "page": 6,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=7",
                "label": "7",
                "page": 7,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=8",
                "label": "8",
                "page": 8,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=9",
                "label": "9",
                "page": 9,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=10",
                "label": "10",
                "page": 10,
                "active": false
            },
            {
                "url": null,
                "label": "...",
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=36",
                "label": "36",
                "page": 36,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=37",
                "label": "37",
                "page": 37,
                "active": false
            },
            {
                "url": "http://127.0.0.1:8000/api/users/parents?page=2",
                "label": "Next »",
                "page": 2,
                "active": false
            }
        ],
        "path": "http://127.0.0.1:8000/api/users/parents",
        "per_page": 15,
        "to": 15,
        "total": 544
    },
    "status": 200,
    "message": "Parents Accounts Retrieved Successfully"
}
GET Get Parent by ID {{url}}/users/parents/95db0ec4-83ab-4a7a-aff4-383e738e8d34

Retrieve a single Parent user along with their students (children).

Path Parameters

  • id (string UUID, required): The parent's user UUID.

Response

Returns the parent's profile plus a students array (id, name fields, image, metadata, active status, third-party/the registry ID).

Notes

  • Returns 404 if the user doesn't exist or isn't a Parent.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "95db0ec4-83ab-4a7a-aff4-383e738e8d34",
        "first_name": "LaParent",
        "middle_name": null,
        "last_name": "Ente",
        "phone": "+25470000001",
        "email": "laparent@gmail.com",
        "identification_document": "national_id",
        "identification_number": "40123123",
        "dob": "1995-11-06 00:00:00",
        "gender": "Male",
        "third_party_id": "cccf3a09-62e2-4026-947d-97aedfa6d6a7",
        "is_active": 1,
        "role": "Parent",
        "institution": "Alliance High School",
        "institution_type": "High School",
        "staff_type": null,
        "supervisor_id": null,
        "addresses": [],
        "metadata": [],
        "image": null,
        "notes": null,
        "location": "Nairobi, Kenya",
        "created_at": "2025-12-03 04:14:03",
        "dependants": [
            {
                "id": "c75f2355-2f88-40b2-916b-999744d1d1f5",
                "first_name": "Lincoln",
                "last_name": "Chege",
                "is_active": 1,
                "metadata": {
                    "grade": "9th Grade"
                }
            },
            {
                "id": "2b37465e-2cc1-4b2f-b702-611505702c7f",
                "first_name": "Leo",
                "last_name": "Junior",
                "is_active": 0,
                "metadata": {
                    "grade": "PP1"
                }
            },
            {
                "id": "9474fd38-dce1-4abc-b4a9-946dc5d841bc",
                "first_name": "Michael",
                "last_name": "Kid",
                "is_active": 1,
                "metadata": {
                    "grade": "PP1"
                }
            }
        ]
    },
    "message": "Parent Retrieved Successfully"
}
GET Trigger Parent-Supervisor Sync (Internal) {{url}}/internal/sync-parent-supervisors?dry_run=false

Internal/ops endpoint — not part of the normal app flow. Dispatches a background job that re-links every parent to the correct school (Administrative Staff "supervisor"), pulling the source of truth from the registry, school by school. Used to fix drift or duplicate parent records after data issues.

Query Parameters

  • dry_run (boolean, optional, default true): When true, the job only logs what it would change without writing anything. Set to false to actually persist the changes.

Required Header

  • X-Sync-Secret (string, required): Must match the server's configured app.sync_secret. Requests without a valid header get a 403 Unauthorized.

Response

{"status": 200, "message": "Sync job dispatched — check logs for progress"} — the job runs asynchronously; check application logs for the actual outcome.

Notes

  • Not authenticated with a normal bearer token — protected only by the shared secret header, so treat that secret like a credential.
  • A distributed lock prevents two syncs from running concurrently; if one is already in progress, a new request is silently skipped (see logs).
  • This is not the same as normal auth:api user authentication — do not expose this route to the public frontend.
Auth
None
Sample Response (200 OK)
{
    "status": 200,
    "message": "Sync job dispatched — check logs for progress"
}