TerraGo API

Trips Planners

Recurring or one-off trip schedules (e.g. morning, mid-morning, afternoon runs) with a direction (Home→School or School→Home) and the set of zones/locations each planner covers. Create, update and list planners, and sync a planner's zones/locations.

9 endpoint(s)
GET List Trip Planners {{url}}/trip_planners

Retrieve a paginated list of trip planners — the reusable schedule templates that define when/how a trip should run (e.g. "Morning pickup, Home → School, weekdays at 6:30am"). Actual trips (see the Trips folder) are created by instantiating one of these planners.

Query Parameters

  • per_page (integer, optional, default 10, max 20)
  • supervisor_id (string UUID, optional): Filter to a school's planners; defaults to your own school/supervisor.
  • status (string, optional): DRAFT, ACTIVE, DISABLED, CANCELLED, or N/A.
  • date_range (string, optional): "YYYY-MM-DD,YYYY-MM-DD", filters by creation date.
  • search (string, optional): Matches zone/location name or planner label.

Response

Paginated list of trip planners (data) with meta; each includes label, direction, start_time, schedule and status.

Auth
Bearer token
Used On
Request Body
{
    //"supervisor_id": "eruewrweor 023r0r023ir23 23r0",
    "date_range": ["2025-10-23 14:03:21", "2025-10-23 14:03:21"],
    "status": "ACTIVE",  //only use: ACTIVE,COMPLETED,CANCELLED,N/A
    "per_page": 10,
    "page": 1
}
Sample Response (200 OK)
{
    "data": [
        {
            "id": "cfc54358-8fc3-4a54-8e09-c197b6b8d8ad",
            "label": "Midday",
            "start_time": "11:13",
            "direction": "H2S",
            "direction_label": "Home to School",
            "schedule_type": "Once",
            "status": "Active",
            "schedule_date": "2026-04-10 00:00:00",
            "recurring_days": [],
            "zones": [
                {
                    "id": "b4c66334-fad9-411b-96fa-cdf25c0b0833",
                    "waas_zone_uuid": "94e511b2-9a5f-45d2-ac5b-a53d356df6fb",
                    "waas_zone_name": "Y"
                },
                {
                    "id": "5273eeb5-d72c-4f02-b953-310e57ff26a5",
                    "waas_zone_uuid": "b6b4c801-55ec-4b09-a894-e92794ceec2f",
                    "waas_zone_name": "Test"
                },
                {
                    "id": "1f568f0b-31bf-4ebc-92a1-7bfa52df2ea9",
                    "waas_zone_uuid": "55169604-66a9-4eba-b35b-2448ea21ba86",
                    "waas_zone_name": "KAP 123"
                }
            ],
            "checkout_counts_as_rollcall": 0,
            "waas_zone_uuid": null,
            "waas_zone_name": null
        },
        {
            "id": "187c3c3d-605b-4bba-b8b4-df7e70742ff4",
            "label": "We are testing trip planner",
            "start_time": "10:53",
            "direction": "H2S",
            "direction_label": "Home to School",
            "schedule_type": "Recurring",
            "status": "Active",
            "schedule_date": null,
            "recurring_days": [
                "MONDAY",
                "TUESDAY",
                "WEDNESDAY",
                "THURSDAY"
            ],
            "zones": [
                {
                    "id": "c802945b-07cf-459f-b44f-0d6b9668c5ee",
                    "waas_zone_uuid": "55169604-66a9-4eba-b35b-2448ea21ba86",
                    "waas_zone_name": "KAP 123"
                }
            ],
            "checkout_counts_as_rollcall": 0,
            "waas_zone_uuid": null,
            "waas_zone_name": null
        },
        {
            "id": "8d82ad94-3486-40d7-b283-f750dfcef370",
            "label": "Night runner",
            "start_time": "00:00",
            "direction": "H2S",
            "direction_label": "Home to School",
            "schedule_type": "Recurring",
            "status": "Active",
            "schedule_date": null,
            "recurring_days": [
                "MONDAY",
                "TUESDAY",
                "WEDNESDAY",
                "THURSDAY",
                "FRIDAY"
            ],
            "zones": [
                {
                    "id": "0851a8d8-7f2d-44dd-b441-dc81c85698b9",
                    "waas_zone_uuid": "9275c202-0a25-4b8e-ab26-841c63636185",
                    "waas_zone_name": "Mat's Bike"
                },
                {
                    "id": "a19e8a62-5b1a-4aad-b594-e08b4877bc83",
                    "waas_zone_uuid": "55169604-66a9-4eba-b35b-2448ea21ba86",
                    "waas_zone_name": "KAP 123"
                }
            ],
            "checkout_counts_as_rollcall": 0,
            "waas_zone_uuid": null,
            "waas_zone_name": null
        },
        {
            "id": "1742827f-ddf2-4894-ab72-60f0f93ba7ff",
            "label": "Morning Trip",
            "start_time": "06:30",
            "direction": "H2S",
            "direction_label": "Home to School",
            "schedule_type": "Recurring",
            "status": "Active",
            "schedule_date": null,
            "recurring_days": [
                "MONDAY",
                "TUESDAY",
                "WEDNESDAY",
                "THURSDAY",
                "FRIDAY"
            ],
            "zones": [
                {
                    "id": "69805a30-b354-409e-a0cc-155d5553ccf9",
                    "waas_zone_uuid": "feed9143-83d9-41f7-96a0-c098508281a8",
                    "waas_zone_name": "Mobile Car"
                },
                {
                    "id": "c1ac90dd-9e11-4ab0-801a-5769560b72b8",
                    "waas_zone_uuid": "9275c202-0a25-4b8e-ab26-841c63636185",
                    "waas_zone_name": "Mat's Bike"
                },
                {
                    "id": "bb88deac-e412-43f2-ace5-526c5ca95b84",
                    "waas_zone_uuid": "410aaf66-5477-4cdf-9c8c-634441757e6a",
                    "waas_zone_name": "KCB 551M"
                },
                {
                    "id": "02dc441a-d077-48e0-9f9b-3ad27263649e",
                    "waas_zone_uuid": "4194ced8-3a81-4bcc-8f50-b15df3a289be",
                    "waas_zone_name": "KBA 156"
                },
                {
                    "id": "2be2127a-c453-466c-a170-d7c875353c84",
                    "waas_zone_uuid": "825e7402-a072-4926-9bfb-27280c2be5eb",
                    "waas_zone_name": "KPM 321"
                },
                {
                    "id": "1068ca4f-9777-40ee-a526-af1790624680",
                    "waas_zone_uuid": "55169604-66a9-4eba-b35b-2448ea21ba86",
                    "waas_zone_name": "KAP 123"
                }
            ],
            "checkout_counts_as_rollcall": 0,
            "waas_zone_uuid": null,
            "waas_zone_name": null
        }
    ],
    "links": {
        "first": "http://127.0.0.1:8000/api/trip_planners?page=1",
        "last": "http://127.0.0.1:8000/api/trip_planners?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:8000/api/trip_planners?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next »",
                "page": null,
                "active": false
            }
        ],
        "path": "http://127.0.0.1:8000/api/trip_planners",
        "per_page": 15,
        "to": 4,
        "total": 4
    },
    "status": 200,
    "message": "Trip Plans Retrieved Successfully"
}
POST Create Trip Planner {{url}}/trip_planners/add

