TerraGo API

Admin

System-admin-only endpoints — aggregate stats, user billing, and subscription management used by the admin dashboard in TerraGoNewUI (src/views/admin/). Every endpoint here requires a System Admin bearer token and reads/writes across all schools rather than being scoped to a single Administrative Staff account.

51 endpoint(s)

Schools

GET Get Schools Stats Schools {{url}}/users/schools/stats

Aggregate counts of Administrative Staff (school) accounts by status — used to power the admin dashboard's school stat cards.

Response

  • total — total school accounts.
  • active — accounts with is_active = 1.
  • pilot — accounts with is_active = -1 (pilot/trial status).
  • inactive — accounts with is_active = 0.

Notes

  • System-admin endpoint — aggregates across all schools.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "total": 42,
        "active": 35,
        "pilot": 4,
        "inactive": 3
    },
    "message": "Schools stats retrieved successfully"
}

Billing

GET Get User Billing Billing {{url}}/users/admin/users/95db0ec4-83ab-4a7a-aff4-383e738e8d34/billing

Full billing picture for a single user (invoices, subscriptions, and any subscription voucher codes redeemed) — powers the "Billing & Transactions" tab on a parent's admin profile page.

Response

  • invoices — each with total_amount and its line items.
  • subscriptions — the user's subscriptions, with dependant info.
  • voucher_codes — subscription voucher codes redeemed by this user.

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "invoices": [
            {
                "id": "9c3e2f1a-1234-4a11-8888-abcde1234567",
                "status": "Paid",
                "total_amount": 1500,
                "items": [
                    {
                        "id": "a1b2c3d4-0000-4a11-8888-abcde1234567",
                        "type": "Subscription",
                        "amount": 1500
                    }
                ],
                "created_at": "Monday 06 Jul 2026 09:12 AM"
            }
        ],
        "subscriptions": [
            {
                "id": "b2c3d4e5-0000-4a11-8888-abcde1234567",
                "status": "Active",
                "start_date": "2026-01-01",
                "end_date": null,
                "is_forever": true,
                "dependant": {
                    "id": "c3d4e5f6-0000-4a11-8888-abcde1234567",
                    "name": "Amani Otieno"
                }
            }
        ],
        "voucher_codes": []
    },
    "message": "User Billing Retrieved Successfully"
}

Subscriptions

GET List Subscriptions Subscriptions {{url}}/admin/subscriptions

Paginated, filterable list of every parent-dependant subscription — the admin dashboard's Subscriptions tab.

Query Parameters

  • status (string, optional): Active, Expired, Disabled, or Cancelled.
  • search (string, optional): matches parent or dependant name/email.
  • sortby (string, optional): one of amount, startdate, enddate, status, createdat, parent, child, school (default created_at).
  • sort_dir (string, optional): asc or desc (default desc).
  • per_page (integer, optional, max 100).
  • page (integer, optional).

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "data": [
            {
                "id": "b2c3d4e5-0000-4a11-8888-abcde1234567",
                "status": "Active",
                "start_date": "2026-01-01",
                "end_date": null,
                "is_forever": true,
                "has_lifetime_voucher": false,
                "amount": 1500,
                "created_at": "2026-01-01 08:00:00",
                "parent": {
                    "id": "35438f0b-b488-4ea0-b69d-73e214910ab9",
                    "first_name": "LaParent",
                    "last_name": "Ente",
                    "email": "laparent@gmail.com",
                    "phone": "+25470000001"
                },
                "dependant": {
                    "id": "c3d4e5f6-0000-4a11-8888-abcde1234567",
                    "name": "Amani Otieno"
                },
                "school": {
                    "id": "448e2ae4-48b4-4842-84b1-a73c84d21de1",
                    "name": "Alliance High School"
                }
            }
        ],
        "total": 1,
        "per_page": 15,
        "current_page": 1,
        "last_page": 1
    },
    "message": "Subscriptions retrieved successfully"
}
POST Create Subscription Subscriptions {{url}}/admin/subscriptions

Manually create a subscription for a parent/dependant pair — used by admins to grant subscriptions outside the normal payment flow.

Request Body

  • parent_id (string UUID, required): must exist in users.
  • dependant_id (string UUID, required): must exist in dependants.
  • status (string, required): Active, Expired, Disabled, or Cancelled.
  • amount (number, required, min 0).
  • start_date (date, required).
  • end_date (date, optional, nullable).
  • isforever (boolean, optional): when true, enddate is stored as null regardless of what was passed.

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "parent_id": "35438f0b-b488-4ea0-b69d-73e214910ab9",
    "dependant_id": "c3d4e5f6-0000-4a11-8888-abcde1234567",
    "status": "Active",
    "amount": 1500,
    "start_date": "2026-01-01",
    "end_date": null,
    "is_forever": true
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "b2c3d4e5-0000-4a11-8888-abcde1234567",
        "status": "Active",
        "start_date": "2026-01-01",
        "end_date": null,
        "is_forever": true,
        "amount": 1500,
        "created_at": "2026-07-13 10:00:00",
        "parent": {
            "id": "35438f0b-b488-4ea0-b69d-73e214910ab9",
            "first_name": "LaParent",
            "last_name": "Ente",
            "email": "laparent@gmail.com",
            "phone": "+25470000001"
        },
        "dependant": {
            "id": "c3d4e5f6-0000-4a11-8888-abcde1234567",
            "name": "Amani Otieno"
        }
    },
    "message": "Subscription created successfully"
}
PATCH Update Subscription Subscriptions {{url}}/admin/subscriptions/b2c3d4e5-0000-4a11-8888-abcde1234567

Partially update a single subscription.

Request Body (all optional)

  • status (string): Active, Expired, Disabled, or Cancelled.
  • amount (number, min 0).
  • start_date (date).
  • end_date (date, nullable).
  • isforever (boolean): when true, enddate is set to null regardless of what was passed for end_date.

Response

Also returns haslifetimevoucher — whether the parent holds a lifetime (forever-duration) subscription voucher code.

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "status": "Active",
    "amount": 1800
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "b2c3d4e5-0000-4a11-8888-abcde1234567",
        "status": "Active",
        "start_date": "2026-01-01",
        "end_date": null,
        "is_forever": true,
        "has_lifetime_voucher": false,
        "amount": 1800
    },
    "message": "Subscription updated successfully"
}
DELETE Delete Subscription Subscriptions {{url}}/admin/subscriptions/b2c3d4e5-0000-4a11-8888-abcde1234567

Soft-delete a single subscription.

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": [],
    "message": "Subscription deleted successfully"
}
PATCH Bulk Update Subscriptions Subscriptions {{url}}/admin/subscriptions/bulk

Apply the same field changes to many subscriptions at once — used by the admin Subscriptions table's multi-select actions.

Request Body

  • ids (string[] UUIDs, required, min 1): subscription IDs to update.
  • status (string, optional): Active, Expired, Disabled, or Cancelled.
  • amount (number, optional, min 0).
  • start_date (date, optional).
  • end_date (date, optional, nullable).
  • is_forever (boolean, optional).

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "ids": [
        "b2c3d4e5-0000-4a11-8888-abcde1234567",
        "d4e5f6a7-0000-4a11-8888-abcde1234567"
    ],
    "status": "Active"
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "updated": 2
    },
    "message": "Subscriptions updated successfully"
}
POST Bulk Delete Subscriptions Subscriptions {{url}}/admin/subscriptions/bulk-delete

Soft-delete many subscriptions at once.

Request Body

  • ids (string[] UUIDs, required, min 1): subscription IDs to delete.

Notes

  • System-admin endpoint.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "ids": [
        "b2c3d4e5-0000-4a11-8888-abcde1234567"
    ]
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "deleted": 1
    },
    "message": "Subscriptions deleted successfully"
}

Auth

PUT Logout Auth {{url}}/auth/logout

Log out the currently authenticated user. Invalidates the current access token (JWT) and deletes all of the user's refresh tokens, so neither the access token nor any refresh token can be used again.

