<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://docs.motiontools.io/announcements/feed/Changelog.xml" rel="self" type="application/atom+xml" /><link href="https://docs.motiontools.io/announcements/" rel="alternate" type="text/html" /><updated>2026-09-09T05:54:39+00:00</updated><id>https://docs.motiontools.io/announcements/feed/Changelog.xml</id><title type="html">MotionTools API Announcements | Changelog</title><subtitle>This site provides updates about MotionTools API changes and related new features as well as upcoming and past deprecations.</subtitle><entry><title type="html">Optimize large routes without waiting on the request</title><link href="https://docs.motiontools.io/announcements/changelog/2026/09/09/asynchronous-route-optimization.html" rel="alternate" type="text/html" title="Optimize large routes without waiting on the request" /><published>2026-09-09T00:00:00+00:00</published><updated>2026-09-09T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/09/09/asynchronous-route-optimization</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/09/09/asynchronous-route-optimization.html"><![CDATA[<p>Route optimization can now be <strong>submitted</strong> instead of waited on:
<a href="https://docs.motiontools.io/#operation/SubmitRouteOptimization" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization/jobs">Submit a route optimization</a> takes the problem and answers straight away
with a job ID, and <a href="https://docs.motiontools.io/#operation/FetchRouteOptimization" class="openapi-inline" data-tooltip="GET /api/maps/route_optimization/jobs/{job_id}">Fetch a route optimization</a> returns the finished route
once it is ready.</p>

<p>This is what makes large tours optimizable. <a href="https://docs.motiontools.io/#operation/OptimizeRoute" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization">Optimize Route</a> solves the
problem while your request waits, which suits the handful of stops most optimizations
involve — but our routing provider treats solving-while-you-wait as a small-problem
operation and stops it after a few seconds. Past that ceiling the request does not come
back slower, it comes back as an error, however many times you retry it. Submitting the
problem lifts the ceiling instead of raising it: the optimization gets the time it
actually needs.</p>

<h2 id="using-it">Using it</h2>

<p>Submit the same payload you send to <a href="https://docs.motiontools.io/#operation/OptimizeRoute" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization">Optimize Route</a> today. The payload
is validated before the job is accepted, so a malformed request still fails immediately
rather than surfacing later.</p>

<p>To know when the result is ready, subscribe to
<a href="https://docs.motiontools.io/#operation/webhook.maps.route_optimization.completed" class="openapi-inline openapi-inline--webhook" data-tooltip="Published when an asynchronous route optimization has been completed."><code>maps.route_optimization.completed</code></a>. It carries the job ID and
whether the optimization succeeded, so you can fetch the route the moment it is done. If
you would rather not receive webhooks, poll <a href="https://docs.motiontools.io/#operation/FetchRouteOptimization" class="openapi-inline" data-tooltip="GET /api/maps/route_optimization/jobs/{job_id}">Fetch a route optimization</a>
instead: it answers <code class="language-plaintext highlighter-rouge">404</code> until the route is ready. Results can be fetched for 30 minutes
after completion.</p>

<p>What comes back is exactly the payload <a href="https://docs.motiontools.io/#operation/OptimizeRoute" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization">Optimize Route</a> returns — the
stops in optimized order, the totals, the unassigned stops. Only the delivery changes, so
whatever you already do with an optimized route keeps working unchanged.</p>

<h2 id="one-difference-worth-planning-for">One difference worth planning for</h2>

<p>Because the optimization now runs after the request that submitted it, a problem that was
accepted can still fail — for example when one of its existing stops is dispatched into
another tour in the meantime. <a href="https://docs.motiontools.io/#operation/FetchRouteOptimization" class="openapi-inline" data-tooltip="GET /api/maps/route_optimization/jobs/{job_id}">Fetch a route optimization</a> reports that the
same way <a href="https://docs.motiontools.io/#operation/OptimizeRoute" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization">Optimize Route</a> does today, so the error handling you already
have applies.</p>

<p>Small optimizations need no change at all, and are better off as they are:
<a href="https://docs.motiontools.io/#operation/OptimizeRoute" class="openapi-inline" data-tooltip="POST /api/maps/route_optimization">Optimize Route</a> answers a handful of stops in one call, with nothing to
poll or subscribe to. Reach for the asynchronous flow when the problem needs it, not by
default. Large ones, however, have a deadline — see
<a href="/announcements/deprecations/2026/09/09/large-synchronous-route-optimizations.html">the deprecation notice</a>.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Route optimization can now be submitted instead of waited on: Submit a route optimization takes the problem and answers straight away with a job ID, and Fetch a route optimization returns the finished route once it is ready.]]></summary></entry><entry><title type="html">Restrict drivers from going online</title><link href="https://docs.motiontools.io/announcements/changelog/2026/09/09/restrict-drivers-from-going-online.html" rel="alternate" type="text/html" title="Restrict drivers from going online" /><published>2026-09-09T00:00:00+00:00</published><updated>2026-09-09T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/09/09/restrict-drivers-from-going-online</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/09/09/restrict-drivers-from-going-online.html"><![CDATA[<p>You can now stop a driver from going online without blocking their account. A
restricted driver stays signed in and can still reach support and look at their
past tours — they simply cannot go online until the restriction is lifted. Every
restriction carries a reason, names the person who applied it, and is written
into the driver’s notes.</p>

<p>Blocking an account signs the driver out and keeps them signed out. A
restriction is the lighter measure, for the situations that come up day to day:
a vehicle that does not match the account, proof-of-completion photos that keep
coming back unusable, an incident that needs looking into before the driver
takes more work. Those are temporary situations, and taking the driver out of
the pool while keeping their support channel open is usually what resolves them
fastest.</p>

<h3 id="every-restriction-states-its-reason">Every restriction states its reason</h3>

<p><a href="https://docs.motiontools.io/#operation/ListOnlineRestrictionReasons" class="openapi-inline" data-tooltip="GET /api/reasons/online_restriction">List Online Restriction Reasons</a> serves the reasons you can
choose from. They are the same twelve for every operation, translated into the
driver’s language, and the order in the response is the order to display them
in. Four of them — account compliance issue, policy violation, safety incident
and “Other” — carry <code class="language-plaintext highlighter-rouge">note_required: true</code> and need a note of up to 250
characters alongside them; on the rest the note is yours to add or leave out.</p>

<h3 id="applying-and-lifting-a-restriction">Applying and lifting a restriction</h3>

<p><a href="https://docs.motiontools.io/#operation/RestrictDriver" class="openapi-inline" data-tooltip="POST /api/drivers/{id}/online_restriction">Restrict driver from going online</a> applies one,
<a href="https://docs.motiontools.io/#operation/UnrestrictDriver" class="openapi-inline" data-tooltip="DELETE /api/drivers/{id}/online_restriction">Lift driver online restriction</a> lifts it again and clears the reason and
note. The driver payloads from <a href="https://docs.motiontools.io/#operation/ListUsers" class="openapi-inline" data-tooltip="GET /api/users">List Users</a> and
<a href="https://docs.motiontools.io/#operation/ShowUser" class="openapi-inline" data-tooltip="GET /api/users/{id}">Show a user</a> carry an <code class="language-plaintext highlighter-rouge">online_restricted</code> boolean for list
views and an <code class="language-plaintext highlighter-rouge">online_restriction</code> object with the reason, note, timestamp and
the ID of the user who applied it, so a driver list and a driver profile can
both be rendered from what you already fetch.</p>

<p>Restrictions sit next to the account block rather than inside it: a driver can
be restricted, blocked, or both, and the two are lifted independently. To change
the reason on an active restriction, lift it and apply a new one — that way the
history keeps both entries.</p>

<h3 id="work-in-progress-is-finished-not-dropped">Work in progress is finished, not dropped</h3>

<p>Restricting a driver acts on their work immediately. Scheduled tours they had
claimed return to the claimable pool, and the driver gets the same notification
they would get if a dispatcher had unclaimed them. The driver is then sent
offline through the regular offlining, so your integration sees an ordinary
offline event rather than a special case.</p>

<p>A driver who is in the middle of a tour is the exception worth knowing about.
That tour is finished undisturbed — the restriction waits and takes effect the
moment the tour ends, however it ends. Until then the driver cannot claim or
pick up anything new, so no fresh work reaches them in the meantime.</p>

<p>When a restricted driver tries to go online, the request is refused with the
failure code <code class="language-plaintext highlighter-rouge">going_online_restricted</code> and a message naming the reason,
translated into the driver’s language, followed by your note exactly as you
wrote it — for example “Your account has been restricted. Reason: Repeated
delays. Late on six of the last ten tours.” That refusal takes precedence over
anything else that would have blocked them from going online, so the driver is
told about the restriction rather than about a missing capability.</p>

<h3 id="the-history-stays-readable-after-the-fact">The history stays readable after the fact</h3>

<p>Each restriction and each lift writes a note on the driver, so months later it
is still possible to see who restricted them, when, and why — even though
lifting clears the reason from the driver’s payload. The notes are written by
the platform with the <code class="language-plaintext highlighter-rouge">system</code> source, wording the reason in your operation’s
default language, and are readable through <a href="https://docs.motiontools.io/#operation/ListNotes" class="openapi-inline" data-tooltip="GET /api/notes/{resource_type}/{id}">List notes</a>. The
<a href="https://docs.motiontools.io/#tag/Notes" class="openapi-inline openapi-inline--topic">Notes</a> overview covers the rest of that surface, including
who gets to read them.</p>

<h3 id="what-comes-next">What comes next</h3>

<p>Support in our own apps is on its way. In the web dashboard, your team will
apply and lift restrictions from the driver’s profile and see the restricted
state in the drivers list. In the driver app, a restricted driver gets a “You
can’t go online” alert showing the reason together with a Contact support
action.</p>

<p>Until those app versions have rolled out to your fleet, drivers on current
versions see the app’s generic “having issues sending you online” message
instead of the reason you picked, because older apps only recognise one
go-online error. The restriction itself works exactly as described — it is only
the explanation that does not reach the driver yet — so it is worth telling your
dispatch team to expect questions from restricted drivers in the meantime.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[You can now stop a driver from going online without blocking their account. A restricted driver stays signed in and can still reach support and look at their past tours — they simply cannot go online until the restriction is lifted. Every restriction carries a reason, names the person who applied it, and is written into the driver’s notes.]]></summary></entry><entry><title type="html">Notes on the data you work with</title><link href="https://docs.motiontools.io/announcements/changelog/2026/08/26/generic-notes-api.html" rel="alternate" type="text/html" title="Notes on the data you work with" /><published>2026-08-26T00:00:00+00:00</published><updated>2026-08-26T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/08/26/generic-notes-api</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/08/26/generic-notes-api.html"><![CDATA[<p>We have introduced <strong>notes</strong> — free text you can attach to your data, stored
together with the author, the time and where the note was written. A note cannot
be edited or deleted once written.</p>

<p>We are launching notes for <strong>users</strong> first, which covers your drivers,
organization managers, customers and admins. In practice that means:</p>

<ul>
  <li>The dispatcher who called a driver after a missed pickup writes down what was
agreed. Whoever handles that driver next reads it on the driver’s profile
instead of asking around.</li>
  <li>The admin who blocks a driver notes why. Whoever decides later whether to
unblock them reads that on the driver’s profile instead of guessing.</li>
  <li>A note can be addressed to the driver themselves, so a request for missing
paperwork reaches them through your own integration instead of a separate
channel.</li>
</ul>

<p>Until now that context had to go into a metadata field anyone can overwrite, a
spreadsheet, or a chat thread that isn’t connected to the driver at all.</p>

<ul>
  <li><a href="https://docs.motiontools.io/#operation/ListNotes" class="openapi-inline" data-tooltip="GET /api/notes/{resource_type}/{id}">List notes</a> reads the notes on one user, newest first, up to
30 per page, with each note’s author included so you can render a list with
bylines from one request.</li>
  <li><a href="https://docs.motiontools.io/#operation/CreateNote" class="openapi-inline" data-tooltip="POST /api/notes/{resource_type}/{id}">Create a note</a> writes a note.</li>
</ul>

<h3 id="every-note-names-its-audience">Every note names its audience</h3>

<p>When you write a note you list the roles that may read it. A note on a driver
can stay between admins, include the managers of that driver’s organization, or
include the driver — and notes with different audiences sit side by side on the
same driver. Customers are an audience just as much as your staff: a note on a
customer’s own profile that includes their role is something they can read
through your integration. Your own role is always part of the list, so you cannot
write a note you would not be able to read back.</p>

<p>Notes also inherit the access rules of whatever they are attached to: if a user
is not visible to you, neither are their notes.</p>

<h3 id="the-origin-of-a-note-is-recorded-not-claimed">The origin of a note is recorded, not claimed</h3>

<p>Each note stores whether it was written from the dashboard, from the driver app
or through the API. We take that from the request itself rather than from the
payload, so nobody can post a note that claims to come from somewhere else. A
fourth value, <code class="language-plaintext highlighter-rouge">system</code>, marks the notes we take automatically as part of platform
operations — blocking a user, for example — rather than notes a person wrote.</p>

<p>Notes written through the API also keep the <strong>name</strong> of the API token that
created them, so you can still tell which integration wrote a note after that
token has been deleted.</p>

<h3 id="a-paper-trail-for-automated-steps-ours-and-yours">A paper trail for automated steps, ours and yours</h3>

<p>Over time we intend to use notes more widely as a place where our own built-in
functionality can leave an explanation behind. Notes like that carry the <code class="language-plaintext highlighter-rouge">system</code>
source and sit on whatever they concern, alongside the notes your team wrote by
hand.</p>

<p>Your integrations can and should be used the same way. When an automated process
of yours acts on a user — pausing a driver after a failed document check, say —
have it write a note stating what it did and on what grounds.</p>

<h3 id="format-and-limits">Format and limits</h3>

<p>A note’s message is up to 500 characters and supports a limited set of Markdown
features: bold, italic, inline code, code blocks, bulleted lists and <code class="language-plaintext highlighter-rouge">http(s)</code>
links. Anything else — headings, images, tables, raw HTML — comes back as plain
text, and links that are not <code class="language-plaintext highlighter-rouge">http(s)</code> are not clickable.</p>

<p>The message is handed back as HTML that is ready to display, so there is nothing
left to escape on your side.</p>

<p>The <a href="https://docs.motiontools.io/#tag/Notes" class="openapi-inline openapi-inline--topic">Notes</a> overview documents the whole surface, including the
visibility rules and the supported Markdown.</p>

<h3 id="what-comes-next">What comes next</h3>

<p>Notes launch for users. We plan to roll out support for bookings, tours, packages
and other data types in the future. The type is part of the path, so an
integration you write today can pick those up without changing shape.</p>

<p>Notes on bookings are what will make this useful for customer communication: a
note that includes the customer as its audience is a plain way to keep them
posted about their booking, written by hand or by an automated process of yours.
Because the mechanism itself is so simple, it bends to whatever a given operation
needs to communicate, instead of asking for a purpose-built feature per case.</p>

<p>Support in our own apps is planned as well. In the web dashboard, your team will
read and write notes on a user directly, choosing each note’s audience as they
write it, with no integration of your own involved. In the driver app, drivers
will see the notes that were shared with their role — so a note addressed to a
driver reaches them there instead of through a channel you have to build
yourself.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced notes — free text you can attach to your data, stored together with the author, the time and where the note was written. A note cannot be edited or deleted once written.]]></summary></entry><entry><title type="html">Smarter stop grouping: same-destination safeguard and merged content</title><link href="https://docs.motiontools.io/announcements/changelog/2026/08/12/smarter-stop-grouping-rules.html" rel="alternate" type="text/html" title="Smarter stop grouping: same-destination safeguard and merged content" /><published>2026-08-12T00:00:00+00:00</published><updated>2026-08-12T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/08/12/smarter-stop-grouping-rules</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/08/12/smarter-stop-grouping-rules.html"><![CDATA[<p>Grouped stops let a driver handle several stops as one at the roadside: completing the
first stop of a group completes its grouped siblings with it. Two refinements to the
grouping rules now make that behaviour both safer and more flexible — a group only takes
effect when its stops are genuinely at the same destination, and differing custom content
no longer splits a group.</p>

<h2 id="groups-only-apply-at-the-same-destination">Groups only apply at the same destination</h2>

<p>A group now only takes effect when the grouped stops are actually at the same place —
either created from the same place, or sharing the same location-derived
<code class="language-plaintext highlighter-rouge">destination_key</code>. Stops at different locations no longer complete together just because
they carry the same group value.</p>

<p>This protects against a reused group string accidentally tying together stops that have
nothing to do with each other — especially valuable now that groups can be assigned
automatically for stops created from places, or managed in bulk through
<a href="https://docs.motiontools.io/#operation/BulkUpdateStopGroup" class="openapi-inline" data-tooltip="PUT /api/hailing/bookings/{booking_id}/stops/groups">Bulk Update Stop’s Groups</a>.</p>

<h2 id="differing-content-no-longer-splits-a-group">Differing content no longer splits a group</h2>

<p>Previously, stops would only group when their custom content was identical, which forced
integrations to mirror the same content onto every stop of a group. That rule is gone:
grouped stops now complete together regardless of their individual content.</p>

<p>We are currently reworking the active tour display in the driver apps, and as part of
that work grouped stops will be presented as one unit — with the stops’ custom content
merged into a single deduplicated view. This driver app support is rolling out over the
coming weeks.</p>

<p>If you maintain a customization or automation that copies content across grouped stops
purely to keep them groupable, you can retire it once the updated driver apps have
rolled out to your fleet — each stop then keeps its own content, and the platform takes
care of the combined display.</p>

<h2 id="where-to-find-the-full-ruleset">Where to find the full ruleset</h2>

<p>The complete set of grouping rules is now documented in one shared block, rendered
directly on the endpoints where it matters: <a href="https://docs.motiontools.io/#operation/HailingCompleteStop" class="openapi-inline" data-tooltip="POST /api/stops/{stop_id}/complete">Complete stop</a>,
<a href="https://docs.motiontools.io/#operation/HailingFailStop" class="openapi-inline" data-tooltip="POST /api/stops/{stop_id}/fail">Fail stop</a>, <a href="https://docs.motiontools.io/#operation/BulkUpdateStopGroup" class="openapi-inline" data-tooltip="PUT /api/hailing/bookings/{booking_id}/stops/groups">Bulk Update Stop’s Groups</a>,
<a href="https://docs.motiontools.io/#operation/CreateHailingBooking" class="openapi-inline" data-tooltip="POST /api/hailing/bookings">Create a Booking</a>, <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" class="openapi-inline" data-tooltip="POST /api/hailing/tours/{tour_id}/stops">Insert custom stop into existing tour</a>,
<a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" class="openapi-inline" data-tooltip="POST /api/hailing/bookings/{booking_id}/stops">Insert custom stop into existing booking</a> and
<a href="https://docs.motiontools.io/#operation/UpdateStopProperties" class="openapi-inline" data-tooltip="PATCH /api/stops/{stop_id}/properties">Update Stop Properties</a>.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Grouped stops let a driver handle several stops as one at the roadside: completing the first stop of a group completes its grouped siblings with it. Two refinements to the grouping rules now make that behaviour both safer and more flexible — a group only takes effect when its stops are genuinely at the same destination, and differing custom content no longer splits a group.]]></summary></entry><entry><title type="html">A home for reports</title><link href="https://docs.motiontools.io/announcements/changelog/2026/07/22/generic-reports-api.html" rel="alternate" type="text/html" title="A home for reports" /><published>2026-07-22T00:00:00+00:00</published><updated>2026-07-22T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/07/22/generic-reports-api</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/07/22/generic-reports-api.html"><![CDATA[<p>We’ve introduced a <strong>generic reports API</strong> — one reliable place to publish a
generated file and deliver it to exactly the people who should see it. Create a
report, choose its audience, and each recipient can list, open and download it
through the same API, with files kept encrypted at rest and cleaned up
automatically when they expire.</p>

