Nova Help

Understand route road calculations

Interpret road times, missing calculations and spending limits without treating unknown driving as zero.

Updated in release 0.0.1 Needs permission from your admin

Read route driving through the Schedule API. The operation reference and required grants are in API reference. Route settings are described in Configure daily route arrangements through the API.

Read driving results

For a technician, request exactly one local working day. Stops, endpoints, commitments, warnings, road legs and totals describe one fingerprint:

GET /v1/schedule/daily-routes/technicians/sres_572986262cb340c2/days/2026-10-03
X-Organization-ID: 1

A leg can have this shape when road access is refused:

{
  "from_uid": "sbook_c01a920b35764987",
  "to_uid": "sbook_218e031e78c64426",
  "departure": "2026-10-03T14:00:00Z",
  "duration_seconds": null,
  "distance_meters": null,
  "quality": "unavailable",
  "reason": "provider_access_denied",
  "encoded_polyline": null
}

route:start and route:finish identify endpoints within this snapshot, not addressable records. A recurrence occurrence uses recur:<parent-uid>:<epoch>. The date is interpreted in the resource's scheduling timezone, with overnight shifts and daylight-saving boundaries. Never connect unrelated days.

Null means unknown. Do not substitute zero for duration, distance or a total. unreachable with no_road_route remains unreachable. Road time and road geometry may be available independently. A missing physical visit stays visible and blocks a complete assessment; a remote commitment still consumes time. The route ignores calendar item-type/search filters and includes all authorized commitments. Restricted work produces an incomplete-day warning, without revealing its customer or location.

Explicit visit flexibility

Read or replace /v1/schedule/daily-routes/visits/{booking_uid}/constraints. A replacement needs expected_version and expected_plan_version from the visit, and the schedule.edit permission. It changes only typed constraints, not appointment times. Exact appointments are fixed unless movable_time is explicitly enabled. keep_time, in-progress/completed work and archived customers keep their times. movable_date requires explicit allowed_dates. Customer availability and existing arrival windows both apply; time_confirmed does not imply customer agreement. An explicit duration has duration_source: "explicit". Resource and dependency references are opaque uids. Cross-type references answer 404; stale edits answer 409.

Calculation quality

  • road: static driving from Google Routes.
  • predicted: traffic-aware driving using that leg's actual departure instant.
  • approximate: explicitly requested straight-line distance with a road allowance and assumed speed. This is not a verified road journey.
  • unavailable: calculation could not be obtained. The reason distinguishes configuration, provider access, temporary errors, calculation limits and spending outcomes.
  • unreachable: no drivable route was returned.

Predicted driving needs a timezone-aware future departure. Historic traffic is unavailable; Nova never silently changes a past departure to now. Static calculations omit departure time. Coordinates must be finite and within geographic bounds, including valid zero coordinates. If the provider uses a static fallback for requested traffic, quality is road with provider_static_fallback; it is not presented as predicted traffic.

When displaying road results outside a Google map, keep Google Maps attribution next to those results. Follow the provider attribution policy.

Provider setup and spending

The server uses its configured Maps or geocoding credential with the Google Routes API enabled. Credential presence alone does not prove access. A Routes access rejection reports provider_access_denied; check the enabled API, billing and key restrictions without exposing the key to a client.

The existing Maps spending governor reserves the full requested matrix rectangle in element units, including any diagonal cells billed in that request. Selected road geometry reserves one request unit. All share the address-lookup daily budget and provider switch. Hold, defer and park outcomes remain unavailable; they do not become failed customer appointments or automatic retries.

One calculation is bounded to 4,000 units and 120 provider requests. Consecutive drives buy adjacent pairs instead of an all-stops square matrix. Exact point, traffic mode and departure matches deduplicate only within that request. Nova no longer stores road results in the obsolete global 30-day travel cache. Render an encoded road polyline when supplied; do not present a straight connecting segment as road directions.

Review daily improvements

POST /api/schedule/route-proposals/improve takes one opaque resource_uid, working_day, and optional exclude_visit_uids. An excluded visit stays in the assessment at its current time. The result names every exact before/after time, assignments, retained customer commitments, expiry and nullable road comparison. It says no_changes when no shorter feasible schedule was found.

{"resource_uid":"sres_a1b2c3d4e5f6a1b2","working_day":"2026-10-06","exclude_visit_uids":[]}

A successful preview carries uid, status: "preview", version: 1, expires_at, changes, and request-only comparisons. Preview does not move appointments or send customer updates. The stored proposal contains business versions and appointment changes, without Google road matrices or geometry. GET /api/schedule/route-proposals/{proposal_uid} reads those exact changes without buying or replaying cached road information.

POST /api/schedule/route-proposals/{proposal_uid}/apply accepts:

{"expected_version":1,"accept_exact_changes":true,"communication_acknowledged":false}

Application rechecks every affected daily snapshot, permissions, canonical work and booking versions and fresh road feasibility. It returns status: "applied" and an advanced version. New bookings, changed availability/settings/locations, expiry and concurrent changes return a conflict requiring a new review. The existing scheduling writers save all accepted changes in one transaction; realtime updates and the existing customer-update process run after commit. Customer-committed changes require explicit review of that communication process.

POST /api/schedule/route-proposals/{proposal_uid}/undo uses the same request shape with the applied version. Undo requires every affected day's post-apply snapshot to remain unchanged; it never overwrites someone else's later edit. The review and undo windows are ten minutes. These operations require the existing scheduling edit permission and preserve work-branch and archived customer policies. Daily improvements hold non-work-order commitments fixed. Recurring visits stay fixed unless their opaque synthetic occurrence UID is explicitly included in allow_occurrence_uids. Selected work uses an aware occurrence_start alongside the parent work-order UID. Apply creates or updates only that child occurrence; other occurrences and the series root remain unchanged.

Place selected work orders

POST /api/schedule/route-proposals/insert compares one work order across explicit person/day scopes. POST /api/schedule/route-proposals/selected plans only the selected work orders across those separate days. Both require schedule.edit and schedule.assign and accept:

{"scopes":[{"resource_uid":"sres_a1b2c3d4e5f6a1b2","working_day":"2026-10-06"}],"work":[{"work_order_uid":"work_order_a1b2c3d4e5f6a1b2","constraints":{}}],"max_added_drive_seconds":1800}

Insertion returns options, each with an expiring proposal UID and the exact person, start and finish. Batch returns one reviewed proposal plus unplaced reasons. Existing unselected appointments stay fixed. A duration comes from the work order or an explicitly labelled override; a service offering is optional. Required people, skills, territory and equipment are checked before an option is recommended. The additional-driving limit hides placements above that limit; unknown driving never means zero. Apply and undo use the same reviewed operations above. A selected work or location change also makes a proposal stale.

POST /api/schedule/daily-routes/summaries accepts a scopes list and returns at most 31 complete person/day summaries. Its entire request shares one governed provider budget and requests no geometry. GET /api/schedule/daily-routes/technicians returns authorized technicians, including an own flag; the matching /technicians/{resource_uid}/days/{day}/revision reads a business fingerprint without buying road estimates.

The service-booking form uses POST /api/schedule/daily-routes/booking-candidates with offering_uid, location_uid, range_start and range_end. It assesses the booking engine's actual opaque assignments and exact duration against the same daily rules. A drive-ranked save carries route_review with resource_uid, working_day and fingerprint; the booking writer preserves that assignment and rechecks the complete day before creating the appointment. Limits are 25 people, 31 dates, 100 candidate appointments and 120 governed road requests per preview. Unsupported travelling assignments and missing road results remain unavailable. The former /travel/suggest-slots operation and its range-based calculation have been removed.

Plan larger selections in the background

POST /api/schedule/route-proposals/jobs takes the selected-work request above and returns HTTP202 with an opaque rjob_... UID. Poll GET /api/schedule/route-proposals/jobs/{job_uid} for queued, running, succeeded, failed, cancelled or expired. A successful job supplies a proposal_uid, unplaced reasons and whether the calculation hit a limit. It creates a reviewable proposal, never appointments. The worker rebuilds current permissions and branch access within the original principal's ceiling.

Use POST /api/schedule/route-proposals/jobs/{job_uid}/cancel when the selection or scope changes. Cancellation stops subsequent candidate/provider work. Jobs expire after ten minutes and have no automatic retry. The maximums are 60 selected work orders, 25 people, 31 dates, 100 person/day routes, 2,000 evaluated placements and twenty seconds of candidate search. Reaching a bound is reported explicitly.

POST /api/schedule/route-proposals/{proposal_uid}/review obtains fresh, request-only road comparisons for the completed proposal. Reading job status or reading a stored proposal does not buy road estimates. Review and apply each recheck current inputs; an old job result cannot override changed appointments. The browser uses background planning for more than five work orders or twenty person/day scopes. API callers can choose background planning directly.

Refresh and offline display

Committed booking, assignment, visit, availability, location and configuration changes publish a privacy-safe Schedule event through the existing Redis transport, including changes made by another backend worker. Read the lightweight revision operation to recover after disconnection without repurchasing unchanged routes. Superseded person/day requests should be cancelled; all query caches need organization, branch, scope, technician and working day.

Offline itineraries must be marked stale and retain only Nova business data. Do not store provider legs, totals, expected finish or geometry in the itinerary cache. Access refusals must never revive an offline copy. The web and Android clients retain these business-only copies for at most 24 hours.

Was this helpful?