REST API¶
The Databús REST API is served by the orchestrator service (Django + Daphne,
ASGI) on port 8000 in development and behind Traefik at api.<domain> in
production. It is the control plane for run management and the data-access
layer for GTFS Schedule data.
OpenAPI / ReDoc: GET /api/docs/ — interactive documentation generated by
drf-spectacular.
Schema download: GET /api/docs/schema/ — returns the AsyncAPI YAML for
the realtime interface (backend/api/realtime.yml).
Authentication: Token authentication (TokenAuthentication) via the
Authorization: Token <key> header. Obtain a token with POST /api/login/.
Not all endpoints require a token (GTFS Schedule reads are currently open).
Authentication¶
POST /api/login/¶
Authenticate an operator and receive a token.
Request:
Response 200:
Response 400: {"error": "Usuario o contraseña incorrectos"}
Run lifecycle endpoints¶
POST /api/create-run/¶
Request creation of a new run. This is a synchronous multi-step call:
- Deserializes and validates the request body.
- Validates that
vehicle_idandoperator_idexist in the database. - Creates a
Runrecord in stateREQUESTED. - Applies
VALIDATE_RUN(GTFS consistency check) → stateVALIDATED. - Applies
INITIALIZE_RUN(writes Redis state, vehicle metadata) → stateINITIALIZED.
Request body fields:
| Field | Type | Required | Notes |
|---|---|---|---|
route_id |
string | Yes | GTFS route_id |
trip_id |
string | Yes | GTFS trip_id |
shape_id |
string | Yes | GTFS shape_id |
direction_id |
int | No | GTFS direction_id |
start_date |
date | Yes | Service date (YYYY-MM-DD) |
start_time |
duration | No | Scheduled start time |
schedule_relationship |
string | No | SCHEDULED / ADDED / UNSCHEDULED / etc. |
vehicle_id |
string | Yes | Must exist in operations.Vehicle |
operator_id |
string | Yes | Must exist in operations.Operator |
Response 200 (success):
Response 400 — serialization or operational validation failure:
Response 422 — GTFS consistency check failed:
GET /api/runs/<uuid:run_id>/state/¶
Return the current lifecycle state of a run.
Response 200:
Response 404: {"status": "error", "errors": {"run_id": "Run not found"}}
POST /api/runs/<uuid:run_id>/update/¶
Request a lifecycle state transition for an existing run. This is the endpoint used by the operator UI and the simulator to send operator commands.
Request body:
| Field | Type | Required | Notes |
|---|---|---|---|
event |
string | Yes | One of the allowed event values (see below) |
details |
object | No | Additional payload merged into the event context |
Allowed event values (from RunLifecycleEvents):
| Event string | Meaning |
|---|---|
run_confirmed_by_operator |
Operator confirms they are ready (RUN_CONFIRMED) |
run_completed |
Manual completion — run ended successfully (RUN_COMPLETED) |
run_interrupted |
Manual interrupt — run ended unexpectedly (RUN_INTERRUPTED) |
run_short_turned |
Manual short-turn — vehicle turned around early (RUN_SHORT_TURNED) |
cancel_run |
Cancel before the run started |
run_tracking_started |
(Usually detected, but can be sent manually) |
run_started |
(Usually detected, but can be sent manually) |
Note
run_completed is the event string for both manual and automatic completion.
Commit 54e23f3 renamed complete_run → run_completed to make clear it is
a fact (something that happened), not a command. The REST endpoint
accepts it as a command in the operator-triggered path; the detection layer
fires it automatically in the telemetry-driven path.
Response 200 (success):
Response 400 — invalid event name or serialization error.
Response 404 — run not found.
Response 422 — FSM guard rejected the transition.
GET /api/runs/<uuid:run_id>/history/¶
Return the ordered FSM transition audit log for a run.
Response 200:
{
"run_id": "uuid",
"transitions": [
{
"event": "run_requested",
"from_state": null,
"to_state": "Requested",
"timestamp": "2026-06-19T12:00:00+00:00",
"actions": {},
"guards": {}
}
]
}
Operations endpoints¶
CRUD ViewSets for operational domain entities. All require token authentication unless noted.
| Endpoint prefix | Model | Notes |
|---|---|---|
/api/company/ |
Company |
Token auth currently commented out |
/api/operator/ |
Operator |
|
/api/vehicle/ |
Vehicle |
Filterable by company |
/api/data-provider/ |
DataProvider |
|
/api/equipment/ |
Equipment |
POST returns {"id": ...} |
/api/equipment-log/ |
EquipmentLog |
Filterable by equipment, data_provider, vehicle |
Telemetry record endpoints¶
Historical GTFS-RT entity records. All require token authentication.
| Endpoint prefix | Model |
|---|---|
/api/position/ |
runs.Position |
/api/stop-status/ |
runs.VehicleStopStatus |
/api/occupancy/ |
runs.OccupancyStatus |
/api/congestion/ |
runs.CongestionLevel |
GTFS Schedule endpoints¶
Read-only schedule data. Token authentication is currently not enforced.
| Endpoint | Filterable by |
|---|---|
GET /api/agency/ |
agency_id, agency_name |
GET /api/stops/ |
stop_id, stop_code, stop_name, stop_lat, stop_lon, stop_url |
GET /api/geo-stops/ |
stop_id, location_type, zone_id, parent_station, wheelchair_boarding |
GET /api/routes/ |
route_type, route_id |
GET /api/trips/ |
shape_id, direction_id, trip_id, route_id, service_id |
GET /api/stop-times/ |
trip_id, stop_id |
GET /api/shapes/ |
shape_id |
GET /api/geo-shapes/ |
shape_id |
GET /api/calendars/ |
service_id |
GET /api/calendar-dates/ |
service_id |
GET /api/fare-attributes/ |
fare_id |
GET /api/fare-rules/ |
route_id, origin_id, destination_id |
GET /api/feed-info/ |
feed_publisher_name |
Auxiliary GTFS endpoints¶
| Endpoint | Parameters | Purpose |
|---|---|---|
GET /api/service-today/ |
?date=YYYY-MM-DD (optional) |
Returns active service_id list for a date |
GET /api/which-shapes/ |
?route_id= |
Returns GeoShapes for a route |
GET /api/find-trips/ |
?route_id=&service_id=&shape_id= |
Returns trips with start times and run lifecycle states |
URL structure¶
All API endpoints are mounted at /api/ in backend/databus/urls.py. The
router URL prefix comes first (e.g., /api/vehicle/), then the explicit
hand-written paths (e.g., /api/create-run/, /api/runs/<id>/update/).
Source: backend/api/urls.py, backend/api/views.py.