Skip to Content
Welcome to Zendera Knowledge Hub
For DevelopersRoute Scheduling

Route Scheduling API

v1

Manage route schedules and their bookable intervals, auto-book orders onto matching slots, adjust capacity, and list bookings.

Route scheduling is Zendera’s capacity calendar: a schedule holds intervals — bookable slots, each with a pickup window, a delivery window, a booking cutoff, and a number of available slots — and orders get booked onto them.

Where this fits in your operation

  • Offer real delivery slots in your webshop or customer portal: read the schedule’s intervals, show the ones that match the order, and book the customer’s choice.
  • Maintain the capacity calendar from your planning system: create and update schedules and intervals via the CRUD endpoints instead of clicking them in one by one.
  • React to capacity changes: a vehicle drops out for Thursday — lower that interval’s slot count so no more orders get booked onto it.
  • Reconcile bookings: list bookings per schedule to see which orders landed on which slots.

Interactive API Explorer

Loading API Documentation...

Authentication

Authorization: apikey YOUR_API_KEY_HERE

Base URLs

  • Production: https://app.zenderatms.com/api/
  • Staging: https://staging.zenderatms.com/api/

Key concepts

  • Schedule (RouteSchedule): the container. Tied to a zone area and a freight level set, with a name. intervalCount is computed at read time.
  • Interval (RouteScheduleInterval): one bookable slot. Carries the pickup and delivery windows, a bookBefore cutoff, availableSlots (capacity you set) and bookedSlots (engine-managed, read-only), plus its matching rules: orderTypeIds, freightLevels, fromToZones, and skills.
  • Booking: an order (identified by your external order ID) occupying a slot on an interval.

Note that there are two endpoint families: /v1/route-schedules + /v1/route-schedule-intervals for managing the calendar (CRUD + search), and /route-scheduling/v1/... for operating on it (auto-book, read details, list bookings, adjust availability).

Managing schedules

POST /v1/route-schedules POST /v1/route-schedules/search GET /v1/route-schedules/{routeScheduleId} PUT /v1/route-schedules/{routeScheduleId} DELETE /v1/route-schedules/{routeScheduleId}

Create takes zoneAreaId, freightLevelSetId, and name. Search is page-based (page / perPage, both required) with optional zoneAreaId / freightLevelSetId filters and a searchTerm matched case-insensitively against the name.

Managing intervals

POST /v1/route-schedule-intervals POST /v1/route-schedule-intervals/search GET /v1/route-schedule-intervals/{intervalId} PUT /v1/route-schedule-intervals/{intervalId} DELETE /v1/route-schedule-intervals/{intervalId}

Create example:

{ "routeScheduleId": 7, "pickupEarliest": "2026-06-18T07:00:00Z", "pickupLatest": "2026-06-18T09:00:00Z", "deliveryEarliest": "2026-06-18T10:00:00Z", "deliveryLatest": "2026-06-18T14:00:00Z", "bookBefore": "2026-06-17T12:00:00Z", "availableSlots": 25, "orderTypeIds": [1, 2], "freightLevels": [3], "fromToZones": [{ "fromZone": "OSLO", "toZone": "BERGEN" }], "skills": [] }

Interval search requires routeScheduleId plus page / perPage, with optional pickupFrom / pickupUntil bounds on the interval’s pickupEarliest.

Reading the schedule with its intervals

GET /route-scheduling/v1/schedule-details?intervalsSince=...&intervalsUntil=...

Returns your organization’s schedule — its zoneArea, freightLevelSet, and the intervals whose pickup or delivery window overlaps the requested range. intervalsSince defaults to now, and intervalsUntil defaults to two months after intervalsSince. This is the natural source of interval IDs for a slot picker.

Booking

Auto-book the first matching interval

POST /route-scheduling/v1/schedule-order

{ "externalOrderId": "ERP-001", "orderTypeId": 1, "customerId": 456, "fromZone": "OSLO", "toZone": "BERGEN", "freightLevel": 3 }

Zendera finds an available interval matching the order type, zone pair, and freight level — respecting bookBefore and remaining slots — books the order onto it, and returns the interval’s time window (interval with intervalId and the four window timestamps).

schedule-order is idempotent per externalOrderId. If the order already has a booking, the existing booking is returned instead of creating a new one. To book a specific interval the customer chose, use POST /v2/orders/{orderId}/book-on-interval instead.

Adjust an interval’s capacity

PATCH /route-scheduling/v1/schedule-interval/{scheduleId}/interval/{intervalId}/update-availability

{ "totalSlots": 10 }

Sets the interval’s total slot count (not the remaining count).

List bookings

GET /route-scheduling/v1/bookings?scheduleId=7&since=2026-06-01T00:00:00Z

scheduleId is optional. Each booking carries externalOrderId, scheduleId, scheduleIntervalId, the four window timestamps, and createdAt.

Common gotchas

  • Two endpoint families. Calendar management lives under /v1/route-schedules and /v1/route-schedule-intervals; booking and reading live under /route-scheduling/v1/....
  • schedule-order won’t move an existing booking. Same externalOrderId returns the existing booking — rebooking onto a different slot goes through the Orders API booking endpoints.
  • update-availability takes the new total, not a delta and not the remaining free slots.
  • bookedSlots is read-only. The booking engine maintains it; you control availableSlots.
  • Matching is exact. An order only fits an interval whose orderTypeIds, fromToZones, and freightLevels all match — a failed schedule-order call usually means no interval matches those three, every matching interval is full, or the bookBefore cutoff has passed.
Last updated on