MotionTools API documentation (2026-11-11)
MotionTools is modern software for urban logistics: the operating system for fleet-based service providers. Operators and teams managing a mobile workforce use it to digitize their processes, boost efficiency and excite their users — from logistics providers transporting goods as a service and retailers orchestrating their deliveries to services transporting people from A to B and field service providers.
The platform covers such a service end to end. Customers order bookings and packages in the customer portal, from their shop or through your own systems, priced by an optional, flexible pricing engine. Your operations team keeps the overview in the booking manager and dispatches efficiently with the dispatch tools and our automated tour planning features. Drivers carry out their tours in the driver app with custom checklists and proof of completion, while live tracking and ETAs keep operators and customers informed. Finally, the platform collects the customer's payment and can also record what each tour earns its driver: tour compensation with base earnings, bonuses and tips that can be distributed automatically, exported as compensation reports for your payroll. Dashboards and apps can be branded with your logo and colours, and white-label apps under your own name in the app stores are available as an extension.
Its configurability — services with their own capabilities and stop rules, pricing and scheduling per service area, custom content for drivers at the stops — and integrations through our API and webhooks let you adapt this robust platform flexibly to your business's everyday needs. The MotionTools API is a REST API to work with all of it from your own systems: connect shop systems, ERP and order management software, automate your operations and build your own experiences on top of the platform. Webhooks keep your systems up to date with what happens in your account in real time.
Our API has predictable resource-oriented URLs, accepts JSON-encoded and form-encoded requests, returns JSON-encoded responses, and uses standard HTTP response codes, authentication, and verbs.
📘 You can follow and subscribe to API change announcements and deprecations on our API announcements blog
📘 If you're not yet ready to integrate a specific API, more high-level feature and product documentation can be found on our help center.
In many cases the first point of integration is either creation of a booking in MotionTools from another system that you may already be using or reacting to events like a booking being completed by a driver via Webhooks.
Here are some related articles in our help center that can help you to quickly kick things off the ground 🚀:
This documentation is built from an OpenAPI 3.0 description of the API. It is available as a YAML file at https://docs.motiontools.io/schema.yml, so API clients, code generators and AI assistants can load it straight from that address, and it always matches what you read here.
To try out the API, import it into the API client of your choice. Two popular ones:
- Bruno: choose Import Collection, pick OpenAPI and the URL option, enter the address and click Import. With the default grouping by tags, the requests are sorted into folders named like the topics of this documentation. The requests address the API as
{{baseUrl}}and authenticate with{{token}}. Both are variables of an environment named Production, which the import creates: select it in the environment picker at the top right, and add your API token to it as a secret variable namedtoken. - Insomnia: click Import, select URL, enter the address, click Scan and then Import.
Both create a collection with a request for every endpoint, pointing at the base URL. In Insomnia, set your API token as the collection's bearer token. Import the address again to pick up later changes to the API.
For questions about a single endpoint, open the menu of its Copy button: Copy for LLM copies the endpoint's part of the description for any AI assistant, and Open in Claude / Open in ChatGPT start a chat about it.
The MotionTools API can be used to manage all aspects of your business that are managed by MotionTools.
To name a few:
Using the MotionTools API requires a basic understanding of how bookings, customers, service areas and a few other relevant concepts are structured, and how they relate to one another.
You can find a corresponding overview in our MotionTools help center glossary.
Contact our customer support agents over at [email protected] and they’ll make sure to clarify all your questions.
Here you can find more info on the authentication mechanisms used for the communication with MotionTools backend.
API Tokens can be created by admin and customer accounts via the Web Dashboard, and carry full permissions to the API as the token's owning user.
- 👉 See Create an API Key
API Tokens are intended to be used by other servers interacting with the MotionTools API, and they are not intended to be used by user-facing applications. Do not use API Tokens to authenticate client apps and do not embed API Tokens in client side code, as they can easily be extracted.
Other relevant points when it comes to authenticating with API tokens:
- the
X-Client-Versionheader must be omitted; - a request without an
Authorizationheader is rejected with status400and the error codeunknown_tenant, and one with an unknown token with status401and the error codeunauthorized; - API Tokens never expire. A token can be deleted in the web dashboard at any time, and we e-mail its owner about tokens that haven't been used for 3 months, recommending to remove them. Blocking a user deletes their API tokens.
All changes and deprecations to our API are announced via our Changelog & Deprecations page. We recommend checking it regularly to stay informed about upcoming changes.
Errors are broadly indicated via HTTP status and further narrowed down using an error code in the response payload. Human-readable descriptions are implementor-facing and meant to help in understanding issues, not user-facing.
{
"error_code": "hello_world",
"description": "Some brief description"
}
Some errors like failed validations may contain additional data in the response in order to clarify to the user what was wrong more easily. These messages are localized based on the sent Accept-Language and should be displayed as applicable:
- If an error key matches a request parameter the messages can be displayed along that field
- If an unknown error key is encountered (this can happen for multi-parameter composite validations like "one of email or phone must be set") all those messages should be displayed in a central place on top or at the bottom of the UI
A validation error response looks like this:
{
"errors": { "first_name": ["is blank"] },
"error_code": "validation_failed",
"description": "The request parameters did not satisfy validation rules for this resource."
}
In case the request parameters input is an array, ie. {"invitations": [{ "role": null }]} the validation error response will be further grouped by the corresponding items index in the input array, for example:
{
"errors": {
"0": { "role": ["is blank"] }
}
}
See documentation for the user invitations endpoint for a more detailed example.
All clients must set the standard Accept-Language HTTP header explicitly and manually to the IETF language tag (en-US) or ISO639-1 (en) locale chosen by the client for client-side message localization.
The reason for this is aligning translated messages stored and shown on the client side with those from the backend, most notably on validation error messages. For example if a client supports only en and de but the device is actually set fr, if the client does not explicitly state which language it picked the backend might make a differing choice based on available backend languages or configured default fallback language.
Note that this does not affect "core" translations, which should not be fetched from the backend dynamically but be defined and used in the clients themselves.
Additionally the backend stores the user's current language to use for server-side issued user-facing communication like e-mails and push notifications.
From the total pool of supported languages, only a subset is enabled for any tenant, and one of these is the default locale.
Clients must use only available locales for the tenant, so if a tenant supports en and de and has a default of de, if fr is also a MotionTools supported language a client on a device configured to be fr locale must then fall back to the default locale de, because fr is not in the enabled list.
You can inject custom data within MotionTools by structuring it as metadata on supported entities.
Metadata unlocks vast integration possibilities and could be used from simple cases where an external tracking id is added to a MotionTools package to more complex cases where metadata could be used to define behavior not supported by MotionTools out of the box, such as organizing drivers into teams by criteria defined by you & stored in metadata on the user accounts.
We support metadata on the following resources:
The listed endpoints will perform a full update of the metadata, effectively replacing the old one with the newly provided one.
We also support partial metadata updates via the PATCH HTTP semantics:
Metadata added on MotionTools entities can additionally be used to search & filter objects based on the contents of the metadata. Filtering based on metadata is currently available for:
When working with payments, you need to provide which payment method should be used.
- Per tenant: This triggers overall availability of a payment method for enabling in service areas
- Per service area: This defines actual availability of a payment method from superset of tenant payment methods in a given service area
- On top of this, some payment methods can be configured to be manually enabled per customer on a tenant-global level
So, depending on what you want to do you must source the available payment methods from the right place so it's correct with regard to all the rules derived from the configuration defined above.
The dedicated endpoint for Bookings Configuration should be used in that case.
Note that when wanting to create a booking as an admin on the behalf of a customer, customer_id should be provided on this endpoint. That way you'll be sure that you're fetching just the payment methods that are enabled for this customer.