View Categories

REST API: delivery, routes and the driver app

9 min read

The REST API for delivery and routing: the Schedule’s stops and routes, delivery areas and the address check, the driver app, and Smart Routing’s planner. Everything the Schedule, the driver app and the route board do on screen goes through these endpoints, so an outside system (a dispatch tool, a telematics app, your own driver app) can do the same. The setup and the conventions shared by every endpoint (keys, errors, pagination) are in REST API overview and authentication.

Base URLs and sign-in #

NamespaceWhat lives thereNeeds
/wp-json/wc-sibooking/v1/The Schedule, delivery areas, hand-overs and the driver appRentals & Bookings Regular for delivery areas and hand-overs; the Schedule’s and the driver app’s endpoints come with Smart Routing
/wp-json/siroutes/v1/Smart Routing’s planner (plan, accept, send)Smart Routing
  • wc-sibooking/v1 takes a WooCommerce REST API key (WooCommerce › Settings › Advanced › REST API) sent as HTTP Basic, like the other rental endpoints. The key’s user decides what it may do (below), so a key made for a driver’s account works the driver endpoints and nothing else.
  • siroutes/v1 does not start with wc-, so WooCommerce keys don’t apply there. Use a WordPress Application Password (Users › Profile › Application Passwords) as HTTP Basic (username:application password), or, inside wp-admin, the logged-in cookie with an X-WP-Nonce header.
  • Send bodies as JSON (Content-Type: application/json). Times are ISO 8601 in UTC (2026-10-20T14:24:00+00:00) unless a field says HH:MM, which is the shop’s local time.
  • Errors use the WordPress shape {"code", "message", "data": {"status"}}. The Regular codes start with sibooking_rest_; the driver and Smart Routing codes are listed with their endpoints.
STORE="https://yourstore.com/wp-json"
curl -u "ck_your_key:cs_your_secret" "$STORE/wc-sibooking/v1/schedule?day=2026-10-20"

Who may do what #

AbilityWho has itOpens
sibooking_view_scheduleShop managers and administrators, and any role given it (a reservationist who only looks)Reading the Schedule, stops, route exports, signatures and photos; Smart Routing’s day
sibooking_dispatchShop managers and administrators, and any role given itChanging stops and routes, picking drivers; Smart Routing’s plan, accept and send
sibooking_driveThe Driver role (Smart Routing adds it), plus everyone with sibooking_dispatch or manage_woocommerceThe driver endpoints. A driver opens only the routes given to them; dispatchers and shop managers open every route
manage_woocommerceShop managers, administratorsDelivery settings, delivery areas, the address check, hand-overs

A user without the ability gets 401 (not signed in) or 403.

The Schedule: stops and routes #

These endpoints come with Smart Routing: they answer while it is active, on Rentals & Bookings Regular 1.0.80 or newer (the stops and routes are Regular’s). A stop is one visit: a delivery, collection, pick-up at the shop, return to the shop, a parcel to transport (dispatch) or a parcel due back (due). A route is one van run on one day. The Schedule shows stops whose status is planned, assigned, on_the_way, done or failed.

GET /wc-sibooking/v1/schedule #

The day’s board, the same as Rentals › Schedule.

ParameterNotes
dayY-m-d; today when left out
locationA location id (Multi Location Inventory); 0 = all
viewboard (default) or week: the counts per day for the week from day

The board answers day, location, routes (each with id, name, driver, vehicle, ordered, stops, minutes, maps), unassigned (the stops not on a route), counter, toPost, dueBack, total and locations.

GET /wc-sibooking/v1/stops #

Stops as cards. Filters, all optional: day, or from and to (Y-m-d); location; area; route; order; status and kind (comma separated). Each card has:

FieldNotes
id, order, numberThe stop, the WooCommerce order id and its number
kind, kindLabeldelivery, collection, pickup, return, dispatch or due
day, window, slot, etaThe day, the booked time slot (08:00-10:00) and the planned arrival window
route, positionThe route (0 = not on one) and the place on it
customer, phone, email, address, postcode, city, country, lat, lngWhere to go
items, note, setupWhat to hand over, the customer’s note, set-up minutes
status, statusLabel, saleThe state; sale is true for an order without rentals

GET /wc-sibooking/v1/stops/{id} #

