public-api-docs

User API Discovery And Vehicle Guide

Overview

Discovery endpoints provide the reference data and availability data needed by user-facing apps: branches, vehicles, categories, stations, physical stations, POIs, attributes, and selected settings. Use these endpoints for maps, vehicle detail screens, station selection, booking discovery, and localized app configuration.

Related reference: User API Stations User API Points-Of-Interest User API User API Guide Radar Guide Tutorial Guide Fair-Use Policy

Core Concepts

Branches

A branch represents a geographic and operational context. Branches influence available vehicles, categories, pricing, rental requirements, packages, subscriptions, terms, stations, and payment behavior.

Use the branch resolver when an app needs to determine the best branch for a user position. Use direct branch reads when the app already knows the branch ID.

Vehicle Availability

GET /vehicles is the main customer-facing availability endpoint. It is intended for app maps and nearby vehicle discovery. Responses can include location, category, battery/state-of-charge information, pricing-related fields, promotion context, and rental eligibility hints depending on tenant configuration.

Poll this endpoint responsibly. Availability changes frequently, but excessive polling can affect platform performance.

Vehicle Categories

Vehicle categories describe user-facing vehicle types and their rental behavior. Category configuration can affect allowed actions, additions, pricing options, booking availability, rental requirements, battery thresholds, and display metadata.

Stations And Physical Stations

The User API exposes station concepts for user-facing discovery. Station data can support station-based vehicles, physical docking/parking infrastructure, booking station selection, and parking-area availability.

POIs

Points of interest are informational map markers. They are not a replacement for stations, areas, or business rules. Use them to show helpful map locations such as service points, partner locations, or informational markers.


Common User Workflows

Resolve And List Branches

Task Endpoint
List branches GET /branches
List branch IDs GET /branches/ids
Resolve closest or fallback branch GET /branches/resolve
Get branch detail GET /branches/{id}
Get intersectable branches GET /branches/{id}/intersectable

Branch data is good cache material, but refresh it periodically because service areas, settings, and branch availability can change.

Show Available Vehicles

Task Endpoint
List available vehicles GET /vehicles
Get vehicle by ID GET /vehicles/{id}
Get vehicle by code GET /vehicles/code/{code}
Check start rental requirements GET /rentals/requirements
List the user’s vouchers GET /vouchers
Locate a vehicle POST /vehicles/{id}/locate
Generate Bluetooth tokens POST /vehicles/{id}/bluetooth/generate-tokens

Use GET /vehicles/code/{code} for scan flows. Use GET /vehicles/{id} when the user opens a detail sheet from the map. Use Bluetooth token generation only when the app is about to perform an allowed BLE action for the selected vehicle.

Efficient Map Discovery

Use GET /vehicles as a map-viewport query, not as a full-fleet sync endpoint. This is especially important for branches with many vehicles. Repeatedly loading the full branch fleet for every map refresh can produce very large responses, slow down the app, and run into rate limiting that protects the platform service.

For mobile and web maps, derive the query from the visible viewport:

  1. Use the current map center as lat and lng.
  2. Calculate rad from the current viewport, normally the distance from the center to the farthest visible corner.
  3. Send rad in miles.
  4. Apply product filters such as branchId, categoryId, excludeStationedVehicles, and minStateOfCharge before rendering markers.
  5. Treat the response as the current map candidate set, then let the map viewport decide which markers are visible on screen.

Example:

GET /vehicles?branchId=3&lat=48.20849&lng=16.37208&rad=1.2&categoryId=7&minStateOfCharge=30

Do not call GET /vehicles without spatial parameters for interactive maps unless the app is intentionally showing a complete branch-level availability list. Without lat, lng, and rad, the endpoint can return all available vehicles in the accessible branches, which is usually more data than a map needs. Apps that poll this unbounded response frequently, especially in high-volume branches, should expect throttling or rate limiting to protect service stability.