<p>It’s built to be the foundation for reporting across the platform: the place our
own exports are delivered, the foundation we’re building richer reporting on, and
a surface you can use right now to distribute your own reports within your
tenant — a monthly statement to a customer, a compensation summary to a driver,
an operations report to your admins — with no bespoke delivery work on your side.</p>

<h3 id="where-to-start">Where to start</h3>

<p>The full surface and its concepts live under the <a href="https://docs.motiontools.io/#tag/Reports" class="openapi-inline openapi-inline--topic">Reports</a>
tag — visibility grants, the two creation flows, retention and permissions.
Start there if you’re integrating.</p>

<h3 id="publishing-a-report">Publishing a report</h3>

<p>Create a report with <a href="https://docs.motiontools.io/#operation/CreateReport" class="openapi-inline" data-tooltip="POST /api/reports">Create a report</a> in one of two ways:</p>

<ul>
  <li>📎 <strong>Immediately</strong>, by including the file inline — the report is ready to
download straight away. Reach for this when you already have the file.</li>
  <li>⏳ <strong>As a pending announcement</strong>, when the file is still being generated —
create the report first, then finish it with <a href="https://docs.motiontools.io/#operation/CompleteReport" class="openapi-inline" data-tooltip="POST /api/reports/{id}/complete">Complete a report</a>
once the file is ready, or <a href="https://docs.motiontools.io/#operation/FailReport" class="openapi-inline" data-tooltip="POST /api/reports/{id}/fail">Fail a report</a> (with an optional
reason) if generation didn’t work out.</li>
</ul>

<p>Either way the report shows up in the list and on its own detail page, giving
every recipient a durable, always-available place to find it.</p>

<h3 id="sharing-with-exactly-the-right-people">Sharing with exactly the right people</h3>

<p>Every report carries <strong>visibility grants</strong> that decide who can see it — and
that’s the whole story, there is no implicit admin-sees-everything. You can share
a report with:</p>

<ul>
  <li>every admin,</li>
  <li>all managers of a specific organization,</li>
  <li>or a single admin, org manager, customer or driver.</li>
</ul>

<p>Grants combine, so the same report can go to your back office <strong>and</strong> the one
customer it concerns at the same time. This is what makes the API genuinely
self-serving: you decide, per report, precisely who it reaches. Set
<code class="language-plaintext highlighter-rouge">notify_by_email</code> when you create a report and everyone it is shared with gets an
e-mail the moment it becomes ready.</p>

<h3 id="organize-and-filter-with-tags">Organize and filter with tags</h3>

<p>Grants decide who sees a report; <strong>tags</strong> decide how it’s organized. Every report
carries a free-form list of labels you choose, and <a href="https://docs.motiontools.io/#operation/ListReports" class="openapi-inline" data-tooltip="GET /api/reports">List reports</a>
filters by them — each tag you add narrows the results — so the labels become the
axes your recipients navigate by. Pick whatever dimensions matter to you:</p>

<ul>
  <li>a <strong>report type</strong> — <code class="language-plaintext highlighter-rouge">type:compensation</code>, <code class="language-plaintext highlighter-rouge">type:billing</code>, <code class="language-plaintext highlighter-rouge">type:operations</code>,</li>
  <li>a <strong>time period</strong> — <code class="language-plaintext highlighter-rouge">2026-W28</code>, <code class="language-plaintext highlighter-rouge">2026-06</code>,</li>
  <li>a <strong>subject</strong> — <code class="language-plaintext highlighter-rouge">org:1234</code>, <code class="language-plaintext highlighter-rouge">region:eu</code>.</li>
</ul>

<p>And they combine: <code class="language-plaintext highlighter-rouge">type:compensation</code> <strong>plus</strong> <code class="language-plaintext highlighter-rouge">2026-W28</code> returns exactly one
week’s compensation reports. Consistent tags turn a growing pile of reports into
something anyone can find their way around at a glance — with no bespoke filtering
on your side.</p>

<h3 id="coming-soon">Coming soon</h3>

<p>A dedicated <strong>Reports section in the dashboard</strong> is on its way, giving your team a
searchable, filterable view of every report they can see — no API required. The
API described here is available today.</p>

<p>This is also the foundation we’re consolidating reporting onto. The existing custom
reports our customer success team maintains for you will be migrated gradually to
this new platform, and the CSV export features in the web dashboard will soon move
over to it too — so more and more of the reports you already rely on will show up
here, in one consistent place.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateReport" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/reports</span>
        
      </div>
      <div><span class="name">Create a report</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CompleteReport" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/reports/{id}/complete</span>
        
      </div>
      <div><span class="name">Complete a report</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/FailReport" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/reports/{id}/fail</span>
        
      </div>
      <div><span class="name">Fail a report</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListReports" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/reports</span>
        
      </div>
      <div><span class="name">List reports</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowReport" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/reports/{id}</span>
        
      </div>
      <div><span class="name">Show a report</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DownloadReport" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/reports/{id}/download</span>
        
      </div>
      <div><span class="name">Download a report file</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We’ve introduced a generic reports API — one reliable place to publish a generated file and deliver it to exactly the people who should see it. Create a report, choose its audience, and each recipient can list, open and download it through the same API, with files kept encrypted at rest and cleaned up automatically when they expire.]]></summary></entry><entry><title type="html">Automatic stop groups for stops created from places</title><link href="https://docs.motiontools.io/announcements/changelog/2026/07/15/automatic-stop-groups-from-places.html" rel="alternate" type="text/html" title="Automatic stop groups for stops created from places" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/07/15/automatic-stop-groups-from-places</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/07/15/automatic-stop-groups-from-places.html"><![CDATA[<p>Stops created from a place are now <strong>grouped automatically</strong>. When several such stops end
up on the same tour — the classic stacked-tour case of two orders picked up at the same
location — they are recognised as one group and completed together, with no manual grouping
step and no custom integration to maintain.</p>

<h2 id="how-it-works">How it works</h2>

<p>Whenever a stop is created from a place and no group is provided, it receives an automatic
group derived from the stop’s type and the place, of the form <code class="language-plaintext highlighter-rouge">A-&lt;type&gt;-&lt;place_id&gt;</code> (for
example <code class="language-plaintext highlighter-rouge">A-pickup-&lt;place id&gt;</code>). This applies both when creating a booking and when inserting
a custom stop:</p>

<p><a href="https://docs.motiontools.io/#operation/CreateHailingBooking" class="openapi-inline" data-tooltip="POST /api/hailing/bookings">Create a Booking</a>
<a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" class="openapi-inline" data-tooltip="POST /api/hailing/tours/{tour_id}/stops">Insert custom stop into existing tour</a>
<a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" class="openapi-inline" data-tooltip="POST /api/hailing/bookings/{booking_id}/stops">Insert custom stop into existing booking</a></p>

<p>Because two stops built from the <strong>same place with the same type</strong> derive the <strong>same</strong> group,
they line up automatically once they share a tour — and completing the first as a driver
completes the rest of the group, exactly as if the group had been set by hand.</p>

<p>When a stop’s type is later changed via <a href="https://docs.motiontools.io/#operation/UpdateStopProperties" class="openapi-inline" data-tooltip="PATCH /api/stops/{stop_id}/properties">Update Stop Properties</a>, its
automatic group is updated to match the new type, so grouping stays correct as stops are
edited.</p>

<h2 id="your-custom-groups-are-always-respected">Your custom groups are always respected</h2>

<p>A group you provide yourself is never touched: if a stop is created with an explicit group,
that value is kept, and it is never overwritten when the type changes. The leading <code class="language-plaintext highlighter-rouge">A-</code>
prefix is what marks a group as automatically managed — any group without it is treated as
yours to control, through <a href="https://docs.motiontools.io/#operation/BulkUpdateStopGroup" class="openapi-inline" data-tooltip="PUT /api/hailing/bookings/{booking_id}/stops/groups">Bulk Update Stop’s Groups</a> as before.</p>

<p>To accommodate the new format, the maximum length of a stop group has been increased from
40 to 50 characters.</p>

<h2 id="adopting-it-smoothly">Adopting it smoothly</h2>

<p>If you currently assign stop groups yourself — for instance through a customization or an
automation scenario — you can now hand that job to the platform. To roll over without
clobbering the automatic groups, make your integration set a group <strong>only when the stop
does not already have one</strong>, rather than always writing it. Once the automatic grouping is
in place, ordinary stop mirroring keeps groups consistent across the booking and its tour on
its own, and the group-setting customization can be retired.</p>

<h2 id="why-this-matters">Why this matters</h2>

<p>Automatic grouping makes the out-of-the-box behaviour match what operators expect: build
bookings from places, stack them into a tour, and the shared stops group and complete as one
— no extra configuration, and no race between competing integrations trying to set the same
group. It removes a whole class of manual-dispatching and stacking edge cases and cuts the
churn of redundant updates that those integrations used to trigger.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Stops created from a place are now grouped automatically. When several such stops end up on the same tour — the classic stacked-tour case of two orders picked up at the same location — they are recognised as one group and completed together, with no manual grouping step and no custom integration to maintain.]]></summary></entry><entry><title type="html">Choose a recovery outcome when failing a booking stop</title><link href="https://docs.motiontools.io/announcements/changelog/2026/07/15/choose-stop-failure-recovery-outcomes.html" rel="alternate" type="text/html" title="Choose a recovery outcome when failing a booking stop" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/07/15/choose-stop-failure-recovery-outcomes</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/07/15/choose-stop-failure-recovery-outcomes.html"><![CDATA[<p>Failing a stop now answers the question that matters most in the field: <strong>what happens
next?</strong> The fail endpoint accepts a recovery <code class="language-plaintext highlighter-rouge">outcome</code> that turns a failed delivery into
an explicit, auditable next step — send the goods back, try again, or accept the failure —
without juggling manual stop edits or custom integrations.</p>

<h2 id="the-outcomes">The outcomes</h2>

<p><a href="https://docs.motiontools.io/#operation/HailingFailStop" class="openapi-inline" data-tooltip="POST /api/stops/{stop_id}/fail">Fail stop</a> accepts an optional <code class="language-plaintext highlighter-rouge">outcome</code> parameter on tour
stops:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">return_now</code> — appends a <em>return stop</em> to the booking, going back to the pickup’s
address and contact, and dispatches it right onto the tour the stop failed on.</li>
  <li><code class="language-plaintext highlighter-rouge">return_later</code> — appends the return stop without dispatching it, leaving the dispatcher
in control of when and how it goes out.</li>
  <li><code class="language-plaintext highlighter-rouge">reattempt_now</code> — appends a <em>reattempt stop</em>, a full copy of the failed stop, and
dispatches it onto the failing tour for an immediate second attempt.</li>
  <li><code class="language-plaintext highlighter-rouge">reattempt_later</code> — appends the reattempt copy undispatched.</li>
  <li><code class="language-plaintext highlighter-rouge">skip_recovery</code> — the stop stays failed and no recovery stop is created. This is the
default when no outcome is given, so existing integrations keep working unchanged.</li>
</ul>

<p>Recovery stops are regular booking stops: they keep the booking active until they reach an
outcome of their own, and the failed stop stays in place — the booking’s history reflects
every attempt.</p>

<h2 id="choosing-safely">Choosing safely</h2>

<p>Each outcome has pre-conditions — returns require the return stop type and a
pickup-then-drop-off booking shape, “now” variants require the tour to still be active,
and stop limits apply. To offer exactly the recovery choices that apply <em>before</em> making
the call, tour stop payloads (for example on <a href="https://docs.motiontools.io/#operation/ShowHailingBooking" class="openapi-inline" data-tooltip="GET /api/hailing/bookings/{id}">Show Booking</a>)
carry a <code class="language-plaintext highlighter-rouge">failure_options</code> object indicating, per outcome, whether the current user may
select it.</p>

<p>Each entry pairs an <code class="language-plaintext highlighter-rouge">allowed</code> flag with a localized <code class="language-plaintext highlighter-rouge">reason</code> explaining why an outcome is
currently unavailable (<code class="language-plaintext highlighter-rouge">null</code> when it is allowed), ready to be shown to the user as-is:</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nl">"failure_options"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
  </span><span class="nl">"outcomes"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w">
    </span><span class="nl">"skip_recovery"</span><span class="p">:</span><span class="w">   </span><span class="p">{</span><span class="w"> </span><span class="nl">"allowed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">  </span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"reattempt_later"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"allowed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">  </span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"reattempt_now"</span><span class="p">:</span><span class="w">   </span><span class="p">{</span><span class="w"> </span><span class="nl">"allowed"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The tour for this stop is no longer active."</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"return_later"</span><span class="p">:</span><span class="w">    </span><span class="p">{</span><span class="w"> </span><span class="nl">"allowed"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="p">,</span><span class="w">  </span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="p">},</span><span class="w">
    </span><span class="nl">"return_now"</span><span class="p">:</span><span class="w">      </span><span class="p">{</span><span class="w"> </span><span class="nl">"allowed"</span><span class="p">:</span><span class="w"> </span><span class="kc">false</span><span class="p">,</span><span class="w"> </span><span class="nl">"reason"</span><span class="p">:</span><span class="w"> </span><span class="s2">"The tour for this stop is no longer active."</span><span class="w"> </span><span class="p">}</span><span class="w">
  </span><span class="p">}</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>The availability reflects everything that determines an outcome’s fate: the user’s role,
the stop’s status, the tour’s state, service configuration and capacity, and the booking’s
shape. The object renders on tour stops that can currently be failed (<code class="language-plaintext highlighter-rouge">approaching</code> or
<code class="language-plaintext highlighter-rouge">arrived</code>), and only for users that can run stop failure flows: administrators,
organization managers and the tour’s driver.</p>

<p>When a chosen outcome is not available after all, the fail request is rejected as a whole
with a <code class="language-plaintext highlighter-rouge">422</code> naming the reason — the stop is <strong>not</strong> failed in that case. A UI driven by
<code class="language-plaintext highlighter-rouge">failure_options</code> should rarely see these rejections.</p>

<p><code class="language-plaintext highlighter-rouge">failure_options</code> also replaces the boolean <code class="language-plaintext highlighter-rouge">fail</code> indicator inside
<code class="language-plaintext highlighter-rouge">completion_requirements</code>, <a href="/announcements/deprecations/2026/07/15/deprecation-of-completion-requirements-fail-indicator.html">which is now deprecated</a> —
<code class="language-plaintext highlighter-rouge">failure_options.outcomes.skip_recovery.allowed</code> carries the same signal, alongside the
richer per-outcome availability.</p>

<h2 id="webhooks">Webhooks</h2>

<ul>
  <li><a href="https://docs.motiontools.io/#operation/webhook.booking.stop_failed" class="openapi-inline openapi-inline--webhook" data-tooltip="Published when the driver fails the stop. It's driven by the state of the dispatched stop."><code>booking.stop_failed</code></a> now carries the applied <code class="language-plaintext highlighter-rouge">outcome</code>
alongside the <code class="language-plaintext highlighter-rouge">failure_reason</code>, so downstream systems no longer need to diff the
booking’s stop list to learn what recovery was chosen.</li>
  <li>The new <a href="https://docs.motiontools.io/#operation/webhook.booking.return_started" class="openapi-inline openapi-inline--webhook" data-tooltip="Published when a return stop is dispatched into a tour — the booking starts its return leg back to the pickup."><code>booking.return_started</code></a> event fires whenever a
return stop is dispatched into a tour — the moment goods start moving back.</li>
</ul>

<h2 id="why-this-matters">Why this matters</h2>

<p>Together with
<a href="/announcements/changelog/2026/07/01/failed-stops-are-terminal.html">terminal failed stops</a>,
this completes the structured recovery flow: every failure gets an explicit decision, every
attempt is a first-class stop, and both the dashboard and your integrations see the same
availability rules and the same audit trail.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Failing a stop now answers the question that matters most in the field: what happens next? The fail endpoint accepts a recovery outcome that turns a failed delivery into an explicit, auditable next step — send the goods back, try again, or accept the failure — without juggling manual stop edits or custom integrations.]]></summary></entry><entry><title type="html">Organization visibility now follows tour execution</title><link href="https://docs.motiontools.io/announcements/changelog/2026/07/15/organization-visibility-follows-tour-execution.html" rel="alternate" type="text/html" title="Organization visibility now follows tour execution" /><published>2026-07-15T00:00:00+00:00</published><updated>2026-07-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/07/15/organization-visibility-follows-tour-execution</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/07/15/organization-visibility-follows-tour-execution.html"><![CDATA[<p>When several organizations work the same service areas — fleet partners,
3PL sub-fleets, or a mix of your own and external drivers — their managers
should see the work that concerns them, and nothing that doesn’t. The
platform now takes care of that automatically: <strong>from the moment a driver
picks, claims, or is force-assigned a tour, the tour and its bookings are
visible only to the driver’s own organization</strong>, which is also the only
organization receiving their live updates and notifications. No
information leaks between competing organizations while the work is on
the road.</p>

<p>The rest of the lifecycle follows the same principle:</p>

<ul>
  <li>When the driver leaves the tour again (ditch, unclaim, claim-window
expiry, or revocation), the managing organizations regain visibility.</li>
  <li>A tour that completes or gets cancelled with a driver on it stays with
the executing driver’s organization, also in history views — and the
managing organizations you configured are no longer rewritten when a
tour ends, so the list set via
<a href="https://docs.motiontools.io/#operation/HailingBookingUpdateManagingOrganizations" class="openapi-inline" data-tooltip="PUT /api/hailing/bookings/{booking_id}/managing_organizations">Update managing organizations</a> stays
what you set it to.</li>
  <li>Bookings split across several tours are visible to the organizations of
all drivers currently executing them.</li>
  <li>Bookings and tours without managing organizations remain invisible to
every organization manager while staying open to drivers of all
organizations.</li>
</ul>

<p>Previously, this behaviour required custom automation rewriting the
managing organizations during the tour lifecycle; it is now the built-in
default for every tenant, with no configuration needed.</p>

<p>Alongside this change we have thoroughly reworked the
<a href="https://docs.motiontools.io/#tag/Booking-Visibility" class="openapi-inline openapi-inline--topic">Booking &amp; Tour Visibility</a> documentation: it now walks
through who sees what per role, the full lifecycle rules above, what
carries over from bookings to tours on dispatch, and how related features
— <a href="https://docs.motiontools.io/#tag/Linking-Organizations-to-Service-Areas" class="openapi-inline openapi-inline--topic">Linking Organizations to Service Areas</a>, preferred
drivers, and the gradual rollout extension — tie into visibility.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[When several organizations work the same service areas — fleet partners, 3PL sub-fleets, or a mix of your own and external drivers — their managers should see the work that concerns them, and nothing that doesn’t. The platform now takes care of that automatically: from the moment a driver picks, claims, or is force-assigned a tour, the tour and its bookings are visible only to the driver’s own organization, which is also the only organization receiving their live updates and notifications. No information leaks between competing organizations while the work is on the road.]]></summary></entry><entry><title type="html">Failed booking stops are now terminal</title><link href="https://docs.motiontools.io/announcements/changelog/2026/07/01/failed-stops-are-terminal.html" rel="alternate" type="text/html" title="Failed booking stops are now terminal" /><published>2026-07-01T00:00:00+00:00</published><updated>2026-07-01T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/07/01/failed-stops-are-terminal</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/07/01/failed-stops-are-terminal.html"><![CDATA[<p>Failed booking stops are now <strong>terminal</strong>: once a stop is failed, it can no longer be
dispatched again into a tour. A stop’s outcome is now final and auditable — a failed stop
stays failed, and recovery happens by adding a new stop to the booking rather than by
reviving the original one.</p>

