---
title: School Bus Router
description: Curb-side-aware school bus routing — students board on their own side of the street, with bell-time AM and PM runs planned from each school.
---

# School Bus Router

School Bus Router plans K-12 bus routes with one rule the routing engine keeps
front and center: a student should never cross traffic to reach the bus. It
runs on the free Logistics core, so schools, stops, students, and buses are all
schema-driven entities you can extend.

School Bus Router is enabled through a district agreement rather than one-click
install. [Contact sales](/contact) to turn it on for your district; once your
agreement is in place it installs like any other app.

## What you get

- **Schools** — each with a location and its bell times (`bell_start` and
  `bell_end`). The school is the anchor every run is planned from.
- **Stops** — placed on a specific curb. A stop declares the side of the street
  it serves (`left`, `right`, or `either` for a controlled corner). The two
  curbs of one road are two stops.
- **Students** — each with a home location and the side of the street they live
  on.
- **Buses** — each with a seat capacity.
- **Routing Runs** — a run is tagged AM or PM and carries the crossing penalty
  and walk radius for that plan. It moves through a review lifecycle before it
  reaches drivers.

## The no-cross rule

When a run is optimized, each student is matched to the nearest stop **on their
own side of the street** within a walk radius. A student is routed across the
street only when there is no same-side stop within that radius — so the two
levers that keep students off the wrong side of the street are **where you place
your stops** and **how wide you set the walk radius**. Put a same-side stop in
range and that student never crosses.

The **crossing penalty** then tells the optimizer how hard to avoid a stop that
requires a crossing when it sequences the route: turn it up and the router works
harder to keep crossing stops out of a run — preferring a longer route, or
leaving a crossing stop for a coordinator to resolve, rather than absorbing it
casually; relax it where a crossing is cheap. The penalty and the walk radius
are set per run.

Each run's result lists the students it had to route across the street and any
student it could not place within the walk radius, so a coordinator reviewing
the proposed run can add a stop or widen the radius before it goes out.

## Bell-time AM and PM runs

The router plans from each school's bell times, not hand-entered clock windows:

- An **AM run** collects students so the bus reaches school by the start bell.
- A **PM run** is the mirror — it leaves the school at the end bell and drops
  students at their stops.

Set a run's direction to AM or PM and the pickup/drop-off windows are derived
from the bell time for you.

## The run lifecycle

A routing run moves **Draft → Queued → Assigning → Optimizing → Proposed →
Approved → Published**. A run can only leave Draft once it has students, stops,
and buses; it only reaches Proposed once the optimizer has produced routes. From
Proposed you can re-optimize with an adjusted crossing penalty, then approve and
publish.

## Plan a run

1. Add your **Schools** (with bell times), **Stops** (each on its curb, with the
   side it serves), **Students** (with their home side), and **Buses**.
2. Create a **Routing Run**, set its direction (AM or PM), and set the crossing
   penalty and walk radius.
3. Move the run through **Assign** and **Optimize**. Review the proposed routes,
   the crossing pickups, and any unassigned students on the run detail.
4. **Approve** and **Publish** when it's ready.

## Starter data

A fresh install includes a worked example — one school, a set of stops on both
curbs, a roster of students (including a couple who can only be served across
the street and one out of walking range), a small fleet, and runs spread across
every stage of the lifecycle — so you can see the board populated and clone the
setup for your own district.