One card plus others (the order’s other stops), history (every change, each {at, type, by, data}; the driver’s taps are driver_on_the_way, driver_arrived, driver_done and driver_failed), slots (that day’s slots with places left) and pod (the proof of delivery: signature as a PNG data URL and photos as {done: [...], failed: [...]} JPEG data URLs).

PATCH /wc-sibooking/v1/stops/{id} #

Moves a stop. Send any of:

FieldNotes
routeThe route to put it on; 0 takes it off its route
positionIts place on the route, from 1; 0 = at the end
windowAnother slot that day (10:00-12:00). A full slot answers 409 slot_full unless force is true
forceBook the slot even when it is full

Answers {"ok": true, "stop": {card}}, plus warning and message when the slot changed. A driver who already has the route sees the change in the app within a few minutes.

Routes #

EndpointWhat it does
POST /wc-sibooking/v1/routesA new route: day (required), location, name (default “Route 2” and so on). Answers 201 with the route
PATCH /wc-sibooking/v1/routes/{id}Renames it: name
DELETE /wc-sibooking/v1/routes/{id}Deletes it; its stops go back to “not on a route”
POST /wc-sibooking/v1/routes/{id}/orderPuts the stops in the built-in route order (the Order routes button); answers before and after (the distance in meters) and the new order
POST /wc-sibooking/v1/routes/{id}/undoUndoes the last order: {"undone": true}
GET /wc-sibooking/v1/routes/{id}/exportThe route for Routific or OptimoRoute: columns, rows and the csv text

The driver app #

The driver app and these endpoints come with Smart Routing: they answer while Smart Routing is active, on Rentals & Bookings Regular 1.0.80 or newer. The phone app at /driver/ uses these endpoints and nothing else, so they are also the way to build your own driver app or to feed a telematics system.

GET /wc-sibooking/v1/driver/routes #

The routes the signed-in user drives on a day: day (Y-m-d, today when left out). Dispatchers and shop managers get every route, can pass driver (a user id) for one driver’s routes, and also get drivers, the people who can drive.

{"day": "2026-10-20", "me": 14, "canPick": false,
 "routes": [{"id": 31, "day": "2026-10-20", "location": 0, "name": "Route 1",
   "vehicle": "Party van", "driver": 14, "driverName": "Alex Rivera",
   "started": "", "ended": "", "stops": 5, "done": 0, "failed": 0}]}

GET /wc-sibooking/v1/driver/routes/{id} #

The whole route for the phone: the route’s fields above plus depot, stops in driving order, reasons (the Couldn’t deliver reasons), fetched and version. Each stop has id, n (its number on the route), order, number, kind, kindLabel, sale, customer, phone, address, postcode, city, lat, lng, slot, eta, items, note, setup, status, doneAt, attempts, failReason, recipient, arrived and nav (Google Maps, Apple Maps and Waze links). 403 when the route is someone else’s.

GET /wc-sibooking/v1/driver/routes/{id}/version #

{"id": 31, "version": "4f1c09a2be7d"}. The version changes when a stop is added, removed or moved, not when one is done. The app checks it every few minutes and reloads the route when it changes.

POST /wc-sibooking/v1/driver/routes/{id}/start and /end #

Start route and End route. Send client_id and at (below). Only the first start and the first end count; repeating them is harmless. Both answer the summary: stops, done, failed, open, started, ended and failures ([{id, customer, reason}]). Ending a route marks what it collected as returned.

POST /wc-sibooking/v1/driver/stops/{id} #

A tap on a stop.

FieldNotes
actionRequired: on_the_way, arrived, done (delivered or collected) or failed (couldn’t deliver)
client_id6 to 64 letters, digits, - or _, unique per tap. A tap sent twice with the same id is applied once; the repeat answers the stop with "replayed": true
atWhen it happened, ISO 8601. Used for taps sent late (no signal); a time ahead of the server or older than a week is replaced by now
recipient, signatureFor done: who took it, and the signature as a data:image/png;base64,… URL (up to 250 KB)
reasonFor failed: no_one_home, no_access, wrong_address, refused, vehicle or other
noteUp to 1,000 characters; needed with other
photosFor done or failed: up to 3 data:image/jpeg;base64,… URLs, 1.5 MB each

Answers the stop’s new state: id, status, doneAt, attempts, failReason, recipient and arrived. Each tap adds an order note, and done on a delivery marks the rental sent (see the filter sibooking_driver_moves_stock to turn that off).