<h2 id="what-changes">What changes</h2>

<ul>
  <li>A failed stop can no longer be re-dispatched. Creating a new tour from a failed stop via
<a href="https://docs.motiontools.io/#operation/DispatchStopsIntoTour" class="openapi-inline" data-tooltip="POST /api/hailing/bookings/merge">Dispatch stops into a tour</a> now returns a <code class="language-plaintext highlighter-rouge">422</code> carrying the <code class="language-plaintext highlighter-rouge">failed_stops</code>
failure code, and inserting a failed stop into an existing tour via
<a href="https://docs.motiontools.io/#operation/DispatchStopsIntoExistingTour" class="openapi-inline" data-tooltip="POST /api/hailing/tours/{tour_id}/stops/insert">Dispatch or move stops into existing tour</a> is likewise rejected — rather than moving
the stop back into a tour.</li>
  <li>When every stop on a booking has reached a final outcome — completed or failed — the booking
now completes automatically rather than returning to a dispatchable state. If a stop fails while
the booking still has stops in progress or waiting to be dispatched, the booking simply carries
on with those — a failure no longer pushes the rest of the booking back toward dispatch.</li>
  <li>A failed stop now stays linked to the tour it failed on, rather than being detached from it as
before, so the failure remains traceable to where it happened.</li>
</ul>

<h2 id="what-this-looks-like">What this looks like</h2>

<p>Here’s how the change plays out across the situations you might see in the field:</p>

<table>
  <thead>
    <tr>
      <th>Situation</th>
      <th>Before</th>
      <th>Now</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td>A booking stop fails</td>
      <td>The stop could be sent out again to retry it</td>
      <td>The outcome is final; to retry, you add a new stop to the booking</td>
    </tr>
    <tr>
      <td>Every stop on a booking has finished — completed or failed</td>
      <td>The booking returned to a dispatchable state, waiting to be sent out again</td>
      <td>The booking closes out automatically</td>
    </tr>
    <tr>
      <td>A stop fails while the booking’s other stops are still in progress or waiting</td>
      <td>The failure could push the whole booking back toward dispatch</td>
      <td>The booking carries on with its remaining stops, unaffected</td>
    </tr>
  </tbody>
</table>

<h2 id="why-this-matters">Why this matters</h2>

<p>Making failure terminal gives every booking a single, predictable lifecycle: a stop reaches
an outcome once and keeps it, so the booking’s history reflects exactly what happened in the
field.</p>

<h2 id="whats-next">What’s next</h2>

<p>This is a preparation for upcoming booking recovery flow features. In the next weeks, based on
this foundation, we will introduce structured ways to recover from a failed stop —
<strong>reattempting</strong> a stop and <strong>returning</strong> undelivered goods — as first-class booking stops.
We’ll announce each as it ships.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Failed booking stops are now terminal: once a stop is failed, it can no longer be dispatched again into a tour. A stop’s outcome is now final and auditable — a failed stop stays failed, and recovery happens by adding a new stop to the booking rather than by reviving the original one.]]></summary></entry><entry><title type="html">Top-level places permission flag</title><link href="https://docs.motiontools.io/announcements/changelog/2026/06/24/top-level-places-permission.html" rel="alternate" type="text/html" title="Top-level places permission flag" /><published>2026-06-24T00:00:00+00:00</published><updated>2026-06-24T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/06/24/top-level-places-permission</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/06/24/top-level-places-permission.html"><![CDATA[<p>The permissions endpoint (<code class="language-plaintext highlighter-rouge">GET /api/user/permissions</code>) now reports a top-level <code class="language-plaintext highlighter-rouge">places</code> flag, giving
you a single, role-accurate signal for whether the current user can work with places.</p>

<p>Places availability used to be indicated only under the <code class="language-plaintext highlighter-rouge">admin</code> section. Places launched as an
admin-only feature, so the indicator lived there — but the places API has since been opened up to
other roles. The new top-level flag reflects access for <strong>every</strong> role that can use places, so you
can decide whether to surface places-related actions without special-casing administrators.</p>

<p><strong>What’s available:</strong></p>
<ul>
  <li>A top-level <code class="language-plaintext highlighter-rouge">places</code> flag on the permissions response — a boolean in the default view, and a
per-action object (<code class="language-plaintext highlighter-rouge">index</code>, <code class="language-plaintext highlighter-rouge">show</code>, <code class="language-plaintext highlighter-rouge">create</code>, <code class="language-plaintext highlighter-rouge">update</code>, <code class="language-plaintext highlighter-rouge">destroy</code>, <code class="language-plaintext highlighter-rouge">fork</code>, <code class="language-plaintext highlighter-rouge">metadata</code>) when
requesting detailed permissions.</li>
</ul>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w"> </span><span class="nl">"permissions"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"places"</span><span class="p">:</span><span class="w"> </span><span class="kc">true</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>The admin-bucket <code class="language-plaintext highlighter-rouge">admin.places</code> indicator is deprecated in favour of this top-level flag — see
<a href="/announcements/deprecations/2026/06/24/deprecation-of-admin-places-permission-indicator.html">the deprecation notice</a>.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[The permissions endpoint (GET /api/user/permissions) now reports a top-level places flag, giving you a single, role-accurate signal for whether the current user can work with places.]]></summary></entry><entry><title type="html">Share workforce busyness with place-level webhooks</title><link href="https://docs.motiontools.io/announcements/changelog/2026/06/10/busyness-signals-webhook.html" rel="alternate" type="text/html" title="Share workforce busyness with place-level webhooks" /><published>2026-06-10T00:00:00+00:00</published><updated>2026-06-10T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/06/10/busyness-signals-webhook</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/06/10/busyness-signals-webhook.html"><![CDATA[<p>Our tenants can now share how busy their workforce is, place by place, with their customers — who can
then react automatically, throttling demand or temporarily offlining a merchant when deliveries can no
longer keep up and re-opening it as the workforce catches up.</p>

<p>When the busyness signals extension is enabled, we emit a <code class="language-plaintext highlighter-rouge">busyness.place_changed</code> webhook for an
affected place whenever its busyness shifts to a new level, from 0 (idle) to 100 (fully saturated).</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.busyness.place_changed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">busyness.place_changed</span>
        
      </div>
      <div><span class="name">Notifies that the workforce busyness affecting a specific place has changed to a new bucket.
Use this signal to apply throttling or temporary offlining decisions per place when the workforce
serving it can no longer keep up with demand.

**Availability:** This event is part of a paid extension and is delivered only to tenants who
have it contracted and enabled. To enable busyness signals for your tenant, please contact our
customer success team.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Busyness signals are a paid extension configured per tenant — reach out to our customer success team to
enable them.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Our tenants can now share how busy their workforce is, place by place, with their customers — who can then react automatically, throttling demand or temporarily offlining a merchant when deliveries can no longer keep up and re-opening it as the workforce catches up.]]></summary></entry><entry><title type="html">Automatic tip distribution onto the tour compensation object</title><link href="https://docs.motiontools.io/announcements/changelog/2026/06/03/automatic-tip-distribution.html" rel="alternate" type="text/html" title="Automatic tip distribution onto the tour compensation object" /><published>2026-06-03T00:00:00+00:00</published><updated>2026-06-03T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/06/03/automatic-tip-distribution</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/06/03/automatic-tip-distribution.html"><![CDATA[<p>Tips set on individual bookings now flow automatically onto the <strong>tour
compensation object</strong> when a tour completes — so everything a driver
earned (base earnings, bonuses, and tips) lives in one place instead of
being stitched together after the fact.</p>

<h3 id="why-this-matters">Why this matters</h3>

<p>Tips are set per booking, but drivers are paid per tour. Until now there
was no automatic bridge between the two: tip data sat on bookings while
payout reporting happened at the tour level, leaving operations to
reconcile the two by hand. With automatic tip distribution, a completed
tour’s compensation breakdown carries the tip total directly — visible to
drivers in the app, to operators in the dashboard and API, and to your
server-to-server integrations through the existing compensation webhook.</p>

<h3 id="enabling-it">Enabling it</h3>

<p>Tip distribution is <strong>opt-in per tour service and off by default</strong>, so
nothing changes until you switch it on. Set the tour service’s tip
distribution strategy with <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" class="openapi-inline" data-tooltip="PUT /api/admin/hailing/services/{id}">Update a service</a>
and read it back via <a href="https://docs.motiontools.io/#operation/AdminShowHailingService" class="openapi-inline" data-tooltip="GET /api/admin/hailing/services/{id}">Show a service</a>.
<strong>API support is available now; configuring it from the dashboard is
coming soon.</strong></p>

<h3 id="the-distribution-strategy">The distribution strategy</h3>

<p>The first available strategy, <code class="language-plaintext highlighter-rouge">completed_dropoffs_on_tour</code>, awards a
booking’s tip to the tour where its drop-offs were completed. Bookings
whose drop-offs are split across multiple tours, that still have
unresolved drop-offs, or whose tip currency differs from the tour’s
compensation currency don’t contribute — and a currency mismatch pauses
distribution for that tour and notifies your admins by email. The default
<code class="language-plaintext highlighter-rouge">noop</code> strategy opts out entirely. The <a href="https://docs.motiontools.io/#tag/Services" class="openapi-inline openapi-inline--topic">Services</a> docs
spell out the exact eligibility rules on the strategy field — start there
for the specifics.</p>

<h3 id="where-the-result-shows-up">Where the result shows up</h3>

<p>Once a tour completes, the distributed tip appears in the <code class="language-plaintext highlighter-rouge">tips</code> component
of its compensation breakdown — readable via
<a href="https://docs.motiontools.io/#operation/ShowTourCompensation" class="openapi-inline" data-tooltip="GET /api/tours/{tour_id}/compensation">Get tour compensation</a> and delivered through
<a href="https://docs.motiontools.io/#operation/webhook.tour.compensation_updated" class="openapi-inline openapi-inline--webhook" data-tooltip="Published when a tour's compensation has been updated, debounced over a short quiet window."><code>tour.compensation_updated</code></a>. This fills the tip
slot that the
<a href="/announcements/changelog/2026/05/07/tour-compensation-object.html">tour compensation object</a>
reserved for platform-side population, and builds on
<a href="/announcements/changelog/2026/05/20/booking-tip-currency-validation.html">booking tip currency validation</a>,
which keeps a booking’s tip currency sound before it ever reaches a tour.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Update a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowTourCompensation" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/tours/{tour_id}/compensation</span>
        
      </div>
      <div><span class="name">Get tour compensation</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.compensation_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.compensation_updated</span>
        
      </div>
      <div><span class="name">Published when a tour's compensation has been updated, debounced over a short quiet window.</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Tips set on individual bookings now flow automatically onto the tour compensation object when a tour completes — so everything a driver earned (base earnings, bonuses, and tips) lives in one place instead of being stitched together after the fact.]]></summary></entry><entry><title type="html">Booking tip currency now validated against the booking’s applicable currency</title><link href="https://docs.motiontools.io/announcements/changelog/2026/05/20/booking-tip-currency-validation.html" rel="alternate" type="text/html" title="Booking tip currency now validated against the booking’s applicable currency" /><published>2026-05-20T00:00:00+00:00</published><updated>2026-05-20T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/05/20/booking-tip-currency-validation</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/05/20/booking-tip-currency-validation.html"><![CDATA[<p>When a booking carries a tip, the <code class="language-plaintext highlighter-rouge">tip.currency</code> value is now required to match
the booking’s <strong>applicable currency</strong> — the service area’s <code class="language-plaintext highlighter-rouge">local_currency</code>,
falling back to the tenant’s <code class="language-plaintext highlighter-rouge">base_currency</code>. Tip writes in any other currency
are rejected with a <code class="language-plaintext highlighter-rouge">422</code> and the new <code class="language-plaintext highlighter-rouge">booking_tip_currency_mismatch</code> operation
failure code.</p>

<p>This brings tip currency in line with how tour-level compensation already works,
and is the foundation for the upcoming automatic tip distribution onto the
<a href="/announcements/changelog/2026/05/07/tour-compensation-object.html">tour compensation object</a>:
once mismatched currencies are rejected at the source, the downstream
distribution logic never has to reconcile them mid-tour.</p>

<p>Concretely, a booking in a EUR service area can no longer be created with a
<code class="language-plaintext highlighter-rouge">tip.currency</code> of <code class="language-plaintext highlighter-rouge">USD</code>. Any caller setting a tip — whether through
<a href="https://docs.motiontools.io/#operation/CreateHailingBooking" class="openapi-inline" data-tooltip="POST /api/hailing/bookings">Create a Booking</a> or through one of the integration
ingestion endpoints — must send the same currency that already governs the
booking’s pricing.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[When a booking carries a tip, the tip.currency value is now required to match the booking’s applicable currency — the service area’s local_currency, falling back to the tenant’s base_currency. Tip writes in any other currency are rejected with a 422 and the new booking_tip_currency_mismatch operation failure code.]]></summary></entry><entry><title type="html">Partial updates for active and off-route tour display settings</title><link href="https://docs.motiontools.io/announcements/changelog/2026/05/13/tour-display-partial-updates.html" rel="alternate" type="text/html" title="Partial updates for active and off-route tour display settings" /><published>2026-05-13T00:00:00+00:00</published><updated>2026-05-13T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/05/13/tour-display-partial-updates</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/05/13/tour-display-partial-updates.html"><![CDATA[<p>The driver tour display configuration covers two distinct screens — the off-route view a driver
sees while browsing tours, and the active-tour view they see while working a tour. Operators
typically tune these screens independently: changing only the active-tour earnings label, or only
the off-route metadata layout, without wanting to revisit the rest of the configuration.</p>

<p>The update endpoint now reflects that workflow. <a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" class="openapi-inline" data-tooltip="PATCH /api/admin/driver_experience/tour_display">Update Tour Display Configuration</a> accepts
any subset of the configuration fields, removing the need to send whole configuration on every request.
Omitted fields are left untouched.</p>

<p>The shape of the configuration is unchanged. <a href="https://docs.motiontools.io/#operation/AdminShowTourDisplay" class="openapi-inline" data-tooltip="GET /api/admin/driver_experience/tour_display">Show Tour Display Configuration</a> still
returns the full set of fields, and any single field that you <em>do</em> send is validated exactly as
before. Only the request semantics have moved from “send everything” (aka <code class="language-plaintext highlighter-rouge">PUT</code> semantics) to “send what changed” (aka <code class="language-plaintext highlighter-rouge">PATCH</code> semantics).</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Show Tour Display Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Update Tour Display Configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[The driver tour display configuration covers two distinct screens — the off-route view a driver sees while browsing tours, and the active-tour view they see while working a tour. Operators typically tune these screens independently: changing only the active-tour earnings label, or only the off-route metadata layout, without wanting to revisit the rest of the configuration.]]></summary></entry><entry><title type="html">Tour compensation object</title><link href="https://docs.motiontools.io/announcements/changelog/2026/05/07/tour-compensation-object.html" rel="alternate" type="text/html" title="Tour compensation object" /><published>2026-05-07T00:00:00+00:00</published><updated>2026-05-07T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/05/07/tour-compensation-object</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/05/07/tour-compensation-object.html"><![CDATA[<p>We have introduced a structured <strong>tour compensation</strong> object as the single
source of truth for what a driver is paid out for a tour. It consolidates
base earnings, bonuses, and tips into one auto-totalled view —
exposed via a dedicated API, surfaced to drivers on tour cards via two new
configurable labels, and observable for server-to-server integrations
through a dedicated webhook.</p>

<p>The new object is purpose-built for the kind of compensation logic
3PL operations need: per-component editing, bonus components with
self-provided keys, and a structured breakdown that is accessible to drivers.
It is the foundation to build robust payroll reporting
on top of, and the place to express anything richer than a flat payout
number going forward.</p>

<p>The legacy single-amount <code class="language-plaintext highlighter-rouge">earnings</code> attribute it supersedes is now
<a href="/announcements/deprecations/2026/05/07/tour-earnings-attribute-and-webhook.html">deprecated</a>
and will be removed on <strong>2026-11-06</strong>.</p>

<h3 id="where-to-start">Where to start</h3>

<p>The full surface and its conventions live under the
<a href="https://docs.motiontools.io/#tag/Tour-Compensation" class="openapi-inline openapi-inline--topic">Tour Compensation</a> tag — the tag overview goes
deeper than this announcement on currency rules, idempotency, and how
concurrency is handled. Start there if you’re integrating.</p>

<h3 id="whats-new">What’s new</h3>

<p><strong>A structured object on every tour</strong> — read the current breakdown via
<a href="https://docs.motiontools.io/#operation/ShowTourCompensation" class="openapi-inline" data-tooltip="GET /api/tours/{tour_id}/compensation">Get tour compensation</a>. Three slots, all expressed
in a single tour-wide currency:</p>

<ul>
  <li>💵 <strong>Base earnings</strong> — set with <a href="https://docs.motiontools.io/#operation/SetTourBaseEarnings" class="openapi-inline" data-tooltip="PUT /api/tours/{tour_id}/compensation/base">Set tour base earnings</a>,
cleared with <a href="https://docs.motiontools.io/#operation/DeleteTourBaseEarnings" class="openapi-inline" data-tooltip="DELETE /api/tours/{tour_id}/compensation/base">Delete tour base earnings</a>.</li>
  <li>🎯 <strong>Bonuses</strong> — up to five named incentives, each addressable by a
stable <code class="language-plaintext highlighter-rouge">key</code>. Set with <a href="https://docs.motiontools.io/#operation/SetTourBonus" class="openapi-inline" data-tooltip="PUT /api/tours/{tour_id}/compensation/bonus/{key}">Set tour bonus</a>, cleared
with <a href="https://docs.motiontools.io/#operation/DeleteTourBonus" class="openapi-inline" data-tooltip="DELETE /api/tours/{tour_id}/compensation/bonus/{key}">Delete tour bonus</a>. Bonuses come back sorted
by <code class="language-plaintext highlighter-rouge">key</code> so the order is stable across reads.</li>
  <li>💝 <strong>Tips</strong> — read-only via the API and reserved for platform-side
population. Automatic tip calculation on tour completion, driven by
configurable strategies, is coming soon.</li>
</ul>

<p><code class="language-plaintext highlighter-rouge">total_amount</code> is recomputed automatically whenever any component
changes, and labels + metadata are kept on each component for
human-readable display and audit context.</p>

<p><strong>Bonus-key uniqueness as a built-in safeguard.</strong> A bonus <code class="language-plaintext highlighter-rouge">key</code> is
enforced unique per tour. This is more than a data-model nicety: it
means an accidental retry, a duplicated job, or a re-fired campaign
event can’t double up the same incentive on the same tour. Use this to
your benefit — pick a stable, descriptive key
(<code class="language-plaintext highlighter-rouge">completion_q1</code>, <code class="language-plaintext highlighter-rouge">peak_hours</code>, <code class="language-plaintext highlighter-rouge">late_night</code>) for anything that should
never accidentally stack, and reach for distinct keys when you genuinely
want multiple incentives to coexist on the same tour.</p>