Notes

  • Requires a valid bearer token (auth:api).
  • After logout, the client should discard both the access and refresh tokens; continuing to use them returns 401 Unauthorized.
  • Idempotent from the client's perspective — calling it again after logout simply fails auth.
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": [],
    "message": "Successfully logged out"
}

Roles

GET List Roles Roles {{url}}/roles

This endpoint returns an array of role objects, each representing a user role within the system. It is typically used to display available roles for user management or assignment purposes.

Auth
None
Sample Response (200 OK)
{
    "data": [
        {
            "id": "184ad925-a873-445e-a140-1edc1b11c2db",
            "name": "System Admin",
            "created_at": "2025-11-27 13:35:56"
        },
        {
            "id": "582c5dc9-4ef6-4238-98e3-7318c57349fb",
            "name": "Parent",
            "created_at": "2025-11-27 13:35:56"
        },
        {
            "id": "989d4025-e939-41f7-b032-356c7269612c",
            "name": "Staff",
            "created_at": "2025-11-27 13:35:56"
        },
        {
            "id": "4583792c-7951-4bf5-ba5f-68c374a12420",
            "name": "Administrative Staff",
            "created_at": "2025-11-27 13:35:56"
        }
    ],
    "links": {
        "first": "https://terragostg.terrasofthq.com/api/roles?page=1",
        "last": "https://terragostg.terrasofthq.com/api/roles?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/roles?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "https://terragostg.terrasofthq.com/api/roles",
        "per_page": 15,
        "to": 4,
        "total": 4
    },
    "status": 200,
    "message": "Roles Retrieved Successfully"
}

Users