The spatial parameters are all-or-nothing: if you send one of lat, lng, or rad, send all three. The backend uses the provided center and radius to reduce the candidate set and also applies tenant-level minimum-radius behavior so very small map views still return a usable result around the user. Because the API can return candidates around the viewport, the client should still avoid rendering markers that are outside the visible map bounds.

Use this refresh pattern for map screens:

Use the filters intentionally:

Parameter How to use it
branchId Send it when the app already knows the active branch. This keeps the result scoped to the branch the user is browsing.
lat, lng, rad Use the current map viewport. rad is in miles and must be sent with both coordinates.
categoryId Send one or more category IDs when the user selected vehicle types, for example only scooters or only e-bikes.
excludeStationedVehicles Set to true for free-floating-only map views. Keep false when station-based vehicles should also be shown.
minStateOfCharge Use for app-level filters such as “show vehicles with at least 30% battery”. The value is a percentage from 0 to 100.

If the app has both free-floating vehicles and station-based availability, keep those display modes explicit. Use GET /vehicles for available vehicle markers, and use station or physical-station endpoints for station markers, parking locations, docking infrastructure, and station detail screens.

If the current viewport has no suitable vehicle, offer a vehicle radar instead of widening the map request indefinitely. A radar lets the user save a radius and receive a notification when an available vehicle appears in that area. See the Radar Guide for the full flow.

Discounted And Rewarded Vehicles

Vehicle discovery can mark vehicles that have a user-facing benefit. Use the benefits array on GET /vehicles responses to decide how the marker should look:

Benefit What it means Suggested map treatment
DISCOUNTED A vehicle or geofence promotion currently applies to this vehicle. Show a discount badge or highlighted marker.
REWARDED The vehicle is configured as a reward vehicle. Show a reward badge or highlighted marker.

The legacy benefit field can contain one value, but new clients should prefer benefits because a vehicle can carry more than one benefit.

GET /vehicles is optimized for map discovery. It tells the app that a vehicle should be visualized as discounted, but it should not be treated as the source of the exact discount copy. When a user taps a discounted marker or opens the vehicle sheet, call GET /vehicles/{id} or GET /vehicles/code/{code} and read pricing.discount.

Use the returned pricing discount like this:

Field Meaning Display example
pricing.discount.discountPercentage Fractional discount. 0.2 means 20% off. Multiple applicable percentage discounts can be combined by the backend. 20% off
pricing.discount.discountValue Fixed rental rebate amount in the vehicle currency. €2 off

If both values are present, show both only when the product design has enough room and the wording is clear. Otherwise prefer a concise badge on the map and explain the full discount in the vehicle detail sheet.

Example vehicle-map logic:

if vehicle.benefits contains DISCOUNTED:
  render discounted marker

on marker tap:
  GET /vehicles/{id}
  if pricing.discount.discountPercentage is present:
    show "{discountPercentage * 100}% off"
  if pricing.discount.discountValue is present:
    show "{discountValue} off"

Discount visibility and discount application are related but not identical. The map marker should communicate that a benefit is available now. The rental start and billing flow still performs the final eligibility and pricing checks, because promotions can depend on time, branch, category, geofence, vehicle annotations, user eligibility, and redemption limits.

Applicable Vouchers On Vehicle Selection

When a user taps a vehicle, the app can show which of the user’s vouchers are eligible for that selected vehicle. Do this from the vehicle detail response, not from the map list alone.

Recommended flow:

  1. User taps a marker from GET /vehicles.
  2. App calls GET /vehicles/{id} or GET /vehicles/code/{code}.
  3. App reads vehicle.applicableVouchers.
  4. App shows eligible voucher names and value information in the vehicle sheet.

applicableVouchers is scoped to the authenticated user, the vehicle’s branch, and the vehicle category. In other words, it answers: “Which of this user’s active constraint vouchers can be used for a rental with this vehicle type in this branch?”

Useful voucher fields for display:

Field Meaning
name User-facing voucher name.
voucherableCode Code of the voucher template or redeemable campaign behind the issued voucher.
rentalRebate / rentalRebateNet Monetary rebate amount.
valueGross / remainingValueGross Monetary value still available on value-based vouchers.
freeMinutes / remainingFreeMinutes Free-minute entitlement, when the voucher represents minutes instead of money.
numberOfRentals / remainingNumberOfRentals Rental-count limits.
validFrom / validUntil Validity window.
applicablePriceType Price component the voucher targets, such as driving, parking, distance, reservation, or unlock fee.

Use GET /vouchers?branchId={branchId}&active=true when building a voucher wallet or benefits screen for the selected branch. Do not use that list alone to decide what to show on a specific vehicle detail screen, because vehicle category constraints still matter. If you need to enrich a selected vehicle voucher with fields from the broader voucher list, match by voucherableCode and prefer vehicle.applicableVouchers as the source of vehicle-level eligibility.

If multiple vouchers are returned, treat them as eligible vouchers, not as a guaranteed ordered application result. At billing time, the backend applies the final voucher rules on the rental. The current pricing logic applies cost-source-scoped vouchers before broad vouchers, applies at most one rebate or percentage-discount voucher per rental, and can apply value vouchers until the rental price reaches zero. The final applied rebate is visible in the rental or invoice pricing after the rental is priced.

Example detail-sheet logic:

on marker tap:
  GET /vehicles/{id}
  if applicableVouchers is not empty:
    show "Voucher available"
    show the best readable value from rentalRebate, remainingValueGross, or remainingFreeMinutes
  else if pricing.discount is present:
    show the vehicle or geofence promotion from pricing.discount

Rental Requirements On Vehicle Selection

When a user taps a vehicle, do not wait until POST /rentals to discover that the user cannot start. Use the selected vehicle’s branchId and categoryId to retrieve the current user’s start rental requirements.

Typical detail-sheet flow:

  1. User taps a vehicle marker from GET /vehicles.
  2. App calls GET /vehicles/{id} to load current vehicle detail, pricing, benefits, and availability.
  3. App calls GET /rentals/requirements?branchId={branchId}&vehicleCategoryId={categoryId}.
  4. App filters the response for fulfilled=false.
  5. If the list is empty, enable the start/reserve action.
  6. If the list contains unfulfilled requirements, show the returned message and route the user to the relevant setup flow.

Example:

GET /rentals/requirements?branchId=3&vehicleCategoryId=7

Example response shape:

[
  {
    "rentalRequirement": "LICENSE",
    "fulfilled": false,
    "message": "Please verify your driving license."
  },
  {
    "rentalRequirement": "PAYMENT_SOURCE",
    "fulfilled": false,
    "message": "Please add a payment method."
  }
]

The API response is the UI checklist. message is the localized user-facing explanation; rentalRequirement is the stable code your app should use to decide which screen or call-to-action to open.

Common requirement handling:

Requirement What it usually means Suggested action
LICENSE Driving license verification is missing, pending, rejected, expired, or requires reverification. Route to driving license verification, usually starting with POST /verification/init.
ID_DOCUMENT, MANUAL, CUSTOM_EXTERNAL_VERIFICATION The tenant requires additional identity, manual, or custom verification. Route to the configured verification flow.
PAYMENT_SOURCE, PAYMENT_ANY, PAYMENT_PUSH The user has not fulfilled the required payment setup for this branch/category. Route to payment method setup or package/payment flow.
TERMS_ACCEPTED, TERMS_ACCEPTED_LATEST, RENTAL_AUTHORITY The user has not accepted required terms or does not yet have rental authority on the branch. Show and accept the required branch terms before retrying.
MINIMUM_AGE, MAXIMUM_AGE, USER_REQUIRED_DRIVING_LICENCE_TYPE_PRESENT, INSUFFICIENT_B_CATEGORY_DURATION The user’s profile or license category/tenure does not satisfy this vehicle category. Explain the blocker; only route to profile or verification if the user can resolve it.
USER_HAVE_ENOUGH_BALANCE, POSITIVE_CREDIT, USER_HAS_NO_UNPAID_INVOICES The account, wallet, balance, credit, or invoice state blocks rental start. Route to balance top-up, invoice payment, or support depending on tenant setup.
RIDE_PASS, PREVIOUS_RENTALS, VEHICLE_IN_STATION_AREA The branch/category has a specific configured requirement. Show the returned message and product-specific action.