Create a new trip planner (schedule template).

Request Body

  • label (string, required, max 255): Display name, e.g. "Morning Pickup Route A".
  • schedule_type (string, required): ONCE or RECURRING.
  • direction (string, required): H2S (Home → School) or S2H (School → Home).
  • start_time (string, optional): HH:MM start time.
  • schedule_date (date, optional): Required for one-off (ONCE) schedules, format YYYY-MM-DD.
  • recurring_days (array, optional): Days of week this recurs on, e.g. ["MONDAY", "WEDNESDAY"].
  • checkoutcountsasrollcall (boolean, optional, default false): If true, a student tapping out at waaszone_uuid counts as their roll-call attendance for the day.
  • waaszoneuuid / waaszonename (required only if checkoutcountsas_rollcall is true): The zone/location whose checkout should count as attendance.
  • status (string, required): DRAFT, ACTIVE, DISABLED, CANCELLED, or N/A.

Response

The created trip planner (data).

Auth
Bearer token
Used On
Request Body
{
    "label" : "Evening Trip",
    "start_time": "16:00",
    "direction": "H2S", // only use: H2S, S2H
    "schedule_type": "ONCE", //only use: ONCE, RECURRING
    "recurring_days": ["MONDAY", "TUESDAY"], //only use: MONDAY, TUESDAY, WEBNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    "trip_direction": "H2S",  //use H2S for  Home to School or  S2H for School to Home
    // "schedule_date": "2025-10-23",
    "checkout_counts_as_rollcall": true,
    "waas_zone_uuid": "abb58804-ae3f-4bf4-8073-9ac8b7e0c257",
    "waas_zone_name": "TerraHQ",
    "status": "ACTIVE" //only use: DRAFT, ACTIVE, DISABLED, CANCELLED, N/A
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "da2175e7-cc4d-4c25-a8e8-4ad81300a9e1",
        "label": "Evening Trip",
        "start_time": "16:00",
        "schedule_type": "Once",
        "status": "Active",
        "schedule_date": null,
        "recurring_days": [
            "MONDAY",
            "TUESDAY"
        ],
        "zones": [],
        "checkout_counts_as_rollcall": true,
        "waas_zone_uuid": "abb58804-ae3f-4bf4-8073-9ac8b7e0c257",
        "waas_zone_name": "TerraHQ"
    },
    "message": "Trip Plan Updated Successfully"
}
PUT Update Trip Planner {{url}}/trip_planners/update/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1