POST Signup Users {{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"
}
GET List Users {{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"
}
GET List Parents Users {{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 Users {{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"
}
PUT Update Users {{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"
}

Students

GET List Students {{url}}/dependants

Retrieves a paginated list of students filtered by optional criteria such as tags, parent ID, or phone number. This endpoint is useful for applications that need to display or manage students associated with a parent entity (such as a user or account).

Parameters

  • tags (array[string], optional): List of tag UUIDs to filter students.
  • parent_id (string, optional): UUID of the parent entity to filter students.
  • phone_number (string, optional): Phone number to filter students.
  • per_page (integer, optional): Number of results per page. Default is 10.
  • page (integer, optional): Page number to retrieve. Default is 1.

Notes

  • All filter parameters are optional; omitting them returns all students.
  • Ensure the token environment variable is set with a valid bearer token.
  • The endpoint may return an empty array if no students match the filters.
Auth
Bearer token
Used On
Request Body
{
    "tags": ["d4b18b8f-eaa6-44e1-8655-d75f146c0933"], // filter by tag
    // "parent_id": "cf7a3821-e6be-490f-85b9-6f7ca3585aad", // filter by parent id
    // "phone_number": "+254733556677",  // filter by phone number
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "184c32e2-878d-4e89-99c3-91dda70c03e9",
            "first_name": "Simon",
            "middle_name": "Kimani",
            "last_name": "Chege",
            "phone": null,
            "email": null,
            "identification_document": null,
            "identification_number": null,
            "dob": "2010-11-06 00:00:00",
            "gender": "Male",
            "third_party_id": "a2fce066-519c-4cba-968d-18aa70446411",
            "is_active": 1,
            "metadata": {
                "grade": null
            },
            "parent": {
                "uuid": "cf7a3821-e6be-490f-85b9-6f7ca3585aad",
                "name": "Kevin Kariuki",
                "email": "kevin.kariuki@example.com",
                "phone": "+254733556677"
            },
            "guardians": [
                {
                    "uuid": "d651190e-5e68-43e0-82db-9c53426311ab",
                    "name": "Peter Chege"
                }
            ],
            "image": null,
            "notes": null,
            "created_at": "2025-12-05 15:51:29",
            "addresses": [
                {
                    "uuid": "93d41cd9-1b01-4bb3-95ce-56175ce7f493",
                    "is_primary": 1,
                    "latitude": "-1.2921",
                    "longitude": "36.8219"
                }
            ],
            "tags": [
                {
                    "id": "d4b18b8f-eaa6-44e1-8655-d75f146c0933",
                    "name": "PM School Tag",
                    "description": "PM School Tag",
                    "entity": "universal",
                    "color_code": "#EA0D8D"
                }
            ]
        },
        {
            "id": "0b1475e9-f811-4683-8a90-a94468dc7ef1",
            "first_name": "Junior",
            "middle_name": null,
            "last_name": "Pm",
            "phone": "",
            "email": null,
            "identification_document": null,
            "identification_number": null,
            "dob": "2005-01-05 00:00:00",
            "gender": "Female",
            "third_party_id": "2b8effd8-0782-4e66-b93f-d0ba8c4464c9",
            "is_active": 1,
            "metadata": {
                "grade": "8th Grade"
            },
            "parent": {
                "uuid": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "name": "Pm Parent",
                "email": "Parent@gmail.com",
                "phone": "+254791472893"
            },
            "guardians": [
                {
                    "uuid": "41e5db5b-2ab2-4d8a-a8e2-6fe3fdaca078",
                    "name": "Nanny Guardian"
                },
                {
                    "uuid": "4d95c454-67aa-47ce-80c3-973f0d3750cb",
                    "name": "Maggy Grants"
                }
            ],
            "image": null,
            "notes": null,
            "created_at": "2026-01-05 14:26:56",
            "addresses": [],
            "tags": [
                {
                    "id": "d4b18b8f-eaa6-44e1-8655-d75f146c0933",
                    "name": "PM School Tag",
                    "description": "PM School Tag",
                    "entity": "universal",
                    "color_code": "#EA0D8D"
                },
                {
                    "id": "0655ca5b-1c6b-437d-b38a-7f4596fb038f",
                    "name": "Kiota School Rongai Route",
                    "description": "Kiota School Rongai Route for students",
                    "entity": "dependant",
                    "color_code": null
                }
            ]
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8001/api/dependants?page=1",
        "last": "http://127.0.0.1:8001/api/dependants?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": "http://127.0.0.1:8001/api/dependants?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://127.0.0.1:8001/api/dependants",
        "per_page": 10,
        "to": 2,
        "total": 2
    },
    "status": 200,
    "message": "Dependants Retrieved Successfully"
}
POST Add Students {{url}}/dependants/add

This endpoint creates a new student record associated with a parent user.

Sample Fields

  • first_name (string): Student's first name.
  • middle_name (string): Student's middle name.
  • last_name (string): Student's last name.
  • dob (string): Date of birth (format: DD-MM-YYYY).
  • gender (string): Gender of the student. Allowed values: MALE, FEMALE, OTHER, N/A.
  • parent_id (string): Unique identifier of the parent user.

Response

The created student (data) — id (uuid), names, grade, parent, guardians, addresses.

Auth
Bearer token
Used On
Request Body
{
    "first_name" : "Simon",
    "middle_name": "Kimani",
    "last_name" : "Chege",
    "dob":"06-11-2010",
    "gender": "MALE", //only use: MALE, FEMALE, OTHER, N/A
    "parent_id" : "cf7a3821-e6be-490f-85b9-6f7ca3585aad",
    "metadata" : {
        "grade" : "Grade 6" //only use: PP1, PP2, PLAYGROUP, GRADE_1 , GRADE_2, GRADE_3, GRADE_4, GRADE_5, GRADE_6, GRADE_7, GRADE_8, GRADE_9, GRADE_10, GRADE_11, GRADE_12, COLLEGE, N/A,
    },
    "tags" : ["cf7a3821-e6be-490f-85b9-6f7ca3585aad", "cf7a3821-e6be-490f-85b9-6f7ca3585aad"],
    "search_term": "Malaika School Thika Road" //optional for the search term used by the parent to find the dependants institution
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "184c32e2-878d-4e89-99c3-91dda70c03e9",
        "first_name": "Simon",
        "middle_name": "Kimani",
        "last_name": "Chege",
        "phone": null,
        "email": null,
        "identification_document": null,
        "identification_number": null,
        "dob": "2010-11-06 00:00:00",
        "gender": "Male",
        "third_party_id": "a2fce066-519c-4cba-968d-18aa70446411",
        "is_active": true,
        "metadata": {
            "grade": null
        },
        "image": null,
        "notes": null,
        "created_at": "2025-12-05 12:51:29"
    },
    "message": "Dependant Created Successfully"
}
PUT Update Students {{url}}/dependants/update/30a250fe-0cbe-4afb-bb48-606e5d8f887f

This endpoint updates the details of an existing student identified by their unique ID in the URL path.

Sample Body Fields:

  • first_name (string, required): Student's first name. Example: "Lincoln"
  • middle_name (string, optional): Student's middle name. Example: "Hungi"
  • last_name (string, required): Student's last name. Example: "Chege"
  • dob (string, required): Date of birth in DD-MM-YYYY format. Example: "06-11-2010"
  • gender (string, required): Gender of the student. Allowed values: MALE, FEMALE, OTHER, N/A
  • parent_id (string, required): UUID of the parent.
  • metadata (object, optional): Additional information. Example: { "grade": "Grade 6" }

Response

The updated student (data).

Auth
Bearer token
Request Body
{
    "first_name" : "Lincoln",
    "middle_name": "Hungi",
    "last_name" : "Chege",
    "dob":"06-11-2010",
    "gender": "MALE", //only use: MALE, FEMALE, OTHER, N/A
    "parent_id" : "b3b62c15-1409-4713-81b2-d4f6744039e6",
    "metadata" : {
        "grade" : "Grade 6" //only use: PP1, PP2, PLAYGROUP, GRADE_1 , GRADE_2, GRADE_3, GRADE_4, GRADE_5, GRADE_6, GRADE_7, GRADE_8, GRADE_9, GRADE_10, GRADE_11, GRADE_12, COLLEGE, N/A,
    },
    "tags" : ["cf7a3821-e6be-490f-85b9-6f7ca3585aad", "cf7a3821-e6be-490f-85b9-6f7ca3585aad"],
    "search_term": "Malaika School Thika Road" //optional for the search term used by the parent to find the dependants institution
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "30a250fe-0cbe-4afb-bb48-606e5d8f887f",
        "first_name": "Lincoln",
        "middle_name": "Hungi",
        "last_name": "Chege",
        "phone": null,
        "email": null,
        "identification_document": null,
        "identification_number": null,
        "dob": "2010-11-06 00:00:00",
        "gender": "Male",
        "third_party_id": "6e09a88f-de47-455b-a1bd-dc83a6e8efc6",
        "is_active": true,
        "metadata": {
            "grade": "Grade 6"
        },
        "image": null,
        "notes": null,
        "created_at": "2025-11-21 11:07:08"
    },
    "message": "Dependant Updated Successfully"
}
GET Show Students {{url}}/dependants/184c32e2-878d-4e89-99c3-91dda70c03e9

Retrieve a single student (child) by UUID with their full context, enriched from the registry.

Path Parameters

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

Response includes

  • Local relationships: parent, guardians, and addresses.
  • the registry enrichment: the student's live the registry record is fetched and merged in, providing route/zone/location tags and assigned Band/Bag Tags devices (mapped onto the response).

Notes

  • Returns 404 if no student matches the UUID.
  • If the registry is unreachable the local data is still returned; the the registry-derived tags/IOTs are simply omitted.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Sample Response (200 OK)
{
    "data": {
        "id": "184c32e2-878d-4e89-99c3-91dda70c03e9",
        "first_name": "Simon",
        "middle_name": "Kimani",
        "last_name": "Chege",
        "phone": null,
        "email": null,
        "identification_document": null,
        "identification_number": null,
        "dob": "2010-11-06 00:00:00",
        "gender": "Male",
        "third_party_id": "a2fce066-519c-4cba-968d-18aa70446411",
        "is_active": 1,
        "metadata": {
            "grade": null
        },
        "parent": {
            "uuid": "cf7a3821-e6be-490f-85b9-6f7ca3585aad",
            "name": "Kevin Kariuki",
            "email": "kevin.kariuki@example.com",
            "phone": "+254733556677"
        },
        "guardians": [
            {
                "uuid": "d651190e-5e68-43e0-82db-9c53426311ab",
                "name": "Peter Chege"
            }
        ],
        "image": null,
        "notes": null,
        "created_at": "2025-12-05 15:51:29",
        "addresses": [
            {
                "uuid": "93d41cd9-1b01-4bb3-95ce-56175ce7f493",
                "is_primary": 1,
                "latitude": "-1.2921",
                "longitude": "36.8219"
            },
            {
                "uuid": "da879dcb-b062-462e-b935-5c1b879e3c0d",
                "is_primary": 1,
                "latitude": "-1.2921",
                "longitude": "36.8219"
            }
        ]
    },
    "status": 200,
    "message": "Dependant Retrieved Successfully"
}
DELETE Delete Students {{url}}/dependants/delete/c3d4e5f6-0000-4a11-8888-abcde1234567

Delete a student (dependant) record.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": [],
    "message": "Dependant Deleted Successfully"
}

Tags

GET List Tags {{url}}/utility/tags

List beneficiary/route tags available for the organisation. This is read directly from TerraGo's registry — TerraGo forwards the query to the registry, then re-paginates the result so the pagination links point back at TerraGo (not the registry).

Query Parameters

  • search (string, optional): Filter tags by text.
  • entity (string, optional): Entity scope (combined with &universal server-side).
  • per_page (integer, optional, default 10, max 20), page (integer, optional).

Response

Paginated collection of tags (TagResource).

Notes

  • Depends on the registry; if the registry is unreachable or errors, returns a warning ("Tag Fetching Failed due to WAAS failure").
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "per_page": 10,  // Page size — how many results per page
    "page": 1  // Page number (starts at 1)
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "323c3700-6a64-4b17-acc5-baf7f4f9dc11",
            "name": "School Z",
            "description": "desc",
            "entity": "zone",
            "color_code": "#FF9500"
        },
        {
            "id": "fc49ed94-1521-49cf-9314-99639ec8757c",
            "name": "Carrefour Employee",
            "description": "Account Tag for carrefour employee",
            "entity": "account",
            "color_code": "#EA0D8D"
        },
        {
            "id": "036ad366-7a0a-46b1-8eb3-8dcec63c7589",
            "name": "Carrefour Store",
            "description": "Carrefour Stores",
            "entity": "beneficiary",
            "color_code": "#FF9500"
        },
        {
            "id": "c50eb33d-822e-4409-9196-9867114bf2c2",
            "name": "Carrefour Customer",
            "description": "Tag to describe functions for carrefour Customer",
            "entity": "account",
            "color_code": "#EA0D8D"
        },
        {
            "id": "a6cc8f59-4b10-45fa-b87d-17dd04438bad",
            "name": "Carrefour Embakasi Zone",
            "description": "Carrefour Embakasi Zone Tag",
            "entity": "zone",
            "color_code": "#FF9500"
        },
        {
            "id": "8ec1a686-5c08-4e82-93c6-9bd082605860",
            "name": "BEN WA FISHARY TAG",
            "description": null,
            "entity": "account",
            "color_code": "#FF9500"
        },
        {
            "id": "b85861df-eb37-4b3d-980a-0de36c3a5085",
            "name": "Marcus",
            "description": "marcus",
            "entity": "dependant",
            "color_code": "#FF9500"
        },
        {
            "id": "d625d7bc-81a4-4815-ab0d-b288e47e7d28",
            "name": "Dependant Backstage Access",
            "description": "Dependant Backstage Access",
            "entity": "dependant",
            "color_code": "#EA0D8D"
        },
        {
            "id": "415e9fc8-4206-4dd9-8de7-484dd23a83fa",
            "name": "Backstage Access",
            "description": "Backstage Access",
            "entity": "account",
            "color_code": "#FF9500"
        },
        {
            "id": "82556e35-4593-4fba-9ba5-df73bcb27b61",
            "name": "BACKSTAGE ACCESS",
            "description": "BACKSTAGE ACCESS",
            "entity": "zone",
            "color_code": "#9351E8"
        }
    ],
    "links": {
        "first": "http://localhost:8001/api/tags?page=1",
        "last": "http://localhost:8001/api/tags?page=5",
        "prev": null,
        "next": "http://localhost:8001/api/tags?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 5,
        "links": [
            {
                "url": null,
                "label": "« Previous",
                "page": null,
                "active": false
            },
            {
                "url": "http://localhost:8001/api/tags?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": "http://localhost:8001/api/tags?page=2",
                "label": "2",
                "page": 2,
                "active": false
            },
            {
                "url": "http://localhost:8001/api/tags?page=3",
                "label": "3",
                "page": 3,
                "active": false
            },
            {
                "url": "http://localhost:8001/api/tags?page=4",
                "label": "4",
                "page": 4,
                "active": false
            },
            {
                "url": "http://localhost:8001/api/tags?page=5",
                "label": "5",
                "page": 5,
                "active": false
            },
            {
                "url": "http://localhost:8001/api/tags?page=2",
                "label": "Next »",
                "page": 2,
                "active": false
            }
        ],
        "path": "http://localhost:8001/api/tags",
        "per_page": 10,
        "to": 10,
        "total": 41
    },
    "status": 200,
    "message": "Tags Retrieved Successfully"
}