<p><strong>Currency-aware writes.</strong> Every write must include <code class="language-plaintext highlighter-rouge">currency</code>, and the
API rejects any value that doesn’t match the tour’s resolved currency
(the service area’s <code class="language-plaintext highlighter-rouge">local_currency</code>, with fallback to the tenant-wide
<code class="language-plaintext highlighter-rouge">base_currency</code>). This keeps tours that span service areas configured
in different currencies from silently miscalculating.</p>

<p><strong>Concurrency-safe writes.</strong> Per-component writes are idempotent and
last-write-wins. Concurrent edits on the same component resolve via a
<code class="language-plaintext highlighter-rouge">409 Conflict</code> on the losing caller — read back, then retry. Writes to
different components don’t contend and proceed in parallel.</p>

<p><strong>A debounced webhook.</strong> Subscribe to
<a href="https://docs.motiontools.io/#operation/webhook.tour.compensation_updated" class="openapi-inline openapi-inline--webhook" data-tooltip="Published when a tour's compensation has been updated, debounced over a short quiet window."><code>tour.compensation_updated</code></a> to react to
changes. After a compensation component changes, we wait for a
120-second quiet window before firing — any further change on the
same tour resets the timer. When the timer expires, a single webhook
fires with the current state. Bursts of writes (e.g. setting base
earnings + two bonuses in quick succession) collapse into one delivery
that reflects the final state, not each intermediate step. The payload
excludes labels and metadata so subscribers can act on amounts without
round-tripping to our backend.</p>

<p><strong>Driver-app visibility.</strong> Two new configurable labels — <strong>Compensation</strong>
and <strong>Tips</strong> — surface the breakdown directly on the driver’s tour
cards. The Compensation label shows the headline payout (base earnings
plus bonuses, with tips excluded so the number stays stable across the
tour); the Tips label surfaces the tip row separately when one is set.
Both ship with sensible default prefix translations and are configurable
on both the off-route and active-tour displays via
<a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" class="openapi-inline" data-tooltip="PATCH /api/admin/driver_experience/tour_display">Update Tour Display Configuration</a>.</p>

<h3 id="migrating-off-the-legacy-earnings-surface">Migrating off the legacy earnings surface</h3>

<p>The flat <code class="language-plaintext highlighter-rouge">earnings</code> attribute on tours, the
<a href="https://docs.motiontools.io/#operation/UpdateEarnings" class="openapi-inline" data-tooltip="Deprecated PUT /api/hailing/bookings/{booking_id}/earnings">⚠️ Update driver earnings</a> endpoint, and the
<a href="https://docs.motiontools.io/#operation/webhook.tour.earnings_updated" class="openapi-inline openapi-inline--webhook" data-tooltip="Deprecated · Published when the tour's earnings are updated.">⚠️ <code>tour.earnings_updated</code></a> webhook are now
deprecated and will be removed on <strong>2026-11-06</strong>. The new compensation
object is the migration target — see the
<a href="/announcements/deprecations/2026/05/07/tour-earnings-attribute-and-webhook.html">deprecation announcement</a>
for the side-by-side guide. There’s no behavioural change to the legacy
surface within the deprecation window; switch over at your own pace.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowTourCompensation" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/tours/{tour_id}/compensation</span>
        
      </div>
      <div><span class="name">Get tour compensation</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/SetTourBaseEarnings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/tours/{tour_id}/compensation/base</span>
        
      </div>
      <div><span class="name">Set tour base earnings</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DeleteTourBaseEarnings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/tours/{tour_id}/compensation/base</span>
        
      </div>
      <div><span class="name">Delete tour base earnings</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/SetTourBonus" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/tours/{tour_id}/compensation/bonus/{key}</span>
        
      </div>
      <div><span class="name">Set tour bonus</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DeleteTourBonus" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/tours/{tour_id}/compensation/bonus/{key}</span>
        
      </div>
      <div><span class="name">Delete tour bonus</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.compensation_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.compensation_updated</span>
        
      </div>
      <div><span class="name">Published when a tour's compensation has been updated, debounced over a short quiet window.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Update Tour Display Configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a structured tour compensation object as the single source of truth for what a driver is paid out for a tour. It consolidates base earnings, bonuses, and tips into one auto-totalled view — exposed via a dedicated API, surfaced to drivers on tour cards via two new configurable labels, and observable for server-to-server integrations through a dedicated webhook.]]></summary></entry><entry><title type="html">Unified failure reasons API</title><link href="https://docs.motiontools.io/announcements/changelog/2026/04/29/unified-failure-reasons-api.html" rel="alternate" type="text/html" title="Unified failure reasons API" /><published>2026-04-29T00:00:00+00:00</published><updated>2026-04-29T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/04/29/unified-failure-reasons-api</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/04/29/unified-failure-reasons-api.html"><![CDATA[<p>We have introduced a unified reasons API that serves configurable failure reasons across
the platform in a single, consistent format. Two categories are live today — stop
failure reasons and package failure reasons.</p>

<p>This gives operators and integrators one predictable shape to build against: each reason
exposes a stable machine-readable <code class="language-plaintext highlighter-rouge">key</code>, a localised <code class="language-plaintext highlighter-rouge">label</code> suitable for display, the
contexts it applies to, and a <code class="language-plaintext highlighter-rouge">properties</code> bag carrying any category-specific flags.
Clients can now render reason pickers with the same code regardless of the category,
and new reason categories can be added on the server without requiring client changes
to the response shape.</p>

<p><strong>Stop failure reasons</strong> — returned by <code class="language-plaintext highlighter-rouge">GET /api/reasons/stop_failure</code> — are the
predefined reasons a driver can pick from when failing a booking stop. They are sourced
from a platform-maintained catalogue and localised in all supported languages.</p>

<p><strong>Package failure reasons</strong> — returned by <code class="language-plaintext highlighter-rouge">GET /api/reasons/package_failure</code> — are the
tenant-configurable reasons already used at package pickup and delivery. They are the
same reasons previously served by the legacy <code class="language-plaintext highlighter-rouge">GET /api/hailing/failure_reasons</code>
endpoint, now reshaped to fit the unified format. The legacy endpoint continues to work
and is scheduled for removal — see the related deprecation announcement for the field
mapping and migration details.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListStopFailureReasons" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/reasons/stop_failure</span>
        
      </div>
      <div><span class="name">List Stop Failure Reasons</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListPackageFailureReasons" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/reasons/package_failure</span>
        
      </div>
      <div><span class="name">List Package Failure Reasons</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a unified reasons API that serves configurable failure reasons across the platform in a single, consistent format. Two categories are live today — stop failure reasons and package failure reasons.]]></summary></entry><entry><title type="html">Configurable labels for the active tour screen</title><link href="https://docs.motiontools.io/announcements/changelog/2026/04/15/active-tour-labels-configuration.html" rel="alternate" type="text/html" title="Configurable labels for the active tour screen" /><published>2026-04-15T00:00:00+00:00</published><updated>2026-04-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/04/15/active-tour-labels-configuration</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/04/15/active-tour-labels-configuration.html"><![CDATA[<p>Following the <a href="/announcements/changelog/2025/08/13/driver-off-route-tour-display.html">configurable off-route tour display</a>
we introduced last year, we are now extending the same configurability to the <strong>active tour screen</strong> — the view
drivers see while they are actively working on a tour. The configuration is available now via the admin API, and
our mobile apps will receive updates in the upcoming weeks to fully utilize these new options.</p>

<p>The new <code class="language-plaintext highlighter-rouge">active_tour_labels</code> and <code class="language-plaintext highlighter-rouge">active_stop_labels</code> configuration options allow you to control which labels
are shown to drivers during an active tour, using the same label types available for the off-route display:</p>

<ul>
  <li>Priority indicators</li>
  <li>Tour name</li>
  <li>Driver earnings</li>
  <li>Total tour distance</li>
  <li>Custom metadata on tours and stops</li>
  <li>Expected arrival time windows on stops</li>
</ul>

<p>The <code class="language-plaintext highlighter-rouge">scheduled_at</code> label and the <code class="language-plaintext highlighter-rouge">distance_to_first_stop</code> distance variant are not available for active tours,
as they are not relevant once a driver is already en-route.</p>

<p>Configuration is available via the existing tour display admin APIs:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Show Tour Display Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Update Tour Display Configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Following the configurable off-route tour display we introduced last year, we are now extending the same configurability to the active tour screen — the view drivers see while they are actively working on a tour. The configuration is available now via the admin API, and our mobile apps will receive updates in the upcoming weeks to fully utilize these new options.]]></summary></entry><entry><title type="html">Introducing the return stop type</title><link href="https://docs.motiontools.io/announcements/changelog/2026/04/15/return-stop-type.html" rel="alternate" type="text/html" title="Introducing the return stop type" /><published>2026-04-15T00:00:00+00:00</published><updated>2026-04-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/04/15/return-stop-type</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/04/15/return-stop-type.html"><![CDATA[<p>We have introduced <code class="language-plaintext highlighter-rouge">return</code> as a new stop type, enabling return-flow booking patterns where
items are brought back to a designated location after delivery. This extends the existing
stop types (<code class="language-plaintext highlighter-rouge">pickup</code>, <code class="language-plaintext highlighter-rouge">dropoff</code>, <code class="language-plaintext highlighter-rouge">task</code>) with a fourth option that can be used on bookings
and tours.</p>

<h2 id="webhook-events">Webhook events</h2>

<p>The following webhook events now include <code class="language-plaintext highlighter-rouge">stop_type: "return"</code> as a possible value in their
payload. If your integration inspects the <code class="language-plaintext highlighter-rouge">stop_type</code> field, make sure your webhook handlers
accept this new value:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_arrived" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_arrived</span>
        
      </div>
      <div><span class="name">Published when the driver arrives at the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_completed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_completed</span>
        
      </div>
      <div><span class="name">Published when the driver completes the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_failed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_failed</span>
        
      </div>
      <div><span class="name">Published when the driver fails the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<h2 id="service-configuration">Service configuration</h2>

<p>Services can now be configured with return stop settings through the admin API. When <code class="language-plaintext highlighter-rouge">return</code>
is included in a service’s <code class="language-plaintext highlighter-rouge">stop_types</code> array, the following configuration fields become
available:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">return_stop_duration_seconds</code> — expected duration at the return location (default: 300 seconds)</li>
  <li><code class="language-plaintext highlighter-rouge">return_label_translations</code> — customizable label for the return stop in multiple languages</li>
  <li><code class="language-plaintext highlighter-rouge">return_stop_default_maximum_driver_distance_meters</code> — geofencing distance for the return location</li>
  <li><code class="language-plaintext highlighter-rouge">return_stop_default_auto_arrival_distance_meters</code> — distance for automatic arrival marking</li>
</ul>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminHailingServices" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">List Services</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Show a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">Create a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Update a service</span></div>
    </div>
  </a>
</div>

<h2 id="creating-and-managing-return-stops">Creating and managing return stops</h2>

<p>Return stops can be included when creating bookings or inserted into existing tours and bookings.
The stop type on existing stops can also be changed to or from <code class="language-plaintext highlighter-rouge">return</code> via the update stop
properties endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateStopProperties" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/stops/{stop_id}/properties</span>
        
      </div>
      <div><span class="name">Update Stop Properties</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The public service listing also reflects whether <code class="language-plaintext highlighter-rouge">return</code> is enabled as a stop type:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/HailingServices" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/services</span>
        
      </div>
      <div><span class="name">Services configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced return as a new stop type, enabling return-flow booking patterns where items are brought back to a designated location after delivery. This extends the existing stop types (pickup, dropoff, task) with a fourth option that can be used on bookings and tours.]]></summary></entry><entry><title type="html">Simplifying service selection with service_key</title><link href="https://docs.motiontools.io/announcements/changelog/2026/04/09/service-key-as-alternative-to-service-id.html" rel="alternate" type="text/html" title="Simplifying service selection with service_key" /><published>2026-04-09T00:00:00+00:00</published><updated>2026-04-09T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/04/09/service-key-as-alternative-to-service-id</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/04/09/service-key-as-alternative-to-service-id.html"><![CDATA[<p>All booking and tour creation endpoints now accept an optional <code class="language-plaintext highlighter-rouge">service_key</code> parameter as a
more stable, human-readable alternative to <code class="language-plaintext highlighter-rouge">service_id</code> for selecting a hailing service.</p>

<p>Unlike UUIDs, service keys are immutable, descriptive identifiers (e.g., <code class="language-plaintext highlighter-rouge">default</code>, <code class="language-plaintext highlighter-rouge">express</code>)
that stay stable across different tenants and between test and production environments —
no need to look up the exact UUID for a specific service on each tenant. We recommend
using <code class="language-plaintext highlighter-rouge">service_key</code> for new integrations where possible.</p>

<p>The <code class="language-plaintext highlighter-rouge">service</code> object in booking responses now includes a <code class="language-plaintext highlighter-rouge">key</code> field alongside the existing <code class="language-plaintext highlighter-rouge">id</code>,
and you can discover all available service keys via the Services configuration endpoint.</p>

<p><strong>Important:</strong> <code class="language-plaintext highlighter-rouge">service_id</code> and <code class="language-plaintext highlighter-rouge">service_key</code> cannot be combined in the same request. If both
are provided, a validation error will be returned. When neither is given, the tenant’s default
service is used — this behavior is unchanged.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/HailingPriceQuery" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/price</span>
        
      </div>
      <div><span class="name">Price Query</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/HailingConfig" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/config</span>
        
      </div>
      <div><span class="name">Bookings configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateEmptyTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours</span>
        
      </div>
      <div><span class="name">Create Empty Tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DispatchStopsIntoTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/merge</span>
        
      </div>
      <div><span class="name">Dispatch stops into a tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreatePackagePickupTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/package_tours/pickup</span>
        
      </div>
      <div><span class="name">Create package pickup tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreatePackageDropoffTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/package_tours/dropoff</span>
        
      </div>
      <div><span class="name">Create package dropoff tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/PackageDropoffToursAutoPlan" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/package_tours/dropoff/automatic_plan</span>
        
      </div>
      <div><span class="name">Automatically plan package dropoff tours</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings/{id}</span>
        
      </div>
      <div><span class="name">Show Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/HailingServices" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/services</span>
        
      </div>
      <div><span class="name">Services configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[All booking and tour creation endpoints now accept an optional service_key parameter as a more stable, human-readable alternative to service_id for selecting a hailing service.]]></summary></entry><entry><title type="html">Aligning fields and codes terminology for bookings and tours</title><link href="https://docs.motiontools.io/announcements/changelog/2026/03/11/aligning-fields-and-codes-terminology-for-bookings-and-tours.html" rel="alternate" type="text/html" title="Aligning fields and codes terminology for bookings and tours" /><published>2026-03-11T00:00:00+00:00</published><updated>2026-03-11T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/03/11/aligning-fields-and-codes-terminology-for-bookings-and-tours</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/03/11/aligning-fields-and-codes-terminology-for-bookings-and-tours.html"><![CDATA[<p>As part of the ongoing transition from booking to tour terminology, the following changes have been made:</p>

<p><strong>New <code class="language-plaintext highlighter-rouge">active_tour_id</code> field</strong></p>

<p>A new <code class="language-plaintext highlighter-rouge">active_tour_id</code> field is now available on the Users endpoint when the returned user is a driver. It’s a nullable field representing the driver’s current active tour and it’s a replacement for the <code class="language-plaintext highlighter-rouge">active_hailing_booking_ids</code> array field, which is now deprecated.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListUsers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/users</span>
        
      </div>
      <div><span class="name">List Users</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowUser" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/users/{id}</span>
        
      </div>
      <div><span class="name">Show a user</span></div>
    </div>
  </a>
</div>

<hr />

<p><strong>⚠️ Breaking Change - Failure code renames ⚠️</strong></p>

<p>The following failure codes have been renamed:</p>

<ul>
  <li>The <code class="language-plaintext highlighter-rouge">active_driver_on_a_booking</code> failure code returned by the Block User endpoint has been renamed to <code class="language-plaintext highlighter-rouge">active_driver_on_a_tour</code>.</li>
  <li>The <code class="language-plaintext highlighter-rouge">on_active_booking</code> failure code returned by Send Driver Offline endpoint has been renamed to <code class="language-plaintext highlighter-rouge">on_active_tour</code>.</li>
</ul>

<p>If your integration handles these specific failure codes, please update accordingly.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/BlockUser" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/users/{id}/block</span>
        
      </div>
      <div><span class="name">Block user</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/SendDriverOffline" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/users/{id}/online_status</span>
        
      </div>
      <div><span class="name">Send Driver offline</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[As part of the ongoing transition from booking to tour terminology, the following changes have been made:]]></summary></entry><entry><title type="html">New verification content type for stops</title><link href="https://docs.motiontools.io/announcements/changelog/2026/03/11/verification-stop-content.html" rel="alternate" type="text/html" title="New verification content type for stops" /><published>2026-03-11T00:00:00+00:00</published><updated>2026-03-11T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/03/11/verification-stop-content</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/03/11/verification-stop-content.html"><![CDATA[<p>We have introduced a new <code class="language-plaintext highlighter-rouge">verification</code> content type for stops that enables client-side
verification workflows, such as verifying a recipient’s date of birth or entering a PIN code.</p>

<p>The verification value is provided as an <a href="https://datatracker.ietf.org/doc/html/rfc9106">argon2id</a>
hash. The backend only validates that the value is a structurally valid argon2id hash — it never
sees the plaintext. The driver app collects input from the recipient and verifies it locally
against the hash.</p>

<p><strong>Important:</strong> While hashing obscures the plain text, it does <strong>not</strong> keep the value secret.
Values with small problem spaces — such as birth dates (~37,000 possible values in the last
100 years) or short numeric PIN codes — can still be brute-forced. Argon2id makes this
computationally harder, but these values should not be considered secret.</p>

<p>The choice of argon2id parameters is up to the requestor. The
<a href="https://www.rfc-editor.org/rfc/rfc9106.html#section-4-6.1">RFC 9106 “first recommended” configuration</a>
is a good starting point.</p>

<p>When using the <code class="language-plaintext highlighter-rouge">date</code> value type, the date must be formatted as <code class="language-plaintext highlighter-rouge">YYYY-MM-DD</code>
(<a href="https://en.wikipedia.org/wiki/ISO_8601">ISO 8601</a> calendar date) before hashing with argon2id.</p>

<p>This new content type can be used when creating or updating stops:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateHailingStopContent" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/stops/{stop_id}/content</span>
        
      </div>
      <div><span class="name">Update Custom Content</span></div>
    </div>
  </a>
</div>

<p><strong>Data retention:</strong> Once a booking or tour is operationally completed (reaches <code class="language-plaintext highlighter-rouge">done</code>, <code class="language-plaintext highlighter-rouge">paid</code>,
or <code class="language-plaintext highlighter-rouge">cancelled</code> state), all verification content values are automatically anonymized. The
<code class="language-plaintext highlighter-rouge">value</code> field is replaced with a random argon2id hash. The content item itself is preserved as
a record that verification was requested.</p>

<h2 id="instruction-templates-with-variables">Instruction templates with variables</h2>