For business-account or group-funded rentals, include the selected user group:

GET /rentals/requirements?branchId=3&vehicleCategoryId=7&userGroupId=42

For booking or pre-booking flows, include the intended booking window so price- and time-dependent checks can be evaluated:

GET /rentals/requirements?branchId=3&vehicleCategoryId=7&bookingStartTime=2026-05-21T10:00:00Z&bookingEndTime=2026-05-21T12:00:00Z

Do not hard-code requirement text from rentalRequirement alone. Use the returned message for display, because the same code can represent different user states. For example, LICENSE can mean the user never started verification, the license is still processing, verification was rejected, the license expired, or reverification is required.

Load Categories, Attributes, And Pricing Options

Task Endpoint
List vehicle categories on a branch GET /vehicles/categories
Get vehicle category detail GET /vehicles/categories/{id}
List vehicle attributes GET /vehicle-attributes
Get on-demand pricing options GET /on-demand-pricing-options

Use category and pricing-option data together before creating a rental when a branch supports multiple on-demand pricing choices.

Locate And Access A Selected Vehicle

Use vehicle utility endpoints only after the user has selected a vehicle or has an active/reserved rental context.

Task Endpoint
Trigger locate behavior POST /vehicles/{id}/locate
Generate Bluetooth access tokens POST /vehicles/{id}/bluetooth/generate-tokens

POST /vehicles/{id}/locate is a user-facing convenience action to help the user find the selected vehicle, for example by flashing lights or sounding a configured signal. Re-read the vehicle after locate actions if the UI depends on fresh state.

POST /vehicles/{id}/bluetooth/generate-tokens is used by app flows that need Bluetooth access tokens for supported vehicles. Generate tokens close to the moment they are needed, store them only according to the app’s secure-storage policy, and do not assume every vehicle category or IoT integration supports Bluetooth access.

Show Stations And POIs

Task Endpoint
List stations from the main User API GET /stations
List tenant stations from the Stations User API GET /stations
Get tenant station detail from the Stations User API GET /stations/{stationId}
List physical stations GET /physical-stations
Get physical station detail GET /physical-stations/{id}
List points of interest GET /pois
List POI categories GET /categories

Physical stations and booking stations can affect parking, booking, and rental-end behavior. POIs are informational markers only.

Load App Content And Configuration

Task Endpoint
Read selected settings GET /settings
Get localized message resources GET /resources/messages
List available message languages GET /resources/messages/languages

Use GET /settings only for known user-facing setting keys. Do not build broad setting-catalog flows with the User API. Tutorials have their own flow; see the Tutorial Guide.


Most Relevant APIs

Area Endpoints
Branches GET /branches, GET /branches/ids, GET /branches/resolve, GET /branches/{id}, GET /branches/{id}/intersectable
Vehicles GET /vehicles, GET /vehicles/{id}, GET /vehicles/code/{code}, POST /vehicles/{id}/locate, POST /vehicles/{id}/bluetooth/generate-tokens
Rental readiness GET /rentals/requirements
Vouchers on selection GET /vehicles/{id}, GET /vehicles/code/{code}, GET /vouchers
Categories and attributes GET /vehicles/categories, GET /vehicles/categories/{id}, GET /vehicle-attributes, GET /on-demand-pricing-options
Stations GET /stations, GET /physical-stations, GET /physical-stations/{id}
Specific station API GET /stations, GET /stations/{stationId} in station-user-api.yaml
POIs GET /pois, GET /categories in pois-user-api.yaml
Content and settings GET /settings, GET /resources/messages, GET /resources/messages/languages

Implementation Notes