Devices

GET List Devices Devices {{url}}/devices

Retrieve a paginated list of hardware devices (trackers, scanners, gateways) registered with TerraGo.

Query Parameters

  • per_page (integer, optional, default 10, max 20)
  • status (string, optional): ONLINE, OFFLINE, LOWBATTERY, PENDINGAPPROVAL, OTHER, or N/A.
  • assigned (integer, optional): 1 for devices assigned to a school/staff, 0 for unassigned.
  • supervisor_id (string UUID, optional): Filter by Administrative Staff (school).
  • search (string, optional): Matches name, description, or serial number.

Response

Paginated list of devices (data) with meta; each includes live-derived status, battery, NFC/location flags, signal and data usage.

Auth
Bearer token
Used On
Request Body
{
    "status": "ONLINE", //only use: ONLINE, OFFLINE, LOW_BATTERY, OTHER, N/A
    "search": "",
    "supervisor_id": "68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "e91c072b-508c-448d-a368-f22c34434742",
            "name": "name",
            "description": "description",
            "sim_phone_number": "+254725544432",
            "serial_number": "serial_number",
            "waas_zone_uuid": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
            "waas_zone_name": "Terra HQ",
            "est_data_usage": "2000",
            "type": "Scanner",
            "administrative_staff": {
                "id": "68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
                "first_name": "Jane",
                "last_name": "Otieno"
            },
            "status": "Online",
            "last_activity": "2025-12-27 14:10:56",
            "battery_level": 100,
            "metadata": null
        }
    ],
    "links": {
        "first": "http://localhost:8001/api/devices?page=1",
        "last": "http://localhost:8001/api/devices?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": "http://localhost:8001/api/devices?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://localhost:8001/api/devices",
        "per_page": 15,
        "to": 1,
        "total": 1
    },
    "status": 200,
    "message": "Devices Retrieved Successfully"
}
POST Register Device (Admin) Devices {{url}}/devices/add

Register a new device directly (as an admin), immediately creating it in both TerraGo and TerraGo's zone/location and tag registry with ONLINE status. Compare to Request Registration, which is the self-service flow devices use before an admin approves them.

Request Body

Same fields as Update Device: name, description, serialnumber (required, unique), type (required), estdatausage (required), plus optional imei, simphonenumber, waaszoneuuid, waaszonename, status, batterylevel, administativestaffid.

Notes

  • Also seeds an initial device-status-log entry so uptime tracking has a baseline from creation time.

Response

The created device (data).

Auth
Bearer token
Used On
Request Body
{
   "name": "name",
    "description": "description",
    "serial_number": "serial_number",
    "administative_staff_id":"68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
    "sim_phone_number": "+254725544432",
    "waas_zone_uuid":"ada52fc6-d481-48d9-82b3-fddb07d5d44f",
    "waas_zone_name":"Terra HQ",
    "est_data_usage":"2000", //In MBs
    "type": "SCANNER" //only use: SCANNER, GATEWAY, TRACKER, OTHER, N/A
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "e91c072b-508c-448d-a368-f22c34434742",
        "name": "name",
        "description": "description",
        "sim_phone_number": "+254725544432",
        "serial_number": "serial_number",
        "waas_zone_uuid": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
        "waas_zone_name": "Terra HQ",
        "est_data_usage": "2000",
        "type": "Scanner",
        "administrative_staff": {
            "id": "68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
            "first_name": "Jane",
            "last_name": "Otieno"
        },
        "status": "Online",
        "last_activity": "2025-12-27 14:10:56",
        "battery_level": 100,
        "metadata": null
    },
    "message": "Device registered successfully"
}
POST Approve Device Registration Devices {{url}}/devices/approve/1aa126a1-f056-4b4e-bd59-9b821ff50bb9

Admin approval step that completes onboarding for a device previously created via Request Registration: fills in the remaining details, syncs it to the registry, and moves it out of PENDING_APPROVAL.

Path Parameters

  • id (string UUID, required): Device UUID (the one created by the self-registration call).

Request Body

Same fields as Update Deviceadministativestaffid is effectively required here since it determines which school the device is registered to in the registry.

Response

The approved/activated device (data).

Auth
Bearer token
Request Body
{
    "name": "name",
    "description": "description",
    "serial_number": "serial_number",
    "administative_staff_id":"46b0a803-39c8-4113-8b29-8ef30438c5bd",
    "sim_phone_number": "+254725544432",
    "waas_zone_uuid":"ada52fc6-d481-48d9-82b3-fddb07d5d44f",
    "waas_zone_name":"Terra HQ",
    "est_data_usage":"2000", //In MBs
    "type": "SCANNER" //only use: SCANNER, GATEWAY, TRACKER, OTHER, N/A
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "38de6cc4-9043-454b-b3f2-ac67b591b09e",
        "name": "name",
        "description": "description",
        "sim_phone_number": "+254725544432",
        "serial_number": "serial_number",
        "waas_zone_uuid": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
        "waas_zone_name": "Terra HQ",
        "est_data_usage": "2000",
        "type": "Scanner",
        "administrative_staff": {
            "id": "46b0a803-39c8-4113-8b29-8ef30438c5bd",
            "first_name": "PM",
            "last_name": "School"
        },
        "status": "Low Battery",
        "last_activity": "2026-02-27 10:52:15",
        "battery_level": 100,
        "metadata": null
    },
    "message": "Device registered successfully"
}
PUT Update Device Devices {{url}}/devices/update/e91c072b-508c-448d-a368-f22c34434742

Update a device's configuration. Changes are pushed to TerraGo's zone/location and tag registry in the same request (transactional — if the registry call fails, nothing is saved locally).

Path Parameters

  • id (string UUID, required): Device UUID.

Request Body

  • name (string, required)
  • description (string, required)
  • serial_number (string, required, must be unique)
  • type (string, required): TRACKER, SCANNER, GATEWAY, OTHER, or N/A.
  • estdatausage (integer, required, min 1): Estimated monthly data usage.
  • imei (string, optional, max 32)
  • simphonenumber (string, optional)
  • waaszoneuuid / waaszonename (string, optional): Reassign to a different vehicle/zone/location.
  • status (string, optional): ONLINE, OFFLINE, LOWBATTERY, PENDINGAPPROVAL, OTHER, or N/A.
  • battery_level (integer, optional, 0–100, default 100)
  • administativestaffid (string UUID, optional): School the device belongs to; resolved from the authenticated user if omitted.

Notes

  • If batterylevel is 25 or below, status is forced to LOWBATTERY regardless of what's passed in.
  • administativestaffid must be resolvable (from the request or from your own account) or this returns a 422.