<p><a href="/announcements/changelog/2025/09/10/stop-instructions.html">Stop instructions</a> provide a convenient way to add
common tasks at stops without having to provide the full custom content schema payload. You can see
available instruction templates via the dedicated endpoint:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListAvailableInstructions" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/stops/available_instructions</span>
        
      </div>
      <div><span class="name">List available stop instructions</span></div>
    </div>
  </a>
</div>

<p>Two new instruction templates are now available that use verification content with dynamic variables:</p>

<ul>
  <li><strong><code class="language-plaintext highlighter-rouge">birthday_verification</code></strong> — requires a <code class="language-plaintext highlighter-rouge">birthdate_argon2id</code> variable (the recipient’s date of birth, hashed with argon2id)</li>
  <li><strong><code class="language-plaintext highlighter-rouge">pin_code_verification</code></strong> — requires a <code class="language-plaintext highlighter-rouge">code_argon2id</code> variable (a delivery PIN code, hashed with argon2id)</li>
</ul>

<p>Instructions can now be passed as objects with a <code class="language-plaintext highlighter-rouge">key</code> and <code class="language-plaintext highlighter-rouge">variables</code> field, in addition to the existing
plain string format. Existing plain-string instructions continue to work unchanged.</p>

<div class="language-json highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">{</span><span class="w">
  </span><span class="nl">"instructions"</span><span class="p">:</span><span class="w"> </span><span class="p">[</span><span class="w">
    </span><span class="p">{</span><span class="w"> </span><span class="nl">"key"</span><span class="p">:</span><span class="w"> </span><span class="s2">"birthday_verification"</span><span class="p">,</span><span class="w"> </span><span class="nl">"variables"</span><span class="p">:</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="nl">"birthdate_argon2id"</span><span class="p">:</span><span class="w"> </span><span class="s2">"$argon2id$..."</span><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="p">}</span><span class="w">
  </span><span class="p">]</span><span class="w">
</span><span class="p">}</span><span class="w">
</span></code></pre></div></div>

<p>Each template’s required variables and their schemas can be introspected via the <code class="language-plaintext highlighter-rouge">variables_schema</code> field
on the list available instructions endpoint shown above.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a new verification content type for stops that enables client-side verification workflows, such as verifying a recipient’s date of birth or entering a PIN code.]]></summary></entry><entry><title type="html">Organization managers can now specify target organization for invitations</title><link href="https://docs.motiontools.io/announcements/changelog/2026/02/12/org-manager-organization-selection.html" rel="alternate" type="text/html" title="Organization managers can now specify target organization for invitations" /><published>2026-02-12T00:00:00+00:00</published><updated>2026-02-12T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/02/12/org-manager-organization-selection</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/02/12/org-manager-organization-selection.html"><![CDATA[<p>Organization managers with multiple managed organizations can now specify which organization to invite drivers to by providing the <code class="language-plaintext highlighter-rouge">organization_id</code> parameter in the invitation request.</p>

<p>Previously, invited users were always assigned to the organization manager’s first managed organization. Now, organization managers can choose the target organization from their managed organizations list.</p>

<p>If no <code class="language-plaintext highlighter-rouge">organization_id</code> is provided, the behavior remains unchanged—the invited user defaults to the organization manager’s first managed organization.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InviteUsers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/users/invite</span>
        
      </div>
      <div><span class="name">Invite users</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Organization managers with multiple managed organizations can now specify which organization to invite drivers to by providing the organization_id parameter in the invitation request.]]></summary></entry><entry><title type="html">booking.in_progress now fires when dispatching into en route tours</title><link href="https://docs.motiontools.io/announcements/changelog/2026/02/04/booking-in-progress-for-mid-tour-dispatch.html" rel="alternate" type="text/html" title="booking.in_progress now fires when dispatching into en route tours" /><published>2026-02-04T00:00:00+00:00</published><updated>2026-02-04T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/02/04/booking-in-progress-for-mid-tour-dispatch</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/02/04/booking-in-progress-for-mid-tour-dispatch.html"><![CDATA[<p>We have enhanced the <code class="language-plaintext highlighter-rouge">booking.in_progress</code> webhook to fire not only when a tour
initially transitions to <code class="language-plaintext highlighter-rouge">en_route</code>, but also when bookings are dispatched into
a tour that is already in progress via the DispatchStopsIntoExistingTour
endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DispatchStopsIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops/insert</span>
        
      </div>
      <div><span class="name">Dispatch or move stops into existing tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.in_progress" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.in_progress</span>
        
      </div>
      <div><span class="name">Published when a tour that the booking's stops are dispatched to is started. Beware that in rare cases, the driver_location may be unavailable and therefore null.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>This ensures that integrations relying on this webhook receive consistent
notifications for all bookings, regardless of whether they were part of the
tour from the start or were added mid-route.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have enhanced the booking.in_progress webhook to fire not only when a tour initially transitions to en_route, but also when bookings are dispatched into a tour that is already in progress via the DispatchStopsIntoExistingTour endpoint.]]></summary></entry><entry><title type="html">Updated error response for User Invites endpoint</title><link href="https://docs.motiontools.io/announcements/changelog/2026/01/14/user-invites-update-error-response.html" rel="alternate" type="text/html" title="Updated error response for User Invites endpoint" /><published>2026-01-14T00:00:00+00:00</published><updated>2026-01-14T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2026/01/14/user-invites-update-error-response</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2026/01/14/user-invites-update-error-response.html"><![CDATA[<p>An adjustment has been made to the User Invites endpoint’s validation error response: when an invitation that specifies
components for the SSO setup (<code class="language-plaintext highlighter-rouge">external_id</code> and <code class="language-plaintext highlighter-rouge">auth_provider_key</code>) fails, the returned error messages for the index
for which they failed won’t be wrapped in the array anymore:</p>

<ul>
  <li>Old response: <code class="language-plaintext highlighter-rouge">collection_errors: { "2": [{ external_id: ["has already been taken"] }] }</code></li>
  <li>New response: <code class="language-plaintext highlighter-rouge">collection_errors: { "2": { external_id: ["has already been taken"] } }</code></li>
</ul>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InviteUsers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/users/invite</span>
        
      </div>
      <div><span class="name">Invite users</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[An adjustment has been made to the User Invites endpoint’s validation error response: when an invitation that specifies components for the SSO setup (external_id and auth_provider_key) fails, the returned error messages for the index for which they failed won’t be wrapped in the array anymore:]]></summary></entry><entry><title type="html">Dedicated preferred drivers endpoints</title><link href="https://docs.motiontools.io/announcements/changelog/2025/11/19/dedicated-preferred-drivers-endpoints.html" rel="alternate" type="text/html" title="Dedicated preferred drivers endpoints" /><published>2025-11-19T00:00:00+00:00</published><updated>2025-11-19T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/11/19/dedicated-preferred-drivers-endpoints</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/11/19/dedicated-preferred-drivers-endpoints.html"><![CDATA[<p>In an effort to further minimize the <code class="language-plaintext highlighter-rouge">minimal</code> tour/booking view, we have introduced dedicated endpoints for fetching
preferred drivers and related flags for tours/bookings.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TourPreferredDrivers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/tours/{id}/preferred_drivers</span>
        
      </div>
      <div><span class="name">Get preferred drivers info</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/BookingPreferredDrivers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/bookings/{id}/preferred_drivers</span>
        
      </div>
      <div><span class="name">Get preferred drivers info</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>To keep things consistent, we’ve moved the endpoint for setting preferred drivers to be in the <code class="language-plaintext highlighter-rouge">tours</code> and <code class="language-plaintext highlighter-rouge">bookings</code>
namespace, deprecating the existing endpoint that is under the <code class="language-plaintext highlighter-rouge">hailing_bookings</code> namespace.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TourAddPreferredDrivers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/tours/{id}/preferred_drivers</span>
        
      </div>
      <div><span class="name">Set preferred drivers</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/BookingAddPreferredDrivers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/bookings/{id}/preferred_drivers</span>
        
      </div>
      <div><span class="name">Set preferred drivers</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[In an effort to further minimize the minimal tour/booking view, we have introduced dedicated endpoints for fetching preferred drivers and related flags for tours/bookings.]]></summary></entry><entry><title type="html">Simplified organization manager booking &amp;amp; tour visibility rules</title><link href="https://docs.motiontools.io/announcements/changelog/2025/11/12/org-managers-visibility-scope-changed.html" rel="alternate" type="text/html" title="Simplified organization manager booking &amp;amp; tour visibility rules" /><published>2025-11-12T00:00:00+00:00</published><updated>2025-11-12T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/11/12/org-managers-visibility-scope-changed</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/11/12/org-managers-visibility-scope-changed.html"><![CDATA[<p>We have simplified the rules regarding visibility of bookings and tours
for the <code class="language-plaintext highlighter-rouge">org_manager</code> role and completely base it off the managing organizations
that are set on the bookings/tours from now on.</p>

<p>Before, this was a combination of preferred drivers on a tour, managing organizations
and a driver from an organization having accepted a tour. This was a bit hard to see through
in different operational scenarios and hence was leading to confusion, which we intend
to address by having just one, simple and transparent rule for the visibility going forward.</p>

<p>This means that if you want to show a booking or a tour to a certain organization,
you will have to set that organization as one of the managing organization.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/HailingBookingUpdateManagingOrganizations" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/hailing/bookings/{booking_id}/managing_organizations</span>
        
      </div>
      <div><span class="name">Update managing organizations</span></div>
    </div>
  </a>
</div>

<p>Previously, we would base the visibility rule also off the pending driver requests,
as well as off the current tour’s driver’s organization.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have simplified the rules regarding visibility of bookings and tours for the org_manager role and completely base it off the managing organizations that are set on the bookings/tours from now on.]]></summary></entry><entry><title type="html">Easier integration of Places with external systems</title><link href="https://docs.motiontools.io/announcements/changelog/2025/10/29/easier-place-integration-with-external-systems.html" rel="alternate" type="text/html" title="Easier integration of Places with external systems" /><published>2025-10-29T00:00:00+00:00</published><updated>2025-10-29T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/10/29/easier-place-integration-with-external-systems</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/10/29/easier-place-integration-with-external-systems.html"><![CDATA[<p>We have introduced an optional <code class="language-plaintext highlighter-rouge">external_id</code> attribute on places.
This gives you additional capabilities in synchronizing another, 
leading system with the booking and places data in MotionTools.</p>

<p>When creating a place, you can now pass an optional <code class="language-plaintext highlighter-rouge">external_id</code> 
string. You would normally set this to the ID of that location in 
your source system.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreatePlace" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/places</span>
        
      </div>
      <div><span class="name">Create a new place</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>In contrast to other, location-specific attributes that require to 
fork a place instead of updating in place to avoid impacting 
historical transactional data, you can update the <code class="language-plaintext highlighter-rouge">external_id</code> in 
place (and also via Fork)</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdatePlace" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/places/{id}</span>
        
      </div>
      <div><span class="name">Update a place</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ForkPlace" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/places/{id}/fork</span>
        
      </div>
      <div><span class="name">Fork a place</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The <code class="language-plaintext highlighter-rouge">external_id</code> becomes indexed by our search index so you can
search by it, and you can also use it as a filter on the list 
endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListPlaces" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/places</span>
        
      </div>
      <div><span class="name">List all places</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>This functionality becomes particularily useful if you combine it
with the <strong>newly extended corresponding <code class="language-plaintext highlighter-rouge">external_id</code> functionality 
when creating bookings</strong>.</p>

<p>When you <strong>create a booking</strong>, you can pass an <code class="language-plaintext highlighter-rouge">external_id</code> 
alongside each stop’s attributes. When given, we will <strong>look up the 
most recently created, non-archived place that belongs to the same 
customer and assign that to the stop</strong>.</p>

<p>When such a place <strong>does not yet exist</strong>, we will <strong>automatically 
create it instead</strong> using the address data given, and on the next 
booking creation it will be re-used as described above.</p>

<p>Please note that we <strong>do not update a previously created, matching
place</strong>. If you want to update the location address data of a place,
in our system that is handled as a new place via the fork mechanism,
to keep historical transactional records correct.</p>

<p>You have <strong>three options if you want to ensure changed location data
get propagated into a place</strong>:</p>

<ul>
  <li>Change the <code class="language-plaintext highlighter-rouge">external_id</code> on your side based on the new location</li>
  <li>Remove the <code class="language-plaintext highlighter-rouge">external_id</code> on existing places with old location data</li>
  <li>Archive existing places with the same <code class="language-plaintext highlighter-rouge">external_id</code></li>
</ul>

<p><strong>Any of these will trigger a new place to be created on the next
booking creation event</strong> based on the location data given on the 
stop at the time. You can also omit latitude &amp; longitude if you want
to utilize our Geocoding features when you do not have GPS 
coordinates for your location in your system.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The same functionality is also available on the endpoints for
adding individual stops into existing bookings and tours:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing tour</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced an optional external_id attribute on places. This gives you additional capabilities in synchronizing another, leading system with the booking and places data in MotionTools.]]></summary></entry><entry><title type="html">New booking lifecycle webhooks</title><link href="https://docs.motiontools.io/announcements/changelog/2025/10/29/new-booking-lifecycle-webhooks.html" rel="alternate" type="text/html" title="New booking lifecycle webhooks" /><published>2025-10-29T00:00:00+00:00</published><updated>2025-10-29T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/10/29/new-booking-lifecycle-webhooks</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/10/29/new-booking-lifecycle-webhooks.html"><![CDATA[<p>We have introduced new booking lifecycle webhooks to gain more transparency into their execution via the tours.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.in_progress" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.in_progress</span>
        
      </div>
      <div><span class="name">Published when a tour that the booking's stops are dispatched to is started. Beware that in rare cases, the driver_location may be unavailable and therefore null.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.driver_location_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.driver_location_updated</span>
        
      </div>
      <div><span class="name">Published when the location of the tour's driver, that the booking's stops are dispatched to, is updated.
Requires a `customer_id` filter on the webhook subscription — webhooks without this filter will not
receive any events.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Together with the new booking lifecycle events, we’ve added new booking’s stop lifecycle event webhooks.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_arrived" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_arrived</span>
        
      </div>
      <div><span class="name">Published when the driver arrives at the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_completed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_completed</span>
        
      </div>
      <div><span class="name">Published when the driver completes the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_failed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_failed</span>
        
      </div>
      <div><span class="name">Published when the driver fails the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Additionally, we’ve enriched the existing <code class="language-plaintext highlighter-rouge">booking.etas_recalculated</code> webhook with the customer ID property, as well
as the ETA info regarding the next 10 unfinished stops.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.etas_recalculated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.etas_recalculated</span>
        
      </div>
      <div><span class="name">Published when the ETAs for the booking's stops have been recalculated.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The publication of these webhooks is based off on the lifecycle of the underlying tour(s) and their stops
used to complete the booking.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced new booking lifecycle webhooks to gain more transparency into their execution via the tours.]]></summary></entry><entry><title type="html">Booking and tour notifications now contain the service_area_id</title><link href="https://docs.motiontools.io/announcements/changelog/2025/10/29/service_area_id-in-booking-and-tour-notifications.html" rel="alternate" type="text/html" title="Booking and tour notifications now contain the service_area_id" /><published>2025-10-29T00:00:00+00:00</published><updated>2025-10-29T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/10/29/service_area_id-in-booking-and-tour-notifications</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/10/29/service_area_id-in-booking-and-tour-notifications.html"><![CDATA[<p>We have extended our existing booking and tour webhook 
notifications to always include the related <code class="language-plaintext highlighter-rouge">service_area_id</code> as 
well.</p>

<p>This can also be used with our webhook filtering feature to
narrow down certain notifications to specific service areas, for 
example if you want to roll out an integration only gradually
across certain service areas.</p>

<p>The updated messages are the following:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.driver_location_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.driver_location_updated</span>
        
      </div>
      <div><span class="name">Published when the location of the tour's driver, that the booking's stops are dispatched to, is updated.
Requires a `customer_id` filter on the webhook subscription — webhooks without this filter will not
receive any events.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.etas_recalculated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.etas_recalculated</span>
        
      </div>
      <div><span class="name">Published when the ETAs for the booking's stops have been recalculated.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.in_progress" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.in_progress</span>
        
      </div>
      <div><span class="name">Published when a tour that the booking's stops are dispatched to is started. Beware that in rare cases, the driver_location may be unavailable and therefore null.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.modified" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.modified</span>
        
      </div>
      <div><span class="name">Published when some part of booking is modified, e.g. when stops are changed.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.route_changed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.route_changed</span>
        
      </div>
      <div><span class="name">Published when the route of a booking has changed, i.e. by adding or removing stops, changing
their locations, changing their order and so on.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_arrived" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_arrived</span>
        
      </div>
      <div><span class="name">Published when the driver arrives at the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_completed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_completed</span>
        
      </div>
      <div><span class="name">Published when the driver completes the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.stop_failed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.stop_failed</span>
        
      </div>
      <div><span class="name">Published when the driver fails the stop. It's driven by the state of the dispatched stop.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.active_status_changed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.active_status_changed</span>
        
      </div>
      <div><span class="name">Notifies drivers about change of active status of a tour.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.earnings_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.earnings_updated</span>
        <span class="openapi-deprecated-badge">Deprecated</span>
      </div>
      <div><span class="name">Published when the tour's earnings are updated.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.etas_recalculated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.etas_recalculated</span>
        
      </div>
      <div><span class="name">Published when the ETAs for the tour's stops have been recalculated.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.force_assigned" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.force_assigned</span>
        
      </div>
      <div><span class="name">Notifies about a tour being forcefully assigned to a driver.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.force_unassigned" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.force_unassigned</span>
        
      </div>
      <div><span class="name">Notifies about tour being forcefully un-assigned from a driver.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.modified" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.modified</span>
        
      </div>
      <div><span class="name">Published when some part of the tour is modified, e.g. when stops are changed.

For **drivers** it's only published while the booking is in `en_route` state.

When the tour doesn't have a driver yet, then it's published to the service area drivers channel.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.route_changed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.route_changed</span>
        
      </div>
      <div><span class="name">Published when the route of a tour has changed, i.e. by adding or removing stops, changing
their locations, changing their order and so on.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.stop_transition" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.stop_transition</span>
        
      </div>
      <div><span class="name">Indicates a change of status for a specific stop of a tour.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.transition" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.transition</span>
        
      </div>
      <div><span class="name">Indicates a change of status of a tour.</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have extended our existing booking and tour webhook notifications to always include the related service_area_id as well.]]></summary></entry><entry><title type="html">Support for external IDs on bookings</title><link href="https://docs.motiontools.io/announcements/changelog/2025/09/24/booking-external-id.html" rel="alternate" type="text/html" title="Support for external IDs on bookings" /><published>2025-09-24T00:00:00+00:00</published><updated>2025-09-24T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/09/24/booking-external-id</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/09/24/booking-external-id.html"><![CDATA[<p>We have introduced support for passing external IDs on the booking creation that will be stored in our system
and becomes visible in API responses and booking-related webhook notifications.</p>

<p>This feature allows easier integration of external systems for booking management with MotionTools, by allowing
you to correlate a booking ID on the other system with booking data stored and published via MotionTools, as the
booking procedes through it’s lifecycle.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>This property will be returned <strong>only</strong> on bookings fetched via <code class="language-plaintext highlighter-rouge">standard</code> and <code class="language-plaintext highlighter-rouge">compact</code> views. You can also filter
by the <code class="language-plaintext highlighter-rouge">external_id</code> on the bookings list.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListHailingBookings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">All Bookings</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings/{id}</span>
        
      </div>
      <div><span class="name">Show Booking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The property is also included in the CSV export of the bookings.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ExportHailingBookings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/export</span>
        
      </div>
      <div><span class="name">Export Bookings as CSV</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>We have also extended all our booking-related webhooks to contain the <code class="language-plaintext highlighter-rouge">external_id</code> when present. This allows you to more easily