Update an existing trip planner.

Path Parameters

  • id (string UUID, required): Trip planner UUID.

Request Body

Same fields as Create Trip Planner (label, scheduletype, direction, starttime, scheduledate, recurringdays, checkoutcountsasrollcall, waaszoneuuid, waaszone_name, status).

Response

The updated trip planner (data).

Auth
Bearer token
Used On
Request Body
{
    "label" : "Morning Trip",
    "start_time": "06:00",
    "direction": "H2S", // only use: H2S, S2H
    "schedule_type": "RECURRING", //only use: ONCE, RECURRING
    // "recurring_days": ["MONDAY", "TUESDAY"], //only use: MONDAY, TUESDAY, WEBNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY
    "schedule_date": "2025-10-23",
    "checkout_counts_as_rollcall": false,
    "waas_zone_uuid": null,
    "waas_zone_name": null,
    "status": "ACTIVE" //only use: DRAFT, ACTIVE, DISABLED, CANCELLED, N/A
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "da2175e7-cc4d-4c25-a8e8-4ad81300a9e1",
        "label": "Morning Trip",
        "start_time": "06:00",
        "schedule_type": "Recurring",
        "status": "Active",
        "schedule_date": "2025-10-23 00:00:00",
        "recurring_days": [],
        "zones": [],
        "checkout_counts_as_rollcall": false,
        "waas_zone_uuid": null,
        "waas_zone_name": null
    },
    "message": "Trip Plan Updated Successfully"
}
POST Sync Trip Planner Zones/Locations {{url}}/trip_planners/sync_zones/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1

Replace the set of zones/locations (e.g. eligible pickup/rollcall zones/locations) associated with a trip planner.

Path Parameters

  • id (string UUID, required): Trip planner UUID.

Request Body

  • tripplannerzones (array, required): The complete list of zones/locations that should be associated — this replaces any existing associations.
  • tripplannerzones[].id (string, required): the registry zone/location UUID.
  • tripplannerzones[].name (string, required): Zone/Location name.

Response

The planner's resulting set of zones/locations (data).