Auth
Bearer token
Used On
Request Body
{
   "name": "name",
    "description": "description",
    "serial_number": "serial_number",
    "administative_staff_id":"68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
    "sim_phone_number": "+254725544432",
    "waas_zone_uuid":"ada52fc6-d481-48d9-82b3-fddb07d5d44f",
    "waas_zone_name":"Terra HQ",
    "est_data_usage":"2000", //In MBs
    "type": "SCANNER", //only use: SCANNER, GATEWAY, TRACKER, OTHER, N/A
    "battery_level":"100",
    "status": "ONLINE" //only use: ONLINE, OFFLINE, LOW_BATTERY, OTHER, N/A
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "e91c072b-508c-448d-a368-f22c34434742",
        "name": "name",
        "description": "description",
        "sim_phone_number": "+254725544432",
        "serial_number": "serial_number",
        "waas_zone_uuid": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
        "waas_zone_name": "Terra HQ",
        "est_data_usage": "2000",
        "type": "Scanner",
        "administrative_staff": {
            "id": "68b86410-e6e8-4b5f-9a3d-8265a7773c0e",
            "first_name": "Jane",
            "last_name": "Otieno"
        },
        "status": "Online",
        "last_activity": "2025-12-27 14:56:47",
        "battery_level": "100",
        "metadata": null
    },
    "message": "Device updated successfully"
}

IoT Stock

GET List Stock IoT Stock {{url}}/iot-stock

Paginated, filterable list of wearable (band/tag) inventory — the admin dashboard's Device Stock → Wearables tab.

Query Parameters

  • supervisor_id (string UUID, optional): filter to stock allocated to one school.
  • status (string, optional): e.g. available, in_use.
  • assigned (boolean, optional): 1 for stock assigned to a dependant, 0 for unassigned.
  • batch_number / color (string, optional).
  • date_range (string, optional): "YYYY-MM-DD,YYYY-MM-DD".
  • search (string, optional): matches serial number or earth code.
  • per_page (integer, optional, max 20).

Response

Paginated stock items, plus a top-level batches array of every distinct batch_number currently in stock (for the batch filter dropdown).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "batches": [
        "BATCH-2026-01",
        "BATCH-2026-02"
    ],
    "message": "Stock fetched successfully",
    "data": [
        {
            "id": "e5f6a7b8-0000-4a11-8888-abcde1234567",
            "serial_number": "WB-10023",
            "earth_code": "EC-88231",
            "batch_number": "BATCH-2026-01",
            "color": "Blue",
            "type": "wearable_band",
            "status": "available",
            "school": null,
            "dependant": null,
            "assigned_at": null,
            "created_at": "2026-01-05 09:00:00"
        }
    ]
}
POST Add Stock Item IoT Stock {{url}}/iot-stock

Register a single wearable device into stock.

Request Body

  • serial_number (string, required, unique).
  • earth_code (string, optional, unique).
  • batch_number (string, optional).
  • color (string, optional).
  • type (string, optional).
  • administrative_id (string UUID, optional): pre-allocate the item to a school.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "serial_number": "WB-10099",
    "earth_code": "EC-88299",
    "batch_number": "BATCH-2026-02",
    "color": "Red",
    "type": "wearable_band"
}
Sample Response (200 OK)
{
    "status": 200,
    "message": "Wearable added to stock",
    "data": {
        "id": "f6a7b8c9-0000-4a11-8888-abcde1234567",
        "serial_number": "WB-10099",
        "earth_code": "EC-88299",
        "batch_number": "BATCH-2026-02",
        "color": "Red",
        "type": "wearable_band",
        "status": "available",
        "school": null,
        "dependant": null,
        "assigned_at": null,
        "created_at": "2026-07-13 10:00:00"
    }
}
POST Bulk Add Stock IoT Stock {{url}}/iot-stock/bulk

Register many wearable devices into stock in one call — used by the bulk-upload flow.

Request Body

  • items (array, required, min 1), each with:
  • serial_number (string, required, unique across all items and existing stock).
  • earthcode / batchnumber / color / type (string, all optional; type defaults to wearable_band).
  • administrative_id (string UUID, optional).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "items": [
        {
            "serial_number": "WB-20001",
            "batch_number": "BATCH-2026-03",
            "color": "Green"
        },
        {
            "serial_number": "WB-20002",
            "batch_number": "BATCH-2026-03",
            "color": "Green"
        }
    ]
}
Sample Response (200 OK)
{
    "status": 200,
    "data": [],
    "message": "Bulk stock added successfully"
}
GET Get Stock Item IoT Stock {{url}}/iot-stock/e5f6a7b8-0000-4a11-8888-abcde1234567

Retrieve a single wearable stock item by UUID.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "message": "Stock item fetched successfully",
    "data": {
        "id": "e5f6a7b8-0000-4a11-8888-abcde1234567",
        "serial_number": "WB-10023",
        "earth_code": "EC-88231",
        "batch_number": "BATCH-2026-01",
        "color": "Blue",
        "type": "wearable_band",
        "status": "available",
        "school": null,
        "dependant": null,
        "assigned_at": null,
        "created_at": "2026-01-05 09:00:00"
    }
}
PUT Update Stock Item IoT Stock {{url}}/iot-stock/update/e5f6a7b8-0000-4a11-8888-abcde1234567

Update a stock item's metadata, status, or school allocation.

Request Body (all optional)

  • earth_code (string, unique).
  • batch_number / color / type (string).
  • status (string).
  • administrative_id (string UUID, nullable): reassign (or unassign, if omitted/null) the school this stock belongs to.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "status": "available",
    "color": "Blue"
}
Sample Response (200 OK)
{
    "status": 200,
    "message": "Stock item updated successfully",
    "data": {
        "id": "e5f6a7b8-0000-4a11-8888-abcde1234567",
        "serial_number": "WB-10023",
        "earth_code": "EC-88231",
        "batch_number": "BATCH-2026-01",
        "color": "Blue",
        "type": "wearable_band",
        "status": "available",
        "school": null,
        "dependant": null,
        "assigned_at": null,
        "created_at": "2026-01-05 09:00:00"
    }
}
POST Assign Stock to School IoT Stock {{url}}/iot-stock/assign-to-school

Bulk-assign wearable stock (by serial number) to a school. Only stock that isn't already tied up with a dependant is reassignable.

Request Body

  • serial_numbers (string[], required, min 1).
  • administrative_id (string UUID, required): the school to assign to.

Response

  • assigned — how many items were reassigned.
  • skipped — serial numbers that didn't match any reassignable stock item.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "serial_numbers": [
        "WB-10023",
        "WB-10024"
    ],
    "administrative_id": "448e2ae4-48b4-4842-84b1-a73c84d21de1"
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "assigned": 2,
        "skipped": []
    },
    "message": "Assigned 2 device(s) to school successfully"
}

Zones/Locations

GET List Zones/Locations {{url}}/utility/zones

List zones/locations (vehicles / pickup areas) for the organisation. Like Tags, this is read directly from TerraGo's registry, re-paginated so the links point back at TerraGo.

Query Parameters

  • showonlymain (boolean, optional): Return only main zones/locations.
  • zone_id (string, optional): Filter by a main zone/location id.
  • status (string, optional), zone_type (string, optional), tags (optional): Additional the registry filters.
  • search (string, optional): Text search.
  • per_page (integer, optional, default 10, max 20), page (integer, optional).

Response

Paginated collection of zones/locations (ZoneResource).