ErrorWhen
404 not_foundNo such stop
403 not_your_stopThe stop was moved to another driver’s route (the office wins)
409 already_doneThe stop is already done
400 bad_reason, 400 note_neededNo reason, or other without a note
400 bad_signature, 413 signature_too_big, 400 bad_photoThe signature or a photo isn’t a PNG or JPEG, or is too large

GET /wc-sibooking/v1/driver/stops/{id}/signature and /photos #

The proof of delivery: {"id", "signature"} (a PNG data URL; 404 no_signature when there is none) and {"id", "done": [...], "failed": [...]} (JPEG data URLs). Open to Schedule viewers, dispatchers and the driver who took them; never cached.

PUT /wc-sibooking/v1/driver/routes/{id}/driver #

Gives a route to a driver (dispatchers only): driver, a user id, or 0 for nobody. 400 not_a_driver when that user can’t drive.

Delivery areas and hand-overs #

These need manage_woocommerce.

EndpointWhat it does
GET /wc-sibooking/v1/delivery/checkIs an address delivered to? postcode, address, country, subtotal. Answers delivered, area (id, name, by, km), fee (offered, amount, message), days and message
GET /wc-sibooking/v1/delivery-zonesThe delivery areas. POST adds one
GET, PUT, PATCH, DELETE /wc-sibooking/v1/delivery-zones/{id}One area; fields not sent are kept
GET, PUT /wc-sibooking/v1/settings/deliveryThe Delivery & pickup settings; PUT keeps what isn’t sent and answers settings and warnings
GET /wc-sibooking/v1/handover/waysThe ways a product offers (product_id, optional ship_to): pick-up p, delivery d, transport s, each with its ways back and slots
GET /wc-sibooking/v1/handover/windowsA day’s time slots for a product: product_id, method, date, side (out or back), return_method
PATCH /wc-sibooking/v1/bookings/{id}/handoverChange a booking’s hand-over: method, return_method, window, back_window, return_tracking, force. 409 not_available when the stock no longer fits, unless force

An area has id, name, public_name, postcodes, radius_km, center, location_id, days, window_list, deliver_before, collect_after, day_cap, fee_model, fee, price_table, free_over, min_order, collect_fee, active and position.

Smart Routing #

The route board’s endpoints. Every one takes date (Y-m-d, required) and depot (a location id, default 0). Reading needs sibooking_view_schedule, the rest sibooking_dispatch (shop managers have both).

EndpointWhat it does
GET /siroutes/v1/dayThe day: vehicles (each van with id, name, shift, capacity, features), stops, the saved plan, locks, sent and version
GET /siroutes/v1/changes{"version"}: changes when the day’s stops or saved routes change
POST /siroutes/v1/planPlans the day (Plan routes) without saving. locks keeps stops on a van, first or last, or at a time
POST /siroutes/v1/timeTimes routes you arranged yourself: routes
POST /siroutes/v1/saveAccept plan: saves routes (and locks) to the Schedule. Answers ok, version and the timed plan
POST /siroutes/v1/sendSend to drivers: {"ok": true, "sent": 2, "told": 9, "version"} (told = customers sent their window, when that setting is on). 422 siroutes_nothing_to_send when nothing is saved

routes is a list of {"vehicle": "r12", "stops": ["101", "102"]} (the van’s id from day, the stop ids in driving order). locks is an object by stop id: {"101": {"vehicle": "r12", "position": "first", "time": "09:30"}}, every part optional.

A plan answers method (the planner used), routes, unassigned and totals. Each route has vehicle, used, startHm, endHm, meters, travel, waiting and late (seconds), and stops with job (the stop id), kind, arrivalHm and beginHm. Each unassigned stop has job, reason (capacity, window, shift, features, no_location, lock and so on) and a message to show. plannerNote says why an outside planner fell back to the built-in one.

curl -u "dispatcher:abcd efgh ijkl mnop qrst uvwx" -X POST \
  -H "Content-Type: application/json" \
  -d '{"date":"2026-10-20"}' "$STORE/siroutes/v1/plan"

Hooks #

To react to these events inside WordPress rather than poll, use the hooks: sibooking_driver_stop_action and sibooking_driver_route_action (driver taps), siroutes_plan_saved (Accept plan) and siroutes_routes_sent (Send to drivers).