Auth
Bearer token
Used On
Request Body
{
    "trip_planner_zones": [  // Zones/locations this trip planner covers
        {
            "id": "825e7402-a072-4926-9bfb-27280c2be5eb",  // Record UUID
            "name": "KPM 321",  // Human-readable name / label
            "zone_type": "Mobile",  // FIXED (a gate/point) or MOBILE (a vehicle)
            "description": null,  // Optional free-text description
            "main_zone": {  // true if this is a top-level (parent) zone
                "id": "e19f7c31-87fa-445e-89c4-588140aa39f7",  // Record UUID
                "name": "PM School"  // Human-readable name / label
            },
            "is_sub_zone": 1,  // true if this zone is nested under a main zone
            "tags": [  // List of tag UUIDs to filter by
                {
                    "id": "d4b18b8f-eaa6-44e1-8655-d75f146c0933",  // Record UUID
                    "name": "PM School Tag",  // Human-readable name / label
                    "description": "PM School Tag",  // Optional free-text description
                    "entity": "universal",  // WaaS entity type to scope the lookup
                    "color_code": "#EA0D8D"  // Hex colour used to render this item in the UI
                }
            ],
            "whitelist_tags": [],  // Tags allowed (whitelisted) for this zone
            "metadata": {  // Extra custom key/value fields
                "fuel_type": "Petrol",  // Fuel type, e.g. PETROL / DIESEL
                "capacity": "35 Seater",  // Vehicle passenger capacity
                "consumption": "20 L"  // Fuel consumption rating (km per litre)
            },
            "assignees": []  // Staff/users assigned
        },
        {
            "id": "55169604-66a9-4eba-b35b-2448ea21ba86",  // Record UUID
            "name": "KAP 123",  // Human-readable name / label
            "zone_type": "Mobile",  // FIXED (a gate/point) or MOBILE (a vehicle)
            "description": null,  // Optional free-text description
            "main_zone": {  // true if this is a top-level (parent) zone
                "id": "e19f7c31-87fa-445e-89c4-588140aa39f7",  // Record UUID
                "name": "PM School"  // Human-readable name / label
            },
            "is_sub_zone": 1,  // true if this zone is nested under a main zone
            "tags": [  // List of tag UUIDs to filter by
                {
                    "id": "84561c7c-125c-4a96-97c8-3ba7ea5ca2e1",  // Record UUID
                    "name": "Foundation",  // Human-readable name / label
                    "description": null,  // Optional free-text description
                    "entity": "universal",  // WaaS entity type to scope the lookup
                    "color_code": "#FF9500"  // Hex colour used to render this item in the UI
                },
                {
                    "id": "5ac13004-3e77-4e9e-a9b8-be8080ce845e",  // Record UUID
                    "name": "BACKSTAGE ACCESS",  // Human-readable name / label
                    "description": "test",  // Optional free-text description
                    "entity": "universal",  // WaaS entity type to scope the lookup
                    "color_code": "#34C759"  // Hex colour used to render this item in the UI
                },
                {
                    "id": "27ba6b10-c659-408f-beb1-dc650d5d5034",  // Record UUID
                    "name": "VIP ACCESS",  // Human-readable name / label
                    "description": "VIP ACCESS",  // Optional free-text description
                    "entity": "universal",  // WaaS entity type to scope the lookup
                    "color_code": "#9351E8"  // Hex colour used to render this item in the UI
                },
                {
                    "id": "d4b18b8f-eaa6-44e1-8655-d75f146c0933",  // Record UUID
                    "name": "PM School Tag",  // Human-readable name / label
                    "description": "PM School Tag",  // Optional free-text description
                    "entity": "universal",  // WaaS entity type to scope the lookup
                    "color_code": "#EA0D8D"  // Hex colour used to render this item in the UI
                }
            ],
            "whitelist_tags": [],  // Tags allowed (whitelisted) for this zone
            "metadata": {  // Extra custom key/value fields
                "capacity": "33 Seats",  // Vehicle passenger capacity
                "fuel_type": "Diesel",  // Fuel type, e.g. PETROL / DIESEL
                "consumption": "7.5 km/l",  // Fuel consumption rating (km per litre)
                "make": "Isuzu",  // Vehicle manufacturer (e.g. Toyota)
                "model": "NQR"  // Vehicle model
            },
            "assignees": [  // Staff/users assigned
                {
                    "id": "8945d636-ee2a-45f6-929e-c817d20570ba",  // Record UUID
                    "first_name": "Last",  // First name
                    "last_name": "Updated",  // Last name
                    "staff_type": "Security"  // Staff role type (DRIVER, BUS_MINDER, TEACHER, …)
                },
                {
                    "id": "cff607d4-c366-4aa7-9335-4b3939f18350",  // Record UUID
                    "first_name": "Michael",  // First name
                    "last_name": "Njoroge",  // Last name
                    "staff_type": "Teacher"  // Staff role type (DRIVER, BUS_MINDER, TEACHER, …)
                }
            ]
        }
    ]
}
Sample Response (200 OK)
{
    "status": 200,
    "data": {
        "id": "da2175e7-cc4d-4c25-a8e8-4ad81300a9e1",
        "label": "Morning Trip",
        "start_time": "06:00",
        "schedule_type": "Recurring",
        "status": "Active",
        "schedule_date": "2025-10-23 00:00:00",
        "recurring_days": [],
        "zones": [
            {
                "id": "8556d5c2-7216-4465-9f5c-447060a2c5d7",
                "waas_zone_uuid": "55169604-66a9-4eba-b35b-2448ea21ba86",
                "waas_zone_name": "KAP 123"
            },
            {
                "id": "4ed90ae5-0a44-4dfa-907a-3099a3a77122",
                "waas_zone_uuid": "825e7402-a072-4926-9bfb-27280c2be5eb",
                "waas_zone_name": "KPM 321"
            }
        ],
        "checkout_counts_as_rollcall": 0,
        "waas_zone_uuid": null,
        "waas_zone_name": null
    },
    "message": "Trip Planner Zones Synced Successfully"
}
GET List Trip Planner Roster {{url}}/trip_planners/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1/dependants?route_id=643ab899-5b74-4dc1-b3a0-5b512dc11336