Notes

  • Depends on the registry; returns a warning if the registry call fails.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Request Body
{
    // "search":  "Terra Hq",
    "show_only_main": false,  
    "zone_type": "Mobile", // Fixed for fixed zone
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "ada52fc6-d481-48d9-82b3-fddb07d5d44f",
            "name": "Terra Hq",
            "zone_type": null,
            "description": "nnn",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": [],
            "metadata": {
                "Age": "12"
            }
        },
        {
            "id": "69a977c0-69f0-461e-b09d-b098a2cf412d",
            "name": "WS3 Main Gate",
            "zone_type": null,
            "description": "Main Gate Access",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "10a7b5f5-6fef-4b60-a265-000cb9c862d8",
            "name": "WS3 Dining Hall",
            "zone_type": null,
            "description": "Dining hall access",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "ffda0655-6d6b-4341-b666-1e3429066e27",
            "name": "Park View Room 101",
            "zone_type": null,
            "description": "Notes",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "e6a21cd2-d7cc-4671-b20b-0020fdcf5847",
            "name": "SITE A",
            "zone_type": null,
            "description": "sdsaa",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "0d8a8f14-6e16-48bc-9485-facff301725b",
            "name": "Backstage",
            "zone_type": null,
            "description": "Backstage",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "dfa84171-df4f-43ab-89cb-5d86ab55f6ab",
            "name": "Main Entrance",
            "zone_type": null,
            "description": "Main Entrance",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [],
            "whitelist_tags": []
        },
        {
            "id": "33029d12-b2db-4def-acdf-ea75cb84427e",
            "name": "SAFARI-WALK",
            "zone_type": null,
            "description": "ZONE ENTRY",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [
                {
                    "id": "2bf8b100-e0df-41e0-96c6-453d7c0f079e",
                    "name": "Zephr Dyer",
                    "description": "Quis porro tempore",
                    "entity": "zone",
                    "color_code": null
                }
            ],
            "whitelist_tags": []
        },
        {
            "id": "fb3d18ca-1688-46d6-8efe-bafbf02a8335",
            "name": "KBJ 101D",
            "zone_type": null,
            "description": "Ruaka Ndenderu Route",
            "main_zone": null,
            "is_sub_zone": 0,
            "tags": [
                {
                    "id": "2bf8b100-e0df-41e0-96c6-453d7c0f079e",
                    "name": "Zephr Dyer",
                    "description": "Quis porro tempore",
                    "entity": "zone",
                    "color_code": null
                }
            ],
            "whitelist_tags": [
                {
                    "id": "7b18d5ea-346e-4b5c-8936-4a1f4cdaabb0",
                    "name": "Universal Tag",
                    "description": "This is a Universal Tag",
                    "entity": "universal",
                    "color_code": "#34C759",
                    "whitelisted_under": "account"
                },
                {
                    "id": "7b18d5ea-346e-4b5c-8936-4a1f4cdaabb0",
                    "name": "Universal Tag",
                    "description": "This is a Universal Tag",
                    "entity": "universal",
                    "color_code": "#34C759",
                    "whitelisted_under": "dependant"
                },
                {
                    "id": "5f9cbe4d-8274-47f4-84cc-8ba83f247c1e",
                    "name": "WS3",
                    "description": "World Service #3 schools",
                    "entity": "dependant",
                    "color_code": "#FF9500",
                    "whitelisted_under": "dependant"
                },
                {
                    "id": "dced7eab-c41a-4053-a38f-60b52b859f04",
                    "name": "Wasee",
                    "description": "Wathee",
                    "entity": "account",
                    "color_code": "#FF9500",
                    "whitelisted_under": "account"
                }
            ]
        }
    ],
    "links": {
        "first": "http://localhost:8001/api/zones?page=1",
        "last": "http://localhost:8001/api/zones?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": "http://localhost:8001/api/zones?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://localhost:8001/api/zones",
        "per_page": 10,
        "to": 9,
        "total": 9
    },
    "status": 200,
    "message": "Zones Retrieved Successfully"
}

Communication

GET List Communication Logs Communication {{url}}/communication/logs

Retrieve a paginated log of messages sent to parents (SMS/WhatsApp), including delivery status.

Query Parameters

  • per_page (integer, optional, default 10, max 20)
  • senderuserid (string UUID, optional)
  • supervisor_id (string UUID, optional): Scope to a school.
  • status (string, optional): e.g. SENT, DELIVERED, FAILED, PENDING.
  • channel (string, optional): SMS or WHATSAPP.
  • category (string, optional): Message category, matching a template category.
  • date_range (string, optional): "YYYY-MM-DD,YYYY-MM-DD".
  • search (string, optional): Matches phone number, subject, or content.

Response

Paginated list of communication-log entries (data) with meta; each: channel, recipient, status and timestamp.

Auth
Bearer token
Used On
Request Body
{
    // "date_range": "2025-10-23 14:03:21, 2025-10-23 14:03:21",
    "status": "PENDING", //only use: PENDING, SENT, DELIVERED, FAILED
    "channel": "WHATSAPP", //only use: SMS, WHATSAPP
    "category": "CHECK_IN", //only use: GENERAL, CHECK_IN, CHECK_OUT, TRAFFIC_DELAY, VEHICLE_ISSUE, WEATHER_ISSUE, SAFETY_INCIDENT
    "search": "",
    "supervisor_id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
    "sender_user_id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "b449cadf-e469-49d6-b9d5-28db605c2aba",
            "phone": "+254791472893",
            "parent": {
                "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "phone": "+254791472893",
                "email": "Parent@gmail.com",
                "first_name": "Pm",
                "last_name": "Parent"
            },
            "dependant": {
                "id": "18435a9c-5822-4f31-9a56-aca28e2a038d",
                "first_name": "Middle",
                "last_name": "PM"
            },
            "sender": {
                "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
                "first_name": "Collins",
                "last_name": "Muriuki"
            },
            "category": "Check In",
            "subject": "Terra Go Check In",
            "content": "Mzazi Mpendwa Mtoto amepanda basi!",
            "channel": "WhatsApp",
            "status": "Pending",
            "response": null,
            "created_at": "2026-01-14 10:38:15"
        },
        {
            "id": "e493e3dd-ea82-4207-bc06-7e0b325b3099",
            "phone": "+254791472893",
            "parent": {
                "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "phone": "+254791472893",
                "email": "Parent@gmail.com",
                "first_name": "Pm",
                "last_name": "Parent"
            },
            "dependant": {
                "id": "18435a9c-5822-4f31-9a56-aca28e2a038d",
                "first_name": "Middle",
                "last_name": "PM"
            },
            "sender": {
                "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
                "first_name": "Collins",
                "last_name": "Muriuki"
            },
            "category": "Check In",
            "subject": "Terra Go Check In",
            "content": "Mzazi Mpendwa Mtoto amepanda basi!",
            "channel": "WhatsApp",
            "status": "Pending",
            "response": null,
            "created_at": "2026-01-14 10:36:25"
        },
        {
            "id": "fab6ae02-0be7-4ff5-bf03-033e1890d801",
            "phone": "+254791472893",
            "parent": {
                "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "phone": "+254791472893",
                "email": "Parent@gmail.com",
                "first_name": "Pm",
                "last_name": "Parent"
            },
            "dependant": {
                "id": "18435a9c-5822-4f31-9a56-aca28e2a038d",
                "first_name": "Middle",
                "last_name": "PM"
            },
            "sender": {
                "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
                "first_name": "Collins",
                "last_name": "Muriuki"
            },
            "category": "Check In",
            "subject": "Terra Go Check In",
            "content": "Mzazi Mpendwa Mtoto amepanda basi!",
            "channel": "WhatsApp",
            "status": "Pending",
            "response": null,
            "created_at": "2026-01-14 10:34:04"
        },
        {
            "id": "e00614ce-400c-4047-ba72-b00ff3a9d54b",
            "phone": "+254791472893",
            "parent": {
                "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "phone": "+254791472893",
                "email": "Parent@gmail.com",
                "first_name": "Pm",
                "last_name": "Parent"
            },
            "dependant": {
                "id": "18435a9c-5822-4f31-9a56-aca28e2a038d",
                "first_name": "Middle",
                "last_name": "PM"
            },
            "sender": {
                "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
                "first_name": "Collins",
                "last_name": "Muriuki"
            },
            "category": "Check In",
            "subject": "Terra Go Check In",
            "content": "Mzazi Mpendwa Mtoto amepanda basi!",
            "channel": "WhatsApp",
            "status": "Pending",
            "response": null,
            "created_at": "2026-01-13 16:58:16"
        },
        {
            "id": "96539eca-cc0b-4a13-94d1-a88b2b54c10b",
            "phone": "+254791472893",
            "parent": {
                "id": "d23b811d-368c-44fd-a031-6663bed28fc0",
                "phone": "+254791472893",
                "email": "Parent@gmail.com",
                "first_name": "Pm",
                "last_name": "Parent"
            },
            "dependant": {
                "id": "18435a9c-5822-4f31-9a56-aca28e2a038d",
                "first_name": "Middle",
                "last_name": "PM"
            },
            "sender": {
                "id": "0e02c849-6f36-4fb9-81d3-64a22908ee5a",
                "first_name": "Collins",
                "last_name": "Muriuki"
            },
            "category": "Check In",
            "subject": "Terra Go Check In",
            "content": "Mzazi Mpendwa Mtoto amepanda basi!",
            "channel": "WhatsApp",
            "status": "Pending",
            "response": null,
            "created_at": "2026-01-13 16:56:49"
        }
    ],
    "links": {
        "first": "http://terrago.test/api/communication/logs?page=1",
        "last": "http://terrago.test/api/communication/logs?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": "http://terrago.test/api/communication/logs?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://terrago.test/api/communication/logs",
        "per_page": 10,
        "to": 5,
        "total": 5
    },
    "status": 200,
    "message": "Communication Logs Retrieved Successfully"
}
GET Get Communication Stats Communication {{url}}/communication/stats