reference the booking on your side against your own identifier without having to store our booking ID alongside it and match them.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.created" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.created</span>
        
      </div>
      <div><span class="name">Published when a new booking has been created</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.etas_recalculated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.etas_recalculated</span>
        
      </div>
      <div><span class="name">Published when the ETAs for the booking's stops have been recalculated.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.modified" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.modified</span>
        
      </div>
      <div><span class="name">Published when some part of booking is modified, e.g. when stops are changed.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.route_changed" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.route_changed</span>
        
      </div>
      <div><span class="name">Published when the route of a booking has changed, i.e. by adding or removing stops, changing
their locations, changing their order and so on.</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.booking.transition" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">booking.transition</span>
        
      </div>
      <div><span class="name">Indicates a change of status of a booking.</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced support for passing external IDs on the booking creation that will be stored in our system and becomes visible in API responses and booking-related webhook notifications.]]></summary></entry><entry><title type="html">Customer cancellation policies for bookings</title><link href="https://docs.motiontools.io/announcements/changelog/2025/09/18/booking-service-cancellation-policy.html" rel="alternate" type="text/html" title="Customer cancellation policies for bookings" /><published>2025-09-18T00:00:00+00:00</published><updated>2025-09-18T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/09/18/booking-service-cancellation-policy</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/09/18/booking-service-cancellation-policy.html"><![CDATA[<p>We have introduced configurable cancellation policies for booking services. The new policies allow you to configure until which point customers can cancel their bookings per booking service:</p>

<ol>
  <li><strong>Never</strong> – Customers cannot cancel their bookings.</li>
  <li><strong>Before dispatch</strong> – Customers can cancel if none of the stops have been dispatched into a tour - <strong>this is the default</strong>.</li>
  <li><strong>Before approaching</strong> – Customers can cancel if none of the dispatched stops have reached the “approaching” status.</li>
  <li><strong>Before arrival</strong> – Customers can cancel if none of the dispatched stops have reached the “arrived” status.</li>
</ol>

<p>This new functionality gives you more control over the booking services you offer to your customers.</p>

<p>You can configure the <code class="language-plaintext highlighter-rouge">cancellation_policy</code> via our usual service admin API endpoints:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminHailingServices" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">List Services</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">Create a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Show a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Update a service</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The ability to cancel a specific booking in its current configuration and status is always indicated via the <code class="language-plaintext highlighter-rouge">available_transitions</code> property of our bookings payload.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListHailingBookings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">All Bookings</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings/{id}</span>
        
      </div>
      <div><span class="name">Show Booking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Configuring this via our admin dashboard is also coming soon.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced configurable cancellation policies for booking services. The new policies allow you to configure until which point customers can cancel their bookings per booking service:]]></summary></entry><entry><title type="html">Dedicated webhook for notifying about tour earnings update</title><link href="https://docs.motiontools.io/announcements/changelog/2025/09/18/tour-earnings-updated-webhook.html" rel="alternate" type="text/html" title="Dedicated webhook for notifying about tour earnings update" /><published>2025-09-18T00:00:00+00:00</published><updated>2025-09-18T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/09/18/tour-earnings-updated-webhook</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/09/18/tour-earnings-updated-webhook.html"><![CDATA[<p>We have introduced a dedicated webhook for notifying about tour earnings update.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.tour.earnings_updated" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">tour.earnings_updated</span>
        <span class="openapi-deprecated-badge">Deprecated</span>
      </div>
      <div><span class="name">Published when the tour's earnings are updated.</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The new webhook is supposed to replace the usage of the very broad <code class="language-plaintext highlighter-rouge">tour.modified</code> webhook for cases when you’re interested
in getting notified about tour earnings update.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a dedicated webhook for notifying about tour earnings update.]]></summary></entry><entry><title type="html">Cancellation of dispatched bookings for admins</title><link href="https://docs.motiontools.io/announcements/changelog/2025/09/10/admin-dispatched-booking-cancellation.html" rel="alternate" type="text/html" title="Cancellation of dispatched bookings for admins" /><published>2025-09-10T00:00:00+00:00</published><updated>2025-09-10T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/09/10/admin-dispatched-booking-cancellation</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/09/10/admin-dispatched-booking-cancellation.html"><![CDATA[<p>We now also allow admins to cancel bookings that are fully <code class="language-plaintext highlighter-rouge">dispatched</code> more easily - meaning all their stops are dispatched into one or more tours.</p>

<p>This complements the <a href="/announcements/changelog/2025/05/21/cancellation-of-partially-dispatched-bookings.html">corresponding feature we’ve announced back in May</a> where this was already made possible more easily for <code class="language-plaintext highlighter-rouge">partially_dispatched</code> bookings.</p>

<hr />

<p>Let’s go through some examples to outline some of the different scenarios. We’ll consider a booking with stops A and B, which are dispatched into a single tour:</p>

<p><strong>Admin cancels before driver arrives at one of the stops</strong></p>

<ul>
  <li>The dispatched stops get removed from the tour</li>
  <li>The tour is empty and <code class="language-plaintext highlighter-rouge">cancelled</code></li>
  <li>The original booking stops are <code class="language-plaintext highlighter-rouge">cancelled</code></li>
  <li>The original booking is <code class="language-plaintext highlighter-rouge">cancelled</code></li>
</ul>

<p><strong>Admin cancels after a driver arrived at a stop</strong></p>

<ul>
  <li>The arrived tour stop A will be marked as failed</li>
  <li>We detach the tour stop A from the booking stop A</li>
  <li>The tour stop B is removed from the tour</li>
  <li>The tour is completed and in <code class="language-plaintext highlighter-rouge">paid</code> status</li>
  <li>The original booking is <code class="language-plaintext highlighter-rouge">cancelled</code></li>
</ul>

<p><strong>Admin cancels after a driver completed or failed a stop</strong></p>

<p>Assuming the driver already completed the tour stop A and is now approaching the tour stop B</p>

<ul>
  <li>The already completed tour stop A remains <code class="language-plaintext highlighter-rouge">done</code> and on the tour</li>
  <li>The corresponding booking stop A remains <code class="language-plaintext highlighter-rouge">done</code></li>
  <li>The second, approaching stop B is removed from the tour and is <code class="language-plaintext highlighter-rouge">cancelled</code> on the booking</li>
  <li>The tour is completed and in <code class="language-plaintext highlighter-rouge">paid</code> status</li>
  <li>The original booking is <code class="language-plaintext highlighter-rouge">cancelled</code></li>
</ul>

<p>When the driver fails stop A the behaviour is the same except that of course the stop will now be in <code class="language-plaintext highlighter-rouge">failed</code> status both on the tour and booking, instead of <code class="language-plaintext highlighter-rouge">done</code></p>

<p>Overall, the behaviour is the same as for <code class="language-plaintext highlighter-rouge">partially_dispatched</code> bookings or bookings
that have their stops dispatched into multiple tours - but the rules will accordingly apply
to all related tours and stops.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TransitionHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/hailing/bookings/{id}/transition</span>
        
      </div>
      <div><span class="name">Perform a transition on a booking or tour</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now also allow admins to cancel bookings that are fully dispatched more easily - meaning all their stops are dispatched into one or more tours.]]></summary></entry><entry><title type="html">Adding stop instructions</title><link href="https://docs.motiontools.io/announcements/changelog/2025/09/10/stop-instructions.html" rel="alternate" type="text/html" title="Adding stop instructions" /><published>2025-09-10T00:00:00+00:00</published><updated>2025-09-10T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/09/10/stop-instructions</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/09/10/stop-instructions.html"><![CDATA[<p>We have introduced the ability to add additional instructions for the driver as custom content
on stops using pre-defined templates as admin and regular customer, both on booking creation and
when inserting a custom stop into a booking or a tour.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing tour</span></div>
    </div>
  </a>
</div>

<p>Instructions are pre-defined content that is attached to the stop, providing additional details about things
to do for the driver at the stop - for example verifying the recipient’s age.
You can see available instructions through the dedicated endpoint:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListAvailableInstructions" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/stops/available_instructions</span>
        
      </div>
      <div><span class="name">List available stop instructions</span></div>
    </div>
  </a>
</div>

<p>You can still provide your own content for the stops, alongside instructions.
In such a case, the content for the instruction will be appended to the provided content.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to add additional instructions for the driver as custom content on stops using pre-defined templates as admin and regular customer, both on booking creation and when inserting a custom stop into a booking or a tour.]]></summary></entry><entry><title type="html">Assigning drivers to specific service areas</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-service-area-assignment.html" rel="alternate" type="text/html" title="Assigning drivers to specific service areas" /><published>2025-08-27T00:00:00+00:00</published><updated>2025-08-27T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-service-area-assignment</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-service-area-assignment.html"><![CDATA[<p>We have introduced the ability to assign drivers to specific service areas.</p>

<p>In MotionTools when a driver goes online in the driver app as well as while they update their location while they’re online
we constantly check their location against the service areas defined for the corresponding tenant.</p>

<p>When the driver moves between service areas we will assign them to the new area automatically. This leads to them showing
up in the operations page of a service area in our dashboard as well as giving them the ability to see pickable and scheduled
tours for the corresponding service areas.</p>

<p>We have now introduced the ability to assign drivers to one or more specific service areas. If a driver is assigned like this
we won’t change their service area in the way described above anymore if the service area matching their current location 
is not assigned to them.</p>

<p>When a driver is not assigned to any specific service areas, the behaviour remains as it was before - a driver can enter any
service area available on the tenant.</p>

<p>The corresponding API endpoints for managing assigned driver service areas that were introduced are:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AssignDriverToServiceArea" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/drivers/{id}/assigned_service_areas</span>
        
      </div>
      <div><span class="name">Assign a driver to a service area</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AssignedDriverServiceAreas" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/drivers/{id}/assigned_service_areas</span>
        
      </div>
      <div><span class="name">Assigned service areas</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UnassignDriverFromServiceArea" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/drivers/{id}/assigned_service_areas/{service_area_id}</span>
        
      </div>
      <div><span class="name">Un-assign a driver from a service area</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>The feature will soon also be available on our admin dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to assign drivers to specific service areas.]]></summary></entry><entry><title type="html">Support for declaring tips</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-tip.html" rel="alternate" type="text/html" title="Support for declaring tips" /><published>2025-08-27T00:00:00+00:00</published><updated>2025-08-27T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-tip</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/27/driver-tip.html"><![CDATA[<p>We have introduced the ability to declare an optional tip amount and currency to send to a driver upon booking creation.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<p>Upon regular booking creation we now allow customers and admins to pass an optional <code class="language-plaintext highlighter-rouge">tip</code> request payload. The
contained fractional amount and currency code will be persisted on the booking.</p>

<p>We also indicate this value on the <code class="language-plaintext highlighter-rouge">standard</code> booking response when present.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/bookings/{id}</span>
        
      </div>
      <div><span class="name">Show Booking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>At this time this value is simply being stored and returned, no further features are available on our platform
for further usage - similar to our tour earnings mechanism, this feature simply provides a way to provide and store
the data, and further processing needs to be implemented as needed via our API and other integrations.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to declare an optional tip amount and currency to send to a driver upon booking creation.]]></summary></entry><entry><title type="html">Updating capabilities on bookings &amp;amp; tours</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/27/update-capabilities.html" rel="alternate" type="text/html" title="Updating capabilities on bookings &amp;amp; tours" /><published>2025-08-27T00:00:00+00:00</published><updated>2025-08-27T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/27/update-capabilities</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/27/update-capabilities.html"><![CDATA[<p>We now allow updating the <code class="language-plaintext highlighter-rouge">requested_capabilities</code> on bookings and tours.</p>

<p>So far, changing the requested capabilities wasn’t allowed after initial creation of a booking or tour.</p>

<p>Especially in the case of tours this was a bit limiting as a tour might be modified and extended during planning
before being given to drivers the required capabilities for doing the tour might change - for example,
a simple tour might suffice a <code class="language-plaintext highlighter-rouge">bike</code> vehicle, but dispatching more stops from other bookings into the
same tour might make a <code class="language-plaintext highlighter-rouge">car</code> necessary.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateBookingRequestedCapabilities" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/bookings/{id}/requested_capabilities</span>
        
      </div>
      <div><span class="name">Update booking's requested capabilities</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateTourRequestedCapabilities" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/tours/{id}/requested_capabilities</span>
        
      </div>
      <div><span class="name">Update tour's requested capabilities</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Support for updating those is also soon coming to our web dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now allow updating the requested_capabilities on bookings and tours.]]></summary></entry><entry><title type="html">Customers can also request booking CSV exports</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/20/customer-booking-csv.html" rel="alternate" type="text/html" title="Customers can also request booking CSV exports" /><published>2025-08-20T00:00:00+00:00</published><updated>2025-08-20T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/20/customer-booking-csv</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/20/customer-booking-csv.html"><![CDATA[<p>Customers can now also request a CSV export of their bookings.</p>

<p>So far the booking CSV export feature was available only to the admin and organization manager roles - 
we have now also made this availble to customers.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ExportHailingBookings" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/export</span>
        
      </div>
      <div><span class="name">Export Bookings as CSV</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Support for this has also been added to our dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Customers can now also request a CSV export of their bookings.]]></summary></entry><entry><title type="html">Assign organizations to service areas</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/20/organization-service-area-assignment.html" rel="alternate" type="text/html" title="Assign organizations to service areas" /><published>2025-08-20T00:00:00+00:00</published><updated>2025-08-20T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/20/organization-service-area-assignment</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/20/organization-service-area-assignment.html"><![CDATA[<p>We have introduced the ability to link organizations and service areas to each other, allowing to automate
visibility of tours.</p>

<p>Our existing managing organizations feature allows scoping the visiblity of bookings and tours to certain organizations - only
drivers and organization managers on these organizations (in addition to explicitly added preferred drivers) will be able to see such bookings
and tours.</p>

<p>This functionality is useful to scope access and operations to certain operational sub-units or subcontractors.</p>

<p>We have now extended this functionality with a built-in automation. You can now link certain organizations to specific service areas.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminListOrganizationServiceAreaLinks" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/organization_service_area_links</span>
        
      </div>
      <div><span class="name">List organization and service area links</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminLinkOrganizationAndServiceArea" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/organization_service_area_links</span>
        
      </div>
      <div><span class="name">Link organization and service area</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUnlinkOrganizationAndServiceArea" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/admin/organization_service_area_links/{id}</span>
        
      </div>
      <div><span class="name">Unlink organization and service area</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>When organizations are assigned to the corresponding service area, we will now automatically set all related organizations
as managing organizations when creating an empty tour or creating a tour by dispatching booking stops via these endpoints:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateEmptyTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours</span>
        
      </div>
      <div><span class="name">Create Empty Tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/DispatchStopsIntoTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/merge</span>
        
      </div>
      <div><span class="name">Dispatch stops into a tour</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Consistent with our previously existing behaviour about managing organization inheritance, operations like dispatching 
booking stops into an existing tour do not further modify the managing organizations.</p>

<p>Support for managing this is also coming soon to our admin dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to link organizations and service areas to each other, allowing to automate visibility of tours.]]></summary></entry><entry><title type="html">Extended configurabilty of off-route driver tour display</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/13/driver-off-route-tour-display.html" rel="alternate" type="text/html" title="Extended configurabilty of off-route driver tour display" /><published>2025-08-13T00:00:00+00:00</published><updated>2025-08-13T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/13/driver-off-route-tour-display</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/13/driver-off-route-tour-display.html"><![CDATA[<p>We are reworking the way pickable, scheduled, claimed, completed and cancelled tours are being displayed in our driver apps.</p>

<p>We want to make our platform even more adaptable to the specific needs of your business and use case, and therefore are
introducing sophisticated new possibilities for configuring the way tours are shown to drivers.</p>

<p>In addition to already existing features like configuring the sorting order and algorithm of the pickable tours list and more,
among the new configurable features you can:</p>

<ul>
  <li>Configure how tour stops are being displayed in overview maps of lists</li>
  <li>Decide whether you only want to show the details of the first or first and last stop in lists</li>
</ul>

<p>We are also introducing highly configurable labels, on both tours and stops. This allows you to choose and configure
which details should be shown, and in what order, including:</p>

<ul>
  <li>The distance to the first stop from the driver’s location</li>
  <li>The total tour distance</li>
  <li>Any metadata on the tour or any of it’s stops</li>
  <li>Driver Earnings</li>
  <li>Expected arrival time windows</li>
</ul>

<p>You can freely add and remove these options and configure localized prefix and suffix values. For this, please use the new
tour display admin APIs:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Show Tour Display Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateTourDisplay" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience/tour_display</span>
        
      </div>
      <div><span class="name">Update Tour Display Configuration</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Additional driver experience related configuration options remain available via:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Show Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Update Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Support for configuring these interactively is coming soon to our admin dashboard as well, and our driver apps will receive updates
in the next weeks that fully utilize these new configuration options for tour display.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We are reworking the way pickable, scheduled, claimed, completed and cancelled tours are being displayed in our driver apps.]]></summary></entry><entry><title type="html">Linking places to service areas</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/13/linking-places-to-service-areas.html" rel="alternate" type="text/html" title="Linking places to service areas" /><published>2025-08-13T00:00:00+00:00</published><updated>2025-08-13T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/13/linking-places-to-service-areas</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/13/linking-places-to-service-areas.html"><![CDATA[<p>We will now create links between service areas and places based on their location.</p>

<p>Most notably, this gives you the ability to filter places based on their service area(s). Please note that
service area coordinates can overlap, and hence a single place can be inside multiple service areas.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListPlaces" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/places</span>
        
      </div>
      <div><span class="name">List all places</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We will now create links between service areas and places based on their location.]]></summary></entry><entry><title type="html">New option to display customer places in driver app</title><link href="https://docs.motiontools.io/announcements/changelog/2025/08/13/show-customer-places-in-driver-app.html" rel="alternate" type="text/html" title="New option to display customer places in driver app" /><published>2025-08-13T00:00:00+00:00</published><updated>2025-08-13T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/08/13/show-customer-places-in-driver-app</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/08/13/show-customer-places-in-driver-app.html"><![CDATA[<p>We have introduced the optional ability to display nearby customer places in the driver app’s map.</p>

<p>If your use case revolves around tasks at repeating customer locations, for example picking up goods
at shops or meals at restaurants, it can be useful for drivers to be aware of where these locations are
around them.</p>

<p>For this, we have introduced a new <code class="language-plaintext highlighter-rouge">show_customer_places</code> flag on our driver experience configuration API,
which defaults to <code class="language-plaintext highlighter-rouge">false</code>. When enabled, drivers will be able to see the locations and names of the up to
100 non-archived customer places closest to their current location and inside their service area while online.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Show Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Update Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Support for configuring this is also available in the admin dashboard and the driver apps will soon start
fetching and displaying these.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the optional ability to display nearby customer places in the driver app’s map.]]></summary></entry><entry><title type="html">Export packages via CSV</title><link href="https://docs.motiontools.io/announcements/changelog/2025/07/23/packages-csv-export.html" rel="alternate" type="text/html" title="Export packages via CSV" /><published>2025-07-23T00:00:00+00:00</published><updated>2025-07-23T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/07/23/packages-csv-export</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/07/23/packages-csv-export.html"><![CDATA[<p>We have introduced the ability to export package information in a CSV file.</p>