List the students assigned to a trip planner, read from the dependantrouteorders pivot — the same mapping the student profile writes and the driver-app roster filters by (GET /api/v2/students?tripplannerid=).

Path Parameters

  • id (string UUID, required): the trip planner UUID.

Query Parameters

  • route_id (string UUID, optional): scope the roster to a single route.

Response

Array of assignments, each: id (the assignment id — pass to Unassign), boarding_order, student (id, name, grade, image), route (id, name).

Notes

  • Requires a bearer token (auth:api).
Auth
Bearer token
GET List Trip Planner Candidates (Paginated) {{url}}/trip_planners/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1/candidates?route_id=643ab899-5b74-4dc1-b3a0-5b512dc11336&status=all&search=&page=1&per_page=15

Paginated student picker for a planner + route: every student on the route's the registry tag, each with an assigned flag (already on this planner for this route). Searchable and filterable by status — all server-side, so the assigned/unassigned filter paginates across the whole roster, not just the current page.

Path Parameters

  • id (string UUID, required): the trip planner UUID.

Query Parameters

  • route_id (string UUID, required).
  • status (string, optional, default all): all | assigned | unassigned.
  • search (string, optional): matches first/last/full name.
  • page (integer, optional), per_page (integer, optional, default 15, max 50).

Response

{ data: [{ id, name, grade, assigned, assignmentid }], assignedcount, meta: { currentpage, lastpage, per_page, total, from, to } }.

Notes

  • assignment_id is non-null only for assigned rows (use it to remove).
  • Requires a bearer token (auth:api).
Auth
Bearer token
POST Bulk Assign Students to Trip Planner {{url}}/trip_planners/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1/dependants

Assign one or more students to this trip planner on a given route, appended to the end of the boarding/alighting order. Idempotent — students already on this (route, planner) are skipped, not duplicated.

Path Parameters

  • id (string UUID, required): the trip planner UUID.

Request Body

  • route_id (string UUID, required): the route (must carry a the registry tag).
  • dependant_ids (array of UUID, required, min 1).

Response

{ assigned, skipped, assignments: { <dependantuuid>: <assignmentuuid> } } — the assignments map lets a client set each row's assignment id without a refetch (flicker-free UI).

Notes

  • Busts the cached the registry roster for the route tag so the driver app re-fetches.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "route_id": "643ab899-5b74-4dc1-b3a0-5b512dc11336",  // Route UUID
    "dependant_ids": [  // List of student UUIDs
        "184c32e2-878d-4e89-99c3-91dda70c03e9"
    ]
}
POST Bulk Remove Students from Trip Planner {{url}}/trip_planners/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1/dependants/bulk-remove

Remove one or more students from this trip planner on a given route in a single call (powers the "uncheck all on page" action without one DELETE per student).

Path Parameters

  • id (string UUID, required): the trip planner UUID.

Request Body

  • route_id (string UUID, required).
  • dependant_ids (array of UUID, required, min 1).

Response

{ removed: <count> }.

Notes

  • Busts the cached the registry roster for the route tag.
  • Requires a bearer token (auth:api).
Auth
Bearer token
Request Body
{
    "route_id": "643ab899-5b74-4dc1-b3a0-5b512dc11336",  // Route UUID
    "dependant_ids": [  // List of student UUIDs
        "184c32e2-878d-4e89-99c3-91dda70c03e9"
    ]
}
DELETE Unassign Student from Trip Planner {{url}}/trip_planners/da2175e7-cc4d-4c25-a8e8-4ad81300a9e1/dependants/9f8b1c22-0000-4a00-8000-abc123456789

Remove a single student's assignment from this trip planner, identified by the assignment id (id) returned by List Trip Planner Roster / Candidates.

Path Parameters

  • id (string UUID, required): the trip planner UUID.
  • assignmentId (string UUID, required): the assignment id to remove.

Notes

  • 404 if the assignment doesn't exist or doesn't belong to this planner.
  • Busts the cached the registry roster for the route tag.
  • Requires a bearer token (auth:api).

Response

Empty data; message confirms the student was removed from the planner.

Auth
Bearer token