SMS-channel engagement stats for the admin dashboard cards — sent this month, sent today, and month-to-date failure rate.

Query Parameters

  • supervisor_id (string UUID, optional): scope stats to a single school; omitted for the org-wide (System Admin) view.

Response

  • channel — always SMS (this endpoint only covers the SMS channel).
  • sentmtd / senttoday — messages sent or delivered, month-to-date / today.
  • failure_rate — percentage of this month's messages that failed.
  • total_mtd — total messages (any status) this month.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Used On
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "channel": "SMS",
        "sent_mtd": 1204,
        "sent_today": 38,
        "failure_rate": 1.4,
        "total_mtd": 1221
    },
    "message": "Communication stats retrieved successfully"
}

Templates

GET List Message Templates Templates {{url}}/templates

Retrieve a paginated list of reusable SMS/WhatsApp/email message templates (e.g. "Child checked in", "Trip delayed").

Query Parameters

  • per_page (integer, optional, default 10, max 20)
  • supervisor_id (string UUID, optional): Templates scoped to a school; org-wide templates have no owner.
  • categories (string, optional): Comma-separated category keys to filter by.
  • is_active (boolean, optional)
  • channel (string, optional): e.g. SMS, WHATSAPP, EMAIL.
  • search (string, optional): Matches name, category, subject, or content.

Response

List of message templates (data).

Auth
Bearer token
Used On
Request Body
{
    "is_active": true, //only use: rue, false
    "search": "",
    "supervisor_id": "d0672893-35bb-4fe5-819f-dc073b786d23",
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "909e0d32-1913-4847-94fc-747fd5727513",
            "name": "Test Template",
            "category": "CHECK_IN",
            "subject": "Child Checkin",
            "content": "Mzazi Mpendwa Mtoto amepanda basi"
        }
    ],
    "links": {
        "first": "http://terrago.test/api/templates?page=1",
        "last": "http://terrago.test/api/templates?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": "http://terrago.test/api/templates?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://terrago.test/api/templates",
        "per_page": 10,
        "to": 1,
        "total": 1
    },
    "status": 200,
    "message": "Templates Retrieved Successfully"
}
POST Create/Update Message Template Templates {{url}}/templates/add

Create a message template, or update it in place if one already exists for the same category + channel + target + school (upsert).

Request Body

  • name (string, required)
  • category (string, required): Must be a known template category.
  • subject (string, required)
  • content (string, required): The message body, likely supporting placeholders.
  • channel (string, optional, default SMS)
  • target (string, optional): Who the template is aimed at.
  • is_active (boolean, optional, default true)
  • administrativestaffid (string UUID, optional): School that owns this template; omit for an org-wide template.

Notes

  • The uniqueness key for the upsert is (category, channel, target, administrativestaffid) — posting the same combination again edits the existing template instead of creating a duplicate.

Response

The created/updated template (data).

Auth
Bearer token
Used On
Request Body
{
    "administrative_staff_id" : "d0672893-35bb-4fe5-819f-dc073b786d23",
    "name": "Test Template",
    "category": "CHECK_IN", //only use: GENERAL, CHECK_IN, CHECK_OUT, TRAFFIC_DELAY, VEHICLE_ISSUE, WEATHER_ISSUE, SAFETY_INCIDENT
    "subject": "Child Checkin",
    "content": "Mzazi Mpendwa Mtoto amepanda basi",
    "target": "SINGLE", //only use: GLOBAL, SINGLE
    "suffix": "powered by us."
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "909e0d32-1913-4847-94fc-747fd5727513",
        "name": "Test Template",
        "category": "CHECK_IN",
        "subject": "Child Checkin",
        "content": "Mzazi Mpendwa Mtoto amepanda basi"
    },
    "message": "Template created successfully"
}
PUT Update Message Template Templates {{url}}/templates/update/909e0d32-1913-4847-94fc-747fd5727513

Update an existing message template.

Path Parameters

  • id (string UUID, required): Template UUID.

Request Body

Same fields as Create/Update Message Template.

⚠️ Notes

  • If content is submitted empty/blank, the template is deleted instead of being updated — this endpoint doubles as a soft "clear to delete" action, so don't send an empty content field by accident.

Response

The updated template (data).

Auth
Bearer token
Used On
Request Body
{
    "name": "Test Template",
    "category": "CHECK_IN", //only use: GENERAL, CHECK_IN, CHECK_OUT, TRAFFIC_DELAY, VEHICLE_ISSUE, WEATHER_ISSUE, SAFETY_INCIDENT
    "subject": "Child Checkin",
    "content": "Mzazi Mpendwa Mtoto amepanda basi saa hii",
    "target": "SINGLE", //only use: GLOBAL, SINGLE
    "suffix": "powered by us."
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "909e0d32-1913-4847-94fc-747fd5727513",
        "name": "Test Template",
        "category": "CHECK_IN",
        "subject": "Child Checkin",
        "content": "Mzazi Mpendwa Mtoto amepanda basi saa hii"
    },
    "message": "Template updated successfully"
}
POST Download Import Template Templates {{url}}/templates/import-template

Download a pre-filled .xlsx bulk-import template for parents, children, devices, or wearables — used by the admin dashboard's bulk-upload flow.

Query Parameters

  • entity (string, required): one of parents, dependants, devices, wearables.
  • administrative_id (string UUID): the school (Administrative Staff) to scope the template to. Required when entity=dependants (needed to populate route/tag choices); optional for the other entity types.

Response

Binary .xlsx file download (Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet), not JSON.

Notes

  • Also reachable via GET on the same path (Route::match(['get','post'], ...)); the frontend calls it as POST.
  • Does not require auth at the route level, but is only ever called from within the authenticated admin dashboard.
Auth
Bearer token

WhatsApp Flow Menus

GET List Menus WhatsApp Flow Menus {{url}}/whatsapp-flow-menus

List every WhatsApp flow menu item, ordered by sort_order — the admin dashboard's System Settings → WhatsApp Flow Menu tab.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": [
        {
            "id": 1,
            "name": "main_menu",
            "description": "Top-level WhatsApp flow menu shown to parents.",
            "enabled": true,
            "sort_order": 0,
            "created_at": "2026-05-19T00:00:00.000000Z",
            "updated_at": "2026-05-19T00:00:00.000000Z"
        }
    ],
    "message": "success"
}
POST Create Menu WhatsApp Flow Menus {{url}}/whatsapp-flow-menus/add

Create a new WhatsApp flow menu item.

Request Body

  • name (string, required, unique).
  • description (string, required).
  • enabled (boolean, optional, default true).
  • sort_order (integer, optional, default 0).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "name": "book_a_ride",
    "description": "Lets a parent book an ad-hoc ride.",
    "enabled": true,
    "sort_order": 1
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": 2,
        "name": "book_a_ride",
        "description": "Top-level WhatsApp flow menu shown to parents.",
        "enabled": true,
        "sort_order": 0,
        "created_at": "2026-05-19T00:00:00.000000Z",
        "updated_at": "2026-05-19T00:00:00.000000Z"
    },
    "message": "Menu created successfully"
}
PUT Update Menu WhatsApp Flow Menus {{url}}/whatsapp-flow-menus/update/1

Update a WhatsApp flow menu item.

Request Body (all optional)

  • name (string, unique).
  • description (string).
  • enabled (boolean).
  • sort_order (integer).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "description": "Updated description."
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": 1,
        "name": "main_menu",
        "description": "Top-level WhatsApp flow menu shown to parents.",
        "enabled": true,
        "sort_order": 0,
        "created_at": "2026-05-19T00:00:00.000000Z",
        "updated_at": "2026-05-19T00:00:00.000000Z"
    },
    "message": "Menu updated successfully"
}
DELETE Delete Menu WhatsApp Flow Menus {{url}}/whatsapp-flow-menus/delete/1

Delete a WhatsApp flow menu item.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": [],
    "message": "Menu deleted successfully"
}
POST Reorder Menus WhatsApp Flow Menus {{url}}/whatsapp-flow-menus/reorder

Bulk-update the sort_order of many menu items at once (drag-to-reorder in the UI).

Request Body

  • menus (array, required), each with:
  • id (integer, required, must exist).
  • sort_order (integer, required).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "menus": [
        {
            "id": 1,
            "sort_order": 0
        },
        {
            "id": 2,
            "sort_order": 1
        }
    ]
}
Sample Response (200 OK)
{
    "status": 200,
    "data": [
        {
            "id": 1,
            "name": "main_menu",
            "description": "Top-level WhatsApp flow menu shown to parents.",
            "enabled": true,
            "sort_order": 0,
            "created_at": "2026-05-19T00:00:00.000000Z",
            "updated_at": "2026-05-19T00:00:00.000000Z"
        }
    ],
    "message": "Order updated successfully"
}
PUT Toggle Menu WhatsApp Flow Menus {{url}}/whatsapp-flow-menus/toggle/1

Enable or disable a menu item without touching its other fields.

Request Body

  • enabled (boolean, required).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "enabled": false
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": 1,
        "name": "main_menu",
        "description": "Top-level WhatsApp flow menu shown to parents.",
        "enabled": false,
        "sort_order": 0,
        "created_at": "2026-05-19T00:00:00.000000Z",
        "updated_at": "2026-05-19T00:00:00.000000Z"
    },
    "message": "Menu status updated successfully"
}

Subscription Voucher Codes

GET List Vouchers Subscription Voucher Codes {{url}}/subscription-voucher-codes

Paginated, filterable list of subscription voucher codes — the admin dashboard's System Settings → Vouchers tab.

Query Parameters

  • status (string, optional): pending or used.
  • code (string, optional): partial match.
  • parent_id (integer, optional): filter by the redeeming user's internal id.
  • search (string, optional): matches code or the redeeming user's name/email.
  • per_page (integer, optional, max 100).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "data": [
            {
                "id": "a1b2c3d4-1111-4a11-8888-abcde1234567",
                "code": "TERRA-FREE-2026",
                "amount": 1500,
                "duration": 1,
                "user_id": null,
                "status": "pending",
                "created_at": "2026-07-13T10:00:00.000000Z",
                "updated_at": "2026-07-13T10:00:00.000000Z"
            }
        ],
        "total": 1,
        "per_page": 20,
        "current_page": 1,
        "last_page": 1
    },
    "message": "success"
}
POST Create Voucher Subscription Voucher Codes {{url}}/subscription-voucher-codes/add

Create a new subscription voucher code.

Request Body

  • code (string, required, unique).
  • amount (number, required, min 0).
  • duration (integer, required): number of billing cycles the voucher discounts; -1 means forever (see SubscriptionVoucherCode::DURATION_FOREVER).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "code": "TERRA-FREE-2026",
    "amount": 1500,
    "duration": 1
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "a1b2c3d4-1111-4a11-8888-abcde1234567",
        "code": "TERRA-FREE-2026",
        "amount": 1500,
        "duration": 1,
        "user_id": null,
        "status": "pending",
        "created_at": "2026-07-13T10:00:00.000000Z",
        "updated_at": "2026-07-13T10:00:00.000000Z"
    },
    "message": "Voucher created successfully"
}
DELETE Delete Voucher Subscription Voucher Codes {{url}}/subscription-voucher-codes/delete/a1b2c3d4-1111-4a11-8888-abcde1234567

Soft-delete a voucher code.

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
Sample Response (200 OK)
{
    "status": 200,
    "data": null,
    "message": "Voucher deleted successfully"
}

Reports

GET Admin — Overview Stats Reports {{url}}/reports/admin/overview-stats

Org-wide week-over-week growth for the four admin-dashboard cards: parents, schools, kids, and buses (bus minders). Compares records created this week (Monday→now) against the previous full week.

Response

For each of parents, schools, kids, buses:

  • this_week — count created this week.
  • last_week — count created the prior week.
  • delta_pct — percentage change vs last week, or null when there's no prior-week baseline (UI then shows the raw "+N this week").

Also returns period.thisweekstart / period.lastweekstart.

Notes

  • "schools" = Administrative Staff users; "buses" = Staff with stafftype = BUSMINDER; "kids" = all students.
  • System-admin endpoint — aggregates across all schools.
  • Requires a bearer token (auth:api).
Auth
Bearer token
GET Admin — Daily Taps Reports {{url}}/reports/admin/daily-taps

Org-wide (not school-scoped) admin-dashboard metric: how many distinct active students were marked PRESENT in a window, versus the total active student base — i.e. daily platform "tap" adoption.

Query Parameters

  • period_start (date, optional, default today): Start of the window (start of day).
  • period_end (date, optional, default today): End of the window (end of day).

Response

uniquestudents, totalstudents (all active students), percentage (unique / total × 100), and the resolved periodstart / periodend.

Notes

  • Counts distinct students with a PRESENT roll-call in the window.
  • This is a system-admin endpoint — it aggregates across all schools, not just the caller's.
  • Requires a bearer token (auth:api).
Auth
Bearer token
GET Admin — List Report Schedule Settings Reports {{url}}/reports/admin/report-schedule-settings

List the automated report delivery schedules, one entry per frequency (Daily, Weekly, Monthly). Returns the configured settings if present, or defaults for any frequency not yet configured.

Response

An array of settings, each with frequency, sendat, dayofweek, dayofmonth, weekdaysonly, timezone, is_enabled, and a human-readable schedule summary.

Notes

  • Pairs with Update Report Schedule Setting to enable/disable and tune each schedule.
  • System-admin endpoint. Requires a bearer token (auth:api).
Auth
Bearer token
PUT Admin — Update Report Schedule Setting Reports {{url}}/reports/admin/report-schedule-settings/Daily

Create or update the automated report schedule for a given frequency (Daily, Weekly, or Monthly). Upserts the setting for that frequency.

Path Parameters

  • frequency (string, required): One of Daily, Weekly, Monthly. An invalid value returns a validation error.

Request Body

  • send_at (string, required): Delivery time, HH:mm (send hour must be within the allowed window, 05:00–20:00).
  • timezone (string, required): Must be one of the allowed timezones.
  • dayofweek (integer, optional): 17 (Mon–Sun) — used for Weekly.
  • dayofmonth (integer, optional): 128 — used for Monthly.
  • weekdays_only (boolean, optional): For Daily, restrict sends to weekdays.
  • is_enabled (boolean, optional): Turn this schedule on/off.

Response

The upserted schedule setting.

Notes

  • System-admin endpoint. Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "send_at": "07:00",  // Time of day to send (HH:mm, 24-hour)
    "timezone": "Africa/Nairobi",  // Timezone, e.g. Africa/Nairobi
    "weekdays_only": true,  // Only send on weekdays (Mon–Fri)
    "is_enabled": true  // Turn this schedule on/off
}