<p>The endpoint supports the common filters also avaible on the regular package listing endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CsvExportPackages" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages/export</span>
        
      </div>
      <div><span class="name">Generate CSV export</span></div>
    </div>
  </a>
</div>

<p>Support for creating these exports is also coming soon to our web dashboard for customers and admins.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to export package information in a CSV file.]]></summary></entry><entry><title type="html">Harmonized distance for route distance and price calculation</title><link href="https://docs.motiontools.io/announcements/changelog/2025/07/09/price-calculation-distance-source.html" rel="alternate" type="text/html" title="Harmonized distance for route distance and price calculation" /><published>2025-07-09T00:00:00+00:00</published><updated>2025-07-09T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/07/09/price-calculation-distance-source</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/07/09/price-calculation-distance-source.html"><![CDATA[<p>We will now use the same source for calculating the distance of a booking for statistics as well as for calculating the price
from the price matrix.</p>

<p>If you’re using our booking pricing module on your tenant in certain scenarios you could have a difference in the overage distance
calculated for the price and the booking distance shown in the web dashboard. The reason for this was that different sources
where used for these before - now, this uses the same source for both.</p>

<p>Which source is being used depends on the route accuracy plan that you have purchased with us, either being straight line calculation
or an actual maps-based route calculation.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We will now use the same source for calculating the distance of a booking for statistics as well as for calculating the price from the price matrix.]]></summary></entry><entry><title type="html">User search now also takes company name into account</title><link href="https://docs.motiontools.io/announcements/changelog/2025/07/09/search-includes-customer-company-name.html" rel="alternate" type="text/html" title="User search now also takes company name into account" /><published>2025-07-09T00:00:00+00:00</published><updated>2025-07-09T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/07/09/search-includes-customer-company-name</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/07/09/search-includes-customer-company-name.html"><![CDATA[<p>Our user search will now also consider the company name listed on customer profiles, if present.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListUsers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/users</span>
        
      </div>
      <div><span class="name">List Users</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Our user search will now also consider the company name listed on customer profiles, if present.]]></summary></entry><entry><title type="html">Restrict driver profile updates</title><link href="https://docs.motiontools.io/announcements/changelog/2025/07/02/restricted-driver-profile-update.html" rel="alternate" type="text/html" title="Restrict driver profile updates" /><published>2025-07-02T00:00:00+00:00</published><updated>2025-07-02T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/07/02/restricted-driver-profile-update</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/07/02/restricted-driver-profile-update.html"><![CDATA[<p>We have introduced the ability to restrict updates to driver profiles.</p>

<p>Depending on your onboarding process for new drivers it can be helpful to restrict further editing
of a driver’s profile details after initial onboarding. To facilitate this we have introduced a new option 
to restrict self-serving updates to a driver’s profile details after a successful initial onboarding.</p>

<p>This option is available to you upon request by reaching out to our customer success team.</p>

<p>Regardless of this setting admins and organization managers remain able to update a driver’s profile details using
our web dashboard and the corresponding API endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateUserProfileAsManagingUser" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/users/{id}/profile</span>
        
      </div>
      <div><span class="name">Update Profile as Admin/Org. Manager</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to restrict updates to driver profiles.]]></summary></entry><entry><title type="html">Managed mode for driver’s capabilities</title><link href="https://docs.motiontools.io/announcements/changelog/2025/06/24/managed-driver-capabilities.html" rel="alternate" type="text/html" title="Managed mode for driver’s capabilities" /><published>2025-06-24T00:00:00+00:00</published><updated>2025-06-24T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/06/24/managed-driver-capabilities</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/06/24/managed-driver-capabilities.html"><![CDATA[<p>We have introduced a managed mode for driver’s capabilities, where admins and optionally
organization managers and drivers themselves can update them.</p>

<p>When a driver is going online in the driver app we ask them about their current capabilities, which are
subsequently used for selecting suitable tours.</p>

<p>Depending on your onboarding flow it can be necessary to do additional verifications like driver license checks
during onboarding. In such situations it can be desirable to restrict the drivers ability to choose different
capabilities after the initial onboarding. For this, we have extended our product with a corresponding
optional configuration, allowing to restrict such updates so for example an onboarded driver always has a <code class="language-plaintext highlighter-rouge">bike</code>
capability and cannot switch to a <code class="language-plaintext highlighter-rouge">car</code> without reaching out to your internal support team.</p>

<p>This option is available to you upon request by reaching out to our customer success team. It’s configurable
whether drivers and/or org_managers can update these each, and the default remains as before that all
of admins, org_managers and drivers can manage them.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateDriverCapabilities" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/drivers/{id}/capabilities</span>
        
      </div>
      <div><span class="name">Update driver's matching capabilities</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Our driver apps will accordingly adapt to this setting and not offer the ability to choose corresponding
capabilities that affect matching when going online.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a managed mode for driver’s capabilities, where admins and optionally organization managers and drivers themselves can update them.]]></summary></entry><entry><title type="html">Enhanced Vehicle Type Profiles: More Accurate Route Calculations for Every Vehicle</title><link href="https://docs.motiontools.io/announcements/changelog/2025/06/11/enhanced-vehicle-type-profile-usage.html" rel="alternate" type="text/html" title="Enhanced Vehicle Type Profiles: More Accurate Route Calculations for Every Vehicle" /><published>2025-06-11T00:00:00+00:00</published><updated>2025-06-11T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/06/11/enhanced-vehicle-type-profile-usage</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/06/11/enhanced-vehicle-type-profile-usage.html"><![CDATA[<p>We’re excited to announce significant improvements to our vehicle type profile system, giving you more 
granular control over route calculations and estimates based on your actual fleet composition.</p>

<h4 id="whats-new">What’s new</h4>

<p>Previously, our platform used a single, global vehicle type profile per tenant for all route calculations, 
regardless of the actual vehicle being used. This meant that whether your driver was using a bike, car, 
or truck, the system would calculate routes and estimates using the same parameters.</p>

<p>Now, you can configure unique vehicle type profiles for each vehicle capability value, enabling more 
accurate and realistic route planning that reflects the true capabilities and constraints of different vehicle types.</p>

<h4 id="why-this-matters">Why This Matters</h4>

<p>Different vehicles have vastly different operational characteristics:</p>

<ul>
  <li>Bikes can take shortcuts through parks and bike lanes but move slower on longer routes</li>
  <li>Cars balance speed and accessibility across most road types</li>
  <li>Trucks can require specific routes that accommodate size and weight restrictions</li>
</ul>

<p>With vehicle-specific profiles, your route estimates and statistics will now accurately reflect these 
differences, leading to:</p>

<ul>
  <li>More realistic delivery time estimates</li>
  <li>Improved customer expectations and satisfaction</li>
</ul>

<h4 id="how-it-works">How It Works</h4>

<h5 id="configure-vehicle-specific-profiles">Configure Vehicle-Specific Profiles</h5>

<p>You can now assign distinct vehicle type profiles to each vehicle capability value through our admin APIs:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateCapability" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/capabilities</span>
        
      </div>
      <div><span class="name">Create Capability</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateCapability" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/capabilities/{capability_key}</span>
        
      </div>
      <div><span class="name">Update Capability</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCapabilities" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/capabilities</span>
        
      </div>
      <div><span class="name">List Capabilities</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCapabilityValues" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/capabilities/{capability_key}/values</span>
        
      </div>
      <div><span class="name">List Capability Values</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateCapabilityValue" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/capabilities/{capability_key}/values</span>
        
      </div>
      <div><span class="name">Create Capability Value</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateCapabilityValue" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/capabilities/{capability_key}/values/{key}</span>
        
      </div>
      <div><span class="name">Update Capability Value</span></div>
    </div>
  </a>
</div>

<h5 id="automatic-profile-assignment">Automatic Profile Assignment</h5>

<p>When drivers go online in the driver app and select a vehicle capability the system automatically assigns 
the corresponding vehicle type profile to their account. This ensures that all subsequent tour calculations 
use the appropriate profile for their specific vehicle and means that estimated distances and times of arrival
can change once a driver starts a tour if their vehicle type profile differs from the one requested on the tour.</p>

<h5 id="enhanced-route-calculations">Enhanced Route Calculations</h5>

<p>The improved system now uses vehicle-specific profiles for:</p>

<ul>
  <li>Arrival time estimates</li>
  <li>Tour statistics</li>
</ul>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/StatsForTours" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/tour/stats</span>
        
      </div>
      <div><span class="name">Fetch stats for tours</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/EstimateBookingsStopsArrivals" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/estimates</span>
        
      </div>
      <div><span class="name">Fetch estimated arrival times for multiple bookings at once</span></div>
    </div>
  </a>
</div>

<h4 id="getting-started">Getting Started</h4>

<p>If you’re already using our capability system with vehicle types, these improvements are automatically available. 
Simply configure vehicle type profiles for your existing vehicle capability values to start seeing more accurate 
route calculations.</p>

<p>For new implementations, the <code class="language-plaintext highlighter-rouge">vehicle_type</code> capability we create by default for new tenants will serve as your 
starting point for vehicle-specific configuration, and already comes with pre-configured <code class="language-plaintext highlighter-rouge">vehicle_type_profile</code> defaults.</p>

<p><em>Need help setting up vehicle type profiles for your fleet? Contact our support team or check out our API documentation 
for detailed implementation guidance.</em></p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We’re excited to announce significant improvements to our vehicle type profile system, giving you more granular control over route calculations and estimates based on your actual fleet composition.]]></summary></entry><entry><title type="html">Collection of proofs for off-tour package delivery</title><link href="https://docs.motiontools.io/announcements/changelog/2025/06/03/off-tour-package-proofs.html" rel="alternate" type="text/html" title="Collection of proofs for off-tour package delivery" /><published>2025-06-03T00:00:00+00:00</published><updated>2025-06-03T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/06/03/off-tour-package-proofs</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/06/03/off-tour-package-proofs.html"><![CDATA[<p>We now allow configuring and collecting proofs of delivery for packages that are force-delivered or marked as collected.</p>

<p>Since the configuration of required proofs of delivery on tours is configured per tour service it cannot apply to off-tour
package delivery &amp; collection - therefore, a new dedicated configuration for off-tour package delivery proofs has been
added to our packages configuration admin API. The available options depend on your plan at MotionTools, and specifically
the purchase of the granular proofs configuration extension.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdatePackageConfig" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/packages</span>
        
      </div>
      <div><span class="name">Update Package Configuration</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>When marking a package as collected or force delivered the corresponding proofs will be collected based on this configuration
in a similar way it would when delivering packages the regular way via a tour.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CollectHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages/{id}/collect</span>
        
      </div>
      <div><span class="name">Mark package as collected</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ForceDeliverHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages/{id}/force_delivery</span>
        
      </div>
      <div><span class="name">Mark package as delivered</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now allow configuring and collecting proofs of delivery for packages that are force-delivered or marked as collected.]]></summary></entry><entry><title type="html">Optional pricing detail links for booking services</title><link href="https://docs.motiontools.io/announcements/changelog/2025/05/28/booking-service-price-details-urls.html" rel="alternate" type="text/html" title="Optional pricing detail links for booking services" /><published>2025-05-28T00:00:00+00:00</published><updated>2025-05-28T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/05/28/booking-service-price-details-urls</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/05/28/booking-service-price-details-urls.html"><![CDATA[<p>You can now define optional, localized <code class="language-plaintext highlighter-rouge">pricing_details_url_translations</code> on booking services which will be used
to show localized links for further pricing information in your web booking portal for customers.</p>

<p>In addition to the API this functionality is also configurable from our booking service management in the admin dashboard.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">Create a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminHailingServices" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">List Services</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Show a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Update a service</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[You can now define optional, localized pricing_details_url_translations on booking services which will be used to show localized links for further pricing information in your web booking portal for customers.]]></summary></entry><entry><title type="html">Package recovery to pickup place</title><link href="https://docs.motiontools.io/announcements/changelog/2025/05/28/recover-packages-to-pickup.html" rel="alternate" type="text/html" title="Package recovery to pickup place" /><published>2025-05-28T00:00:00+00:00</published><updated>2025-05-28T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/05/28/recover-packages-to-pickup</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/05/28/recover-packages-to-pickup.html"><![CDATA[<p>We now allow recovering a failed package to its original pickup place.</p>

<p>When a package fails to be picked up or dropped of at a corresponding stop we move it
into the <code class="language-plaintext highlighter-rouge">failed</code> status.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/RecoverHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages/{id}/recover</span>
        
      </div>
      <div><span class="name">Recover failed package</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>So far we only allowed to recover packages to one of your tenant hub places. To make resolving situations
where the actual pickup of the package at its origin fails (i.e. because it wasn’t ready in time) easier
we now additionally allow recovering packages to their pickup place. This makes it easier to re-attempt pickup
of a package without having to do a cancel &amp; recreate cycle.</p>

<p>This functionality is also available from our package management tools in the admin dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now allow recovering a failed package to its original pickup place.]]></summary></entry><entry><title type="html">Cancellation of partially dispatched bookings</title><link href="https://docs.motiontools.io/announcements/changelog/2025/05/21/cancellation-of-partially-dispatched-bookings.html" rel="alternate" type="text/html" title="Cancellation of partially dispatched bookings" /><published>2025-05-21T00:00:00+00:00</published><updated>2025-05-21T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/05/21/cancellation-of-partially-dispatched-bookings</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/05/21/cancellation-of-partially-dispatched-bookings.html"><![CDATA[<p>We have made it easier for admins to cancel partially dispatched bookings in a single API call.</p>

<p>This functionality was already available before in our web dashboard and via our API, but on the API
it required taking a few individual calls to reach the desired state - you had to first undispatch the
corresponding stops from a tour before you could move on to cancelling the booking.</p>

<p>With the new change the <code class="language-plaintext highlighter-rouge">cancel</code> transition will also appear for <code class="language-plaintext highlighter-rouge">partially_dispatched</code> bookings
in their <code class="language-plaintext highlighter-rouge">available_transitions</code> via the API, and can then be cancelled using our generic
booking transition endpoint.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TransitionHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/hailing/bookings/{id}/transition</span>
        
      </div>
      <div><span class="name">Perform a transition on a booking or tour</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have made it easier for admins to cancel partially dispatched bookings in a single API call.]]></summary></entry><entry><title type="html">Package delivery re-attempts</title><link href="https://docs.motiontools.io/announcements/changelog/2025/05/13/package-delivery-reattempts.html" rel="alternate" type="text/html" title="Package delivery re-attempts" /><published>2025-05-13T00:00:00+00:00</published><updated>2025-05-13T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/05/13/package-delivery-reattempts</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/05/13/package-delivery-reattempts.html"><![CDATA[<p>We have introduced the ability to append delivery reattempts for failed package deliveries
on the same tour via a corresponding failure reason.</p>

<p>Our package failure reason configuration already enables you to define specific failure reasons
for your package pickups and deliveries in a self-serving way via the API as well as our admin
dashboard.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminListHailingFailureReasons" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/failure_reasons</span>
        
      </div>
      <div><span class="name">List Failure Reasons</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateHailingFailureReasons" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/failure_reasons</span>
        
      </div>
      <div><span class="name">Create Failure Reason</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingFailureReason" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/failure_reasons/{id}</span>
        
      </div>
      <div><span class="name">Update Failure Reason</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>We have now introduced an optional <code class="language-plaintext highlighter-rouge">triggers_reattempt</code> flag on failure reasons. When this flag
is set and a package delivery is marked as failed in the driver app using a corresponding failure
reason with this flag we will automatically append another delivery attempt stop at the end of the current
tour. The driver can then move the stop into a reasonable position in the order using our familiar
stop reordering feature in the driver app.</p>

<p>This new feature is intended to help in situations where upon delivery the driver becomes aware
that a recipient might be able to be reached for delivery at a later point during the tour.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to append delivery reattempts for failed package deliveries on the same tour via a corresponding failure reason.]]></summary></entry><entry><title type="html">External labels in package transition webhook</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/30/external-labels-in-package-transition-webhook.html" rel="alternate" type="text/html" title="External labels in package transition webhook" /><published>2025-04-30T00:00:00+00:00</published><updated>2025-04-30T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/30/external-labels-in-package-transition-webhook</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/30/external-labels-in-package-transition-webhook.html"><![CDATA[<p>Our package transition webhook notification now also contains the external labels of the package</p>

<p>This can be helpful for integrating our packages with external systems as you can now more easily
close the loop between passing the <code class="language-plaintext highlighter-rouge">external_labels</code> upon package creation and then listening for corresponding
updates without having to store our own package ID or looking it up via API for identification.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/webhook.hailing_package.transition" data-tooltip="Open webhook documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">Webhook</span>
        <span class="path">hailing_package.transition</span>
        
      </div>
      <div><span class="name">Indicates a change of status for a package</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages</span>
        
      </div>
      <div><span class="name">Create a Package</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[Our package transition webhook notification now also contains the external labels of the package]]></summary></entry><entry><title type="html">Gradual rollout for pickable tours</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/23/gradual-rollout-for-pickable-tours.html" rel="alternate" type="text/html" title="Gradual rollout for pickable tours" /><published>2025-04-23T00:00:00+00:00</published><updated>2025-04-23T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/23/gradual-rollout-for-pickable-tours</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/23/gradual-rollout-for-pickable-tours.html"><![CDATA[<p>We have introduced an extension giving you the ability to roll out pickable tours gradually to available drivers 
based on their distance from the first stop.</p>

<p>This optional extension works by looking up the next closest available driver and marking them as preferred, instead
of the default behaviour of pickable tours becoming immediately visible to all suitable drivers. It can help you
in optimize the approach time on your tours by ensuring the closest drivers see and ideally pick tours, 
avoiding longer approach distances and thus driving times.</p>

<p>This feature is available as a paid extension via our customer success team - please reach
out to us in case you are interested.</p>

<p>Once enabled you can configure this feature per operations configuration, so you can either have one central configuration
for all of your service areas or go as detailed as having one individual per service area.</p>

<p>You can configure whether:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">driver_ranking</code> is enabled</li>
  <li><code class="language-plaintext highlighter-rouge">gradual_rollout</code> is enabled</li>
  <li>How long we should wait before rolling out to the next available driver via <code class="language-plaintext highlighter-rouge">gradual_rollout_frequency_seconds</code></li>
</ul>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListSchedulingConfigs" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/hailing/scheduling_configs</span>
        
      </div>
      <div><span class="name">List scheduling configss</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateSchedulingConfigs" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/scheduling_configs</span>
        
      </div>
      <div><span class="name">Create new scheduling config</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateSchedulingConfig" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/scheduling_configs/{id}</span>
        
      </div>
      <div><span class="name">Update a scheduling config</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>We also introduced an endpoint that allows inspecting the current ranking for drivers for a given tour:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TourDriverRanking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/tours/{id}/ranked_drivers</span>
        
      </div>
      <div><span class="name">Driver Ranking</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Once the extension is enabled you can also configure it interactively through our admin dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced an extension giving you the ability to roll out pickable tours gradually to available drivers based on their distance from the first stop.]]></summary></entry><entry><title type="html">Preferred drivers on tours can be modified while en route</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/16/update-preferred-drivers-en-route.html" rel="alternate" type="text/html" title="Preferred drivers on tours can be modified while en route" /><published>2025-04-16T00:00:00+00:00</published><updated>2025-04-16T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/16/update-preferred-drivers-en-route</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/16/update-preferred-drivers-en-route.html"><![CDATA[<p>We now allow updating the list of preferred drivers on tours that are already en route.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TourAddPreferredDrivers" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/tours/{id}/preferred_drivers</span>
        
      </div>
      <div><span class="name">Set preferred drivers</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now allow updating the list of preferred drivers on tours that are already en route.]]></summary></entry><entry><title type="html">Collecting packages from a hub</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/10/collect-packages-from-hub.html" rel="alternate" type="text/html" title="Collecting packages from a hub" /><published>2025-04-10T00:00:00+00:00</published><updated>2025-04-10T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/10/collect-packages-from-hub</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/10/collect-packages-from-hub.html"><![CDATA[<p>We have introduced a new package flow for picking them up from a hub, skipping delivery via a tour.</p>

<p>If you offer self-pickup of packages at one of your hubs you can now facilitate this process through
our packages product.</p>

<p>You can initiate the flow on packages that are <code class="language-plaintext highlighter-rouge">at_hub</code> or <code class="language-plaintext highlighter-rouge">scheduled_for_delivery</code> by triggering the corresponding
<code class="language-plaintext highlighter-rouge">request_collection</code> transition:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TransitionHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/hailing/packages/{id}/transition</span>
        
      </div>
      <div><span class="name">Perform a transition on a package</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>An eligible package can then be marked as collected using the corresponding endpoint:</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CollectHailingPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/packages/{id}/collect</span>
        
      </div>
      <div><span class="name">Mark package as collected</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Our driver apps were updated accordingly, allowing to utilize this new feature from the package scanner.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a new package flow for picking them up from a hub, skipping delivery via a tour.]]></summary></entry><entry><title type="html">Package journey now also contains location type</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/10/location-type-on-package-journey.html" rel="alternate" type="text/html" title="Package journey now also contains location type" /><published>2025-04-10T00:00:00+00:00</published><updated>2025-04-10T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/10/location-type-on-package-journey</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/10/location-type-on-package-journey.html"><![CDATA[<p>We now include the <code class="language-plaintext highlighter-rouge">location_type</code> on package interaction based properties on the package journey.</p>

<p>This makes it easier to interpret whether a certain event listed is for example a pickup at the origin or at a hub.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowPackageJourney" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/packages/{id}/journey</span>
        
      </div>
      <div><span class="name">Show package journey</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now include the location_type on package interaction based properties on the package journey.]]></summary></entry><entry><title type="html">Expanded package tracking details</title><link href="https://docs.motiontools.io/announcements/changelog/2025/04/02/expanded-package-tracking-details.html" rel="alternate" type="text/html" title="Expanded package tracking details" /><published>2025-04-02T00:00:00+00:00</published><updated>2025-04-02T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/04/02/expanded-package-tracking-details</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/04/02/expanded-package-tracking-details.html"><![CDATA[<p>We have extended the information available on the public package tracking API.</p>

<ul>
  <li>When a package is <code class="language-plaintext highlighter-rouge">scheduled_for_delivery</code> or <code class="language-plaintext highlighter-rouge">out_for_delivery</code> we will now include the latest estimated time of arrival for the package dropoff stop at the destination</li>
  <li>We will provide the driver’s approximate current location when they are approaching the package destination dropoff stop and the package is therefore <code class="language-plaintext highlighter-rouge">out_for_delivery</code></li>
  <li>For packages that are <code class="language-plaintext highlighter-rouge">out_for_delivery</code> we will also provide the approximate number of stops for them to reach the package’s destination stop on the tour</li>
</ul>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/TrackPackage" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/packages/{tracking_code}/tracking</span>
        
      </div>
      <div><span class="name">Track package</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Our public package tracking page was adjusted accordingly to reflect this additional information.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have extended the information available on the public package tracking API.]]></summary></entry><entry><title type="html">Custom pickable list sorting algorithms</title><link href="https://docs.motiontools.io/announcements/changelog/2025/03/19/custom-pickable-sorting-algorithm.html" rel="alternate" type="text/html" title="Custom pickable list sorting algorithms" /><published>2025-03-19T00:00:00+00:00</published><updated>2025-03-19T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/03/19/custom-pickable-sorting-algorithm</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/03/19/custom-pickable-sorting-algorithm.html"><![CDATA[<p>We have introduced an extension for providing a custom sorting algorithm to determine
the order pickable tours appear in on the driver app.</p>

<p>When chosen we provide the following variables for the custom algorithm:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">scheduled_in_seconds</code> - How many seconds from now the tour is scheduled</li>
  <li><code class="language-plaintext highlighter-rouge">driver_distance_meters</code> - How far away the viewing driver is from the first stop location</li>
  <li><code class="language-plaintext highlighter-rouge">tour_distance_meters</code> - How long the estimated tour is in meters</li>
</ul>

<p>Using these variables in the custom sorting algorithm can help optimize your operational efficiency
significantly by increasing the likeliness drivers that pick a tour are close to the first stop,
prioritize longer tours or those that are late, or any combination of these, depending on your operational
requirements and optimization targets.</p>

<p>This feature is available as a paid extension via our customer success team - please reach
out to us in case you are interested.</p>

<p>The configuration of the custom sorting algorithm itself can only be changed via our customer success team at 
this time upon your request, however once enabled you can switch it’s usage off and on using the corresponding driver experience
admin API or in our web dashboard.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Show Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Update Driver Experience Configuration</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced an extension for providing a custom sorting algorithm to determine the order pickable tours appear in on the driver app.]]></summary></entry><entry><title type="html">Unified stop completion timestamps and clock skew compensation</title><link href="https://docs.motiontools.io/announcements/changelog/2025/02/26/clock-skew-and-stop-timestamps.html" rel="alternate" type="text/html" title="Unified stop completion timestamps and clock skew compensation" /><published>2025-02-26T00:00:00+00:00</published><updated>2025-02-26T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/02/26/clock-skew-and-stop-timestamps</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/02/26/clock-skew-and-stop-timestamps.html"><![CDATA[<p>We have made adjustments to unify the stop arrival, completion and failure timestamps, as well as the events history. We have also
adjusted our apps to compensate client-side clock skew.</p>

<p>We are tracking <code class="language-plaintext highlighter-rouge">arrived_at</code>, <code class="language-plaintext highlighter-rouge">completed_at</code>, and <code class="language-plaintext highlighter-rouge">failed_at</code> timestamps on stops, as well as keeping a separate events history.
So far, there could be discrepancies between the individual timestamps of these events between the events history and the dedicated
timestamps - we have adjusted our stop completion logic to keep those aligned so the timestamps will always match.</p>

<p>We have also made adjustments to the completion of grouped stops, where we now ensure the corresponding grouped stops will also
have the same timestamps throughout, matching those on the initial completed grouped stop.</p>

<p>Additionally our driver apps now handle clock skew in a better way - if the clock on the device of a driver is
incorrect, so far the resulting stop timestamps could be wrong from the actual time the corresponding arrival or completion events occured, 
both in offline as well as online stop completion. We will now adjust those timestamps according to the real time based on the delta of
the driver’s device clock to the actual time.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have made adjustments to unify the stop arrival, completion and failure timestamps, as well as the events history. We have also adjusted our apps to compensate client-side clock skew.]]></summary></entry><entry><title type="html">Permission indication for removing packages from a tour</title><link href="https://docs.motiontools.io/announcements/changelog/2025/02/26/permission-indication-for-removing-packages-from-tour.html" rel="alternate" type="text/html" title="Permission indication for removing packages from a tour" /><published>2025-02-26T00:00:00+00:00</published><updated>2025-02-26T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/02/26/permission-indication-for-removing-packages-from-tour</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/02/26/permission-indication-for-removing-packages-from-tour.html"><![CDATA[<p>We now indicate the permission to remove a package from a tour on the package payload.</p>

<p>You can find the flag in <code class="language-plaintext highlighter-rouge">permissions.removable</code> on the package response payload, making it easier to figure
out whether the operation to remove a package can be succesfully called.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListHailingPackages" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/hailing/packages</span>
        
      </div>
      <div><span class="name">List packages</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/RemovePackagesFromExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">delete</span>
        <span class="path">/api/hailing/tours/{tour_id}/packages</span>
        
      </div>
      <div><span class="name">Remove packages from a tour</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We now indicate the permission to remove a package from a tour on the package payload.]]></summary></entry><entry><title type="html">Force-ending a tour marks packages as delivered</title><link href="https://docs.motiontools.io/announcements/changelog/2025/02/20/package-status-after-tour-force-end.html" rel="alternate" type="text/html" title="Force-ending a tour marks packages as delivered" /><published>2025-02-20T00:00:00+00:00</published><updated>2025-02-20T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/02/20/package-status-after-tour-force-end</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/02/20/package-status-after-tour-force-end.html"><![CDATA[<p>When force-ending a tour a package is currently on in the status <code class="language-plaintext highlighter-rouge">scheduled_for_delivery</code> we will now mark this package as <code class="language-plaintext highlighter-rouge">delivered</code>.</p>

<p>Before, such packages were being moved back into <code class="language-plaintext highlighter-rouge">at_hub</code> status the tour was originating from but this behaviour didn’t make
sense in case of the force-ending of a tour as it is meant for <strong>completing</strong> the tour without the driver’s interaction.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ForceEndBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/force_end</span>
        
      </div>
      <div><span class="name">Force end a booking or a tour</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[When force-ending a tour a package is currently on in the status scheduled_for_delivery we will now mark this package as delivered.]]></summary></entry><entry><title type="html">Introducing phone number masking</title><link href="https://docs.motiontools.io/announcements/changelog/2025/02/12/masked-communication.html" rel="alternate" type="text/html" title="Introducing phone number masking" /><published>2025-02-12T00:00:00+00:00</published><updated>2025-02-12T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/02/12/masked-communication</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/02/12/masked-communication.html"><![CDATA[<p>We have introduced the masked communication extension, which allows drivers to call
customers without revealing the real customer or driver phone number to either party.</p>

<p>The feature relies solely on the phone number attached to the currently active stop
of a tour, which can be set either on booking or individual stop creation or by 
updating the stop contact details via the dedicated API endpoint or from our web dashboard.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateStopContact" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/stops/{stop_id}/contact</span>
        
      </div>
      <div><span class="name">Update Contact Details</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>When a driver chooses to call the stored stop phone number and the feature is enabled
they will instead call a dedicated phone number specific to your tenant, and we will proxy
the call to the final destination defined on the stop. The customer will see the call coming in from your 
tenant-wide phone number, and once connected the driver and customer are able to discuss
delivery details via phone without revealing each other’s real phone numbers.</p>

<p>We have also included additional phone number sanitization and normalization rules
which fix many common errors in the phone numbers provided by users, increasing successful phone
connection percentages, and therefore speed to reach the stop, significantly.</p>

<p>These features are available as a paid extension via our customer success team - please reach
out to us in case you are interested.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the masked communication extension, which allows drivers to call customers without revealing the real customer or driver phone number to either party.]]></summary></entry><entry><title type="html">Improvements to places filtering</title><link href="https://docs.motiontools.io/announcements/changelog/2025/01/30/improved-place-filters.html" rel="alternate" type="text/html" title="Improvements to places filtering" /><published>2025-01-30T00:00:00+00:00</published><updated>2025-01-30T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/01/30/improved-place-filters</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/01/30/improved-place-filters.html"><![CDATA[<p>We have introduced the ability to request customer and admin / tenant places together
in the places list.</p>

<p>So far, you were only able to either retrieve tenant-wide places or places for specific
customer IDs. We have now introduced additional options to this filter:</p>

<ul>
  <li><code class="language-plaintext highlighter-rouge">customers_only</code> - will list only customer places, but for any customer</li>
  <li><code class="language-plaintext highlighter-rouge">include_customers</code> - will list tenant-wide places alongside customer-specific places</li>
</ul>

<p>Additionally, when making requests as an admin we will now show some details about
the customer user account for customer places in the corresponding API responses.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ListPlaces" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/places</span>
        
      </div>
      <div><span class="name">List all places</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowPlace" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/places/{id}</span>
        
      </div>
      <div><span class="name">Show a place</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>Our web dashboard has been adjusted accordingly to support these new options.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced the ability to request customer and admin / tenant places together in the places list.]]></summary></entry><entry><title type="html">Introducing driver experience configuration</title><link href="https://docs.motiontools.io/announcements/changelog/2025/01/15/introducing-driver-experience-configuration.html" rel="alternate" type="text/html" title="Introducing driver experience configuration" /><published>2025-01-15T00:00:00+00:00</published><updated>2025-01-15T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/01/15/introducing-driver-experience-configuration</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/01/15/introducing-driver-experience-configuration.html"><![CDATA[<p>We are extending the self-serving configurability of the driver experience in our apps.</p>

<p>To facilitate this we have introduced a new driver experience API. The new API allows you
to adjust the following behaviour in our driver app:</p>

<ul>
  <li>The field to sort pickable tours by - either by <code class="language-plaintext highlighter-rouge">scheduled_at</code> or by the distance from the driver’s location</li>
  <li>The sorting direction of the pickable tours list</li>
  <li>The maximum number of results to show in the pickable tours list</li>
  <li>The maximum distance a driver can have from their current location to the first stop of a tour in the pickable list</li>
</ul>

<p>You can use these new features to optimize the way tours are shown to drivers in a way best suitable to your
business model, operations and driver availability.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminShowDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Show Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateDriverExperience" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/admin/driver_experience</span>
        
      </div>
      <div><span class="name">Update Driver Experience Configuration</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>A corresponding UI based configuration is also available in our admin dashboard.</p>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We are extending the self-serving configurability of the driver experience in our apps.]]></summary></entry><entry><title type="html">Automatic arrival and geofencing configuration enhancements</title><link href="https://docs.motiontools.io/announcements/changelog/2025/01/08/geofencing-enhancements-and-auto-arrival.html" rel="alternate" type="text/html" title="Automatic arrival and geofencing configuration enhancements" /><published>2025-01-08T00:00:00+00:00</published><updated>2025-01-08T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/01/08/geofencing-enhancements-and-auto-arrival</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/01/08/geofencing-enhancements-and-auto-arrival.html"><![CDATA[<p>We have extended our geofencing capabilities around the arrival at stops.</p>

<p>So far admins already had the ability to set an optional <code class="language-plaintext highlighter-rouge">maximum_driver_distance_meters</code> on stops when
creating bookings, inserting custom stops into bookings or tours, or by updating them. When set a driver
is prohibited to mark a stop as arrived when outside of the specified aerial distance from the stop location.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/CreateHailingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings</span>
        
      </div>
      <div><span class="name">Create a Booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingBooking" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/bookings/{booking_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing booking</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/InsertCustomStopIntoExistingTour" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/hailing/tours/{tour_id}/stops</span>
        
      </div>
      <div><span class="name">Insert custom stop into existing tour</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateStopProperties" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/stops/{stop_id}/properties</span>
        
      </div>
      <div><span class="name">Update Stop Properties</span></div>
    </div>
  </a>
</div>

<p><br /></p>

<p>We have extended these functionalities with additional features:</p>

<h4 id="automatic-arrival-at-stop">Automatic arrival at stop</h4>

<p>In addition to the <code class="language-plaintext highlighter-rouge">maximum_driver_distance_meters</code> we now also allow defining an <code class="language-plaintext highlighter-rouge">auto_arrival_distance_meters</code>
on the same endpoints. When set the driver app will automatically mark the stop as arrived when the driver enters
the given radius from the stop location.</p>

<h4 id="defaults-from-booking-and-tour-services">Defaults from booking and tour services</h4>

<p>Additionally to the manual passing or setting of these values via the API we now also allow defining defaults
for both <code class="language-plaintext highlighter-rouge">maximum_driver_distance_meters</code> as well as <code class="language-plaintext highlighter-rouge">auto_arrival_distance_meters</code> on the booking and tour services
for each stop type.</p>

<p>When configured stops where the corresponding service applies will automatically be created with these defaults applied.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminCreateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">post</span>
        <span class="path">/api/admin/hailing/services</span>
        
      </div>
      <div><span class="name">Create a service</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/AdminUpdateHailingService" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">put</span>
        <span class="path">/api/admin/hailing/services/{id}</span>
        
      </div>
      <div><span class="name">Update a service</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have extended our geofencing capabilities around the arrival at stops.]]></summary></entry><entry><title type="html">Support for dedicated billing e-mail in invoice address</title><link href="https://docs.motiontools.io/announcements/changelog/2025/01/08/invoice-address-billing-email.html" rel="alternate" type="text/html" title="Support for dedicated billing e-mail in invoice address" /><published>2025-01-08T00:00:00+00:00</published><updated>2025-01-08T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/01/08/invoice-address-billing-email</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/01/08/invoice-address-billing-email.html"><![CDATA[<p>We have introduced a new, optional <code class="language-plaintext highlighter-rouge">billing_email</code> field on our invoice address account feature.</p>

<p>When provided booking receipt e-mails sent by our platform will instead be delivered to this dedicated address
instead of the user’s default account e-mail.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/ShowInvoiceAddress" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">get</span>
        <span class="path">/api/user/invoice_address</span>
        
      </div>
      <div><span class="name">Show Invoice Address</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateInvoiceAddress" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/user/invoice_address</span>
        
      </div>
      <div><span class="name">Update Invoice Address</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateInvoiceAddressAsManagingUser" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/users/{id}/invoice_address</span>
        
      </div>
      <div><span class="name">Update Invoice Address as Admin/Org. Manager</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have introduced a new, optional billing_email field on our invoice address account feature.]]></summary></entry><entry><title type="html">Loosened restrictions for updating additional booking, tour and stop information</title><link href="https://docs.motiontools.io/announcements/changelog/2025/01/08/loosened-additional-information-editing-restrictions.html" rel="alternate" type="text/html" title="Loosened restrictions for updating additional booking, tour and stop information" /><published>2025-01-08T00:00:00+00:00</published><updated>2025-01-08T00:00:00+00:00</updated><id>https://docs.motiontools.io/announcements/changelog/2025/01/08/loosened-additional-information-editing-restrictions</id><content type="html" xml:base="https://docs.motiontools.io/announcements/changelog/2025/01/08/loosened-additional-information-editing-restrictions.html"><![CDATA[<p>We have loosened the restrictions for updating the additional information of bookings, tours and stops
and now also allow updates even after they are completed.</p>

<p>The corresponding endpoints allow for providing additional information to drivers, changing the tour name 
as well as attaching order images and documents. Especially the latter can be particularily helpful
when additional order documentation is prepared after completion and hence can now be easily attached
to the corresponding stop, booking or tour.</p>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/EditBookingAdditionalInformation" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/hailing/bookings/{booking_id}/additional_information</span>
        
      </div>
      <div><span class="name">Edit booking's additional information</span></div>
    </div>
  </a>
</div>

<div class="openapi-endpoint">
  <a href="https://docs.motiontools.io/#operation/UpdateStopAdditionalInformation" data-tooltip="Open endpoint documentation in OpenAPI">
    <div class="grid">
      <div>
        <span class="request-method">patch</span>
        <span class="path">/api/stops/{stop_id}/additional_information</span>
        
      </div>
      <div><span class="name">Update Additional Information</span></div>
    </div>
  </a>
</div>]]></content><author><name></name></author><category term="Changelog" /><summary type="html"><![CDATA[We have loosened the restrictions for updating the additional information of bookings, tours and stops and now also allow updates even after they are completed.]]></summary></entry></feed>