public-api-docs

User API Rental Guide

Overview

Rental endpoints support the customer-facing on-demand rental lifecycle: reservations, active trips, rental operations, end checks, additions, damages, files, feedback, parking reservations, vehicle cards, and driving logs.

Related reference: User API User API Guide Discovery And Vehicle Guide Payments And Invoices Guide Error Codes

Core Concepts

Rental State

Common rental states include:

State Meaning
RESERVATION The vehicle is reserved for the user but the trip has not started.
ACTIVE The rental is in progress. The vehicle may be driving or parked depending on rental phases and operations.
EXPIRED A reservation expired before it was started.
CANCELLED A reservation was canceled.
ENDED The rental completed and billing/finalization has run.
ENDED_NO_MOVEMENT The rental started but ended without meaningful movement.

Rental Operations

Use rental operations for state transitions and vehicle actions:

Operation Typical use
START Start a reserved rental.
PARK Pause driving while keeping the rental active.
DRIVE Resume driving after parking.
END End the rental and trigger final checks and billing.
OPEN_TAILBOX Open a configured tailbox/helmet box.
RENEW_RESERVATION Extend a reservation where supported.

The public User API reference exposes POST /rentals/{rentalId}/operation for rental operations.

Rental Requirements And Checks

Rental start can be blocked by missing T&C, verification, payment method, rental authority, branch/category restrictions, minimum age/license rules, balance requirements, or business account constraints.

Rental end can be blocked by parking, station, geofence, vehicle-state, equipment, photo, or surcharge checks. Use POST /rentals/{rentalId}/check/end before ending when the app needs to explain unresolved end-rental requirements.

Main Rental Flow

The normal customer-facing rental flow has four phases:

Phase Goal Main endpoints
Prepare Make sure the user can rent this vehicle. GET /vehicles, GET /vehicles/{id}, GET /termsandconditions, POST /termsandconditions, GET /payment, GET /rentals/requirements
Create Reserve or start the rental. POST /rentals
Operate Start, park, drive, renew, open tailbox, or cancel. POST /rentals/{rentalId}/operation, DELETE /rentals/{rentalId}
End Validate parking/end conditions, upload files, end, then show final state. POST /rentals/{rentalId}/check/end, POST /files, POST /rentals/{rentalId}/operation, GET /rentals/{rentalId}

Applied Rebates And Free Minutes

When a rental ends, the appliedRebates array on the rental detail response lists every promotion, package, subscription, reward, or voucher that was applied to that trip. Each entry carries the monetary discount it contributed and — for certain types — a nested voucherable object that describes the configured benefit.

Rebate types and voucherable availability:

type voucherable present Free-minutes benefit
PROMOTION Yes (@type: "Promotion") Via voucherable.benefits[] — look for type: "FreeMinutes"
PACKAGE Yes (@type: "Package") Via voucherable.benefits[]
SUBSCRIPTION Yes (@type: "Subscription") Via voucherable.benefits[]
REWARD Yes (@type: "Reward") Via voucherable.benefits[]
RIDE_PASS Yes (@type: "RidePass") Via voucherable.benefits[]
VEHICLE_PROMOTION No Only amountNet / amountGross available
CASHBACK, CUSTOMER_CARE, SINGLE_USE_VOUCHER, SIGNUP_REFERRAL, GEOFENCE_PROMOTION, GEOFENCE_SURCHARGE, FREE_REWARD, EARLY_RETURN_DISCOUNT No Only amountNet / amountGross available

appliedRebates is only populated for ended rentals. It is empty for rentals in RESERVATION or ACTIVE state.

How to read free-minutes consumption on a rental:

consumed minutes = voucherable.benefits[FreeMinutes].freeMinutesCount
  (for the portion actually applied to this rental)

monetary discount = appliedRebates[].amountGross

For types without a voucherable, the monetary discount in amountGross is the only signal available. To derive consumed minutes, divide amountGross by the applicable per-minute rate.

Example — promotion with 10 free minutes, full ride is 10 minutes on a bike (€0.15/min):

GET /rentals/98765

{
  "id": 98765,
  "state": "ENDED",
  "totalDuration": 10,
  "sumGross": 0.00,
  "currency": "EUR",
  "price": {
    "priceForDrivingGross": 1.50,
    "rebateGross": 1.50,
    "finalPriceGross": 0.00
  },
  "appliedRebates": [
    {
      "type": "PROMOTION",
      "name": "10 Free Minutes",
      "amountNet": 1.26,
      "amountGross": 1.50,
      "voucherable": {
        "@type": "Promotion",
        "id": 77,
        "name": "10 Free Minutes",
        "benefits": [
          {
            "type": "FreeMinutes",
            "freeMinutesCount": 10.0
          }
        ]
      }
    }
  ]
}

amountGross: 1.50 is the €1.50 that was deducted from the trip cost because of the promotion. freeMinutesCount: 10 tells you the promotion covers 10 minutes — confirming that all 10 minutes of this trip were free.

Example — partial usage: 10 free-minute promotion, only 7 minutes ridden:

"appliedRebates": [
  {
    "type": "PROMOTION",
    "name": "10 Free Minutes",
    "amountNet": 0.88,
    "amountGross": 1.05,
    "voucherable": {
      "@type": "Promotion",
      "id": 77,
      "name": "10 Free Minutes",
      "benefits": [
        {
          "type": "FreeMinutes",
          "freeMinutesCount": 10.0
        }
      ]
    }
  }
]

7 minutes × €0.15/min = €1.05 gross was discounted. The remaining 3 free minutes stay on the promotion for future rentals.

Example — vehicle promotion (no voucherable), 10 free minutes equivalent:

"appliedRebates": [
  {
    "type": "VEHICLE_PROMOTION",
    "name": "Bike Promo",
    "amountNet": 1.26,
    "amountGross": 1.50,
    "voucherable": null
  }
]

For VEHICLE_PROMOTION, only the monetary discount is available. Divide amountGross by the per-minute rate to calculate consumed minutes programmatically.

Migration note for v1 integrations: The v1 field bonusMetersUsed from GET /pricing/reservations/{reservationID} has no direct equivalent in v2. Use appliedRebates[].amountGross for the monetary value consumed, and appliedRebates[].voucherable.benefits[type=FreeMinutes].freeMinutesCount for the configured free-minute count when available.


Common User Workflows

Find Current And Historical Rentals

Task Endpoint
List current user’s rentals GET /rentals
Get rental detail GET /rentals/{rentalId}
List group rentals GET /rentals/user-group/{userGroupId}

Use rental detail after any operation to display the current state, price, vehicle, invoice, and next available actions.

Show A Trip Overview In The App

Use trip overview screens to help users understand the current trip, review past trips, and continue into receipt, invoice, feedback, damage, or support actions. In the app, this usually means two UI levels:

GET /rentals is optimized for overview lists. It returns enough information for cards such as “Trip on 21 May”, “ended in Praterstrasse”, “12 min”, “€4.20”, and “Toyota Yaris / Scooter 123”. Use it for history, active-rental banners, and quick account views. The endpoint is paginated and defaults to newest rentals first.

For a compact in-app card, show only the information a user can scan quickly: state, vehicle, date/time, start/end address, duration or distance, final or estimated price, and a small follow-up indicator for invoice or feedback where relevant. Keep billing details, route map, photos, rebates, and support actions for the trip detail screen.

Recommended list-card fields:

UI element Rental fields
Status badge state, phaseState where available, rideMode
Vehicle label vehicle.name, vehicle.code, vehicle.licensePlate, vehicle.categoryId
Start/end time startTime, driveStartTime, endTime
Start/end place startAddress, endAddress, startPosition, endPosition
Duration and distance totalDuration, distance
Price preview/final price estimatedPrice, price, priceV3, priceV4, priceGross, sumGross, currency
Benefit indicators appliedRebates, pricingOption
Business context type, reason, group, userGroup, balanceName
Follow-up actions feedback, invoiceId, bookingId, activeDeposit

Use GET /rentals/{rentalId} when the user opens a specific trip. The detail response contains richer context and is the better source for a receipt-like screen:

Detail section Rental fields
Trip route encodedPolylineOfRoute, imageOfRouteUrl, startPosition, endPosition
Vehicle vehicle, startSoc, endSoc, startKilometers, endKilometers
Time and distance startTime, driveStartTime, endTime, totalDuration, distance
Price breakdown priceV4, priceV3, price, estimatedPrice, currency, appliedRebates
Invoice and payment invoiceId, invoice, deposit
Add-ons and pricing additions, pricingOption, pricingBundleVersion
Photos and reports fileIds, station, parking details where present
Feedback feedback.rating, feedback.ratingDescription

For active rentals, show estimatedPrice as an estimate and keep refreshing the rental at a responsible interval. For ended rentals, show final price fields and invoice data when available. If invoiceId is present but the full invoice object is not enough for the UI, link to the invoice flow from the Payments And Invoices Guide.

The trip overview should not infer final billing from only the list row. Open the detail view and re-fetch GET /rentals/{rentalId} when the user wants receipt, invoice, feedback, damage, parking-photo, or support actions.

Create A Reservation Or Active Rental

Use POST /rentals.

Common request context:

Field/context Purpose
vehicleId or vehicleCode Vehicle selected from the map or scan flow.
startRentalState RESERVATION or ACTIVE, depending on whether the user reserves or starts immediately.
userGroupCode / type: "BUSINESS" Business account billing where configured.
additions Optional paid or configured additions selected before start.
Pricing option Selected on-demand pricing option where the branch/category supports choices.

Before creating the rental, make sure the user has accepted required T&C and has fulfilled start rental requirements.

Choose Personal Payment Or Business Account

The rental start screen should let the user choose how this trip will be paid before calling POST /rentals.

For a personal rental, load the user’s active payment sources with GET /payment?state=ACTIVE&branchId={branchId} and show the current default source. If the user selects a different card, wallet, or PayPal source, call PUT /payment with the selected sourceId, then re-fetch GET /payment and start the rental without userGroupCode. The rental creation request does not accept a payment-source ID; personal rentals use the user’s current eligible default payment source.

For a business-account rental, load the user’s memberships with GET /groups and show the eligible group as a separate billing option. When the user selects that option, pass the group’s userGroupCode in POST /rentals and set type: "BUSINESS" when the app sends an explicit rental type. The rental is then billed through the configured business account instead of the user’s personal default payment source.

Re-run rental requirements whenever the user changes between personal payment and a business account. Use GET /rentals/requirements with the selected branch/category/vehicle context and include userGroupCode or userGroupId for business rentals. This lets the app explain account-specific blockers such as missing payment setup, missing driving license, unaccepted terms, unpaid invoices, missing business-account approval, or required business context before the user taps start.

If the user adds a new payment method from the start screen, complete the add-payment flow, re-fetch GET /payment, optionally make the new source the default with PUT /payment, and then continue with the rental start. If the user switches to a business account, do not try to pass the personal payment source to POST /rentals; use userGroupCode to select the business billing context.

Select Rental Add-Ons

Rental add-ons are optional extras attached to a rental. They can be physical extras, such as a helmet or child seat, or digital products, such as an additional insurance package that reduces the user’s deductible or adds another rental-specific charge.

Load available add-ons with GET /rentals/additions. Filter the request by the selected vehicleCategoryId and branchId; include userGroupCode when the user selected a business account. For booking-like flows or scheduled pickup windows, also pass bookingStartTime and bookingEndTime so the returned additions match the intended rental window.

Each returned RentalAddition contains:

Field How to use it
code Stable value to pass in additions when creating or updating the rental.
name / description Localized user-facing copy for the start screen.
isInternal Do not display internal additions as selectable user options.
entitled Indicates that the current user is entitled to this addition, for example through a voucher, benefit, subscription, or group setup.
pricingInformation Price context to show next to the add-on before the user starts.

The app can let the user select multiple add-ons. Keep the selected add-on codes as an array and pass them in POST /rentals:

{
  "vehicleId": 12345,
  "startRentalState": "ACTIVE",
  "additions": ["INSURANCE", "HELMET"]
}

If the rental is still in RESERVATION and has not entered ACTIVE, the app can update the selected add-ons with PATCH /rentals/{rentalId} and the new additions array. Once the rental is active, treat add-ons as locked unless the API explicitly allows the update for that tenant and rental type.

Show add-ons as part of the final start confirmation, together with vehicle, payment/business billing context, vouchers, rental requirements, and estimated price. For priced add-ons, include them in the estimate by calling GET /pricing-bundles/pricing-calculator with the same branchId, vehicleCategoryId or pricing bundle context, time window, business context, and selected additions codes. The price response can include additionsPriceGross, which lets the app show the add-on cost separately from driving, parking, unlock, distance, or reservation charges.

For an insurance-style add-on, do not hard-code the legal or deductible text in the app. Display the localized name, description, and price returned by the API/configuration, and make the selected code part of the rental creation request. If the add-on is included because the user has an entitlement, show it as included or discounted according to the returned addition and pricing/voucher information instead of charging it again in the UI.

When an add-on cannot be used, surface the API error as a recoverable start-screen state. Common examples are RA100 when an addition code is unknown and R245 when additions are not supported for the chosen rental type.

Recommended pre-rental sequence:

  1. Resolve the branch and show available vehicles with GET /vehicles.
  2. Open vehicle detail with GET /vehicles/{id} or GET /vehicles/code/{code} for scan flows.
  3. Load category/addition/pricing context with GET /vehicles/categories/{id}, GET /rentals/additions, and GET /on-demand-pricing-options where relevant.
  4. Let the user select one or more add-ons and keep the selected addition codes.
  5. Load payment sources with GET /payment and business memberships with GET /groups when the app supports business rentals.
  6. Let the user choose personal payment or an eligible business account.
  7. Check whether T&C are needed with GET /termsandconditions or branch-specific acceptance state. If needed, accept with POST /termsandconditions.
  8. Check rental requirements with the selected payment/business context; route the user to payment setup, verification, unpaid-invoice payment, or group setup when required.
  9. If business rental is selected, confirm userGroupCode, reason, and cost-center context where configured.
  10. Call POST /rentals with vehicleId or vehicleCode, startRentalState, selected additions, optional paid reservation minutes, optional group context, and optional pricing option.
  11. Store the returned rentalId and immediately render the returned rental state.

Manage A Rental

Task Endpoint
Perform rental operation POST /rentals/{rentalId}/operation
Cancel a reservation DELETE /rentals/{rentalId}
Buy reservation minutes POST /rentals/{rentalId}/buy-reservation
Execute pre-end actions POST /rentals/{rentalId}/execute-pre-end-actions
Check end-rental requirements and surcharges POST /rentals/{rentalId}/check/end
Reserve parking station PUT /rentals/{rentalId}/parking-reservation

If a rental operation returns a concurrent-processing conflict, wait and re-fetch the rental before retrying. End-rental operations can involve vehicle commands, requirement evaluation, pricing, payment capture, invoices, and events.

Sell Additional Reservation Time

Users can purchase additional reservation time while a rental is still in RESERVATION. This lets an app sell predefined extension options such as “add 5 minutes”, “add 10 minutes”, or “add 15 minutes” before the user starts the vehicle.

Call POST /rentals/{rentalId}/buy-reservation?minutes={minutes} with the selected number of minutes. The API returns the updated rental. The backend verifies that the rental still belongs to the user and is still reserved, extends the rental endTime, creates a paid reservation phase, and then opens a new free reservation phase after the paid block.

Recommended app flow:

  1. Show a countdown from the rental’s current reservation endTime.
  2. When the user taps an extension option, confirm the minutes, price, and payment/business billing context.
  3. Call POST /rentals/{rentalId}/buy-reservation?minutes={minutes}.
  4. Re-render the returned rental immediately and update the countdown from the new endTime.
  5. If the call fails because the rental is no longer in RESERVATION, re-fetch GET /rentals/{rentalId} and switch the UI to the current state.

The API accepts the number of minutes, not a package ID. If the operator wants to sell fixed reservation-time packages, model those as app choices backed by the configured reservation pricing. For example, the app can show three buttons for 5, 10, and 15 minutes, call the same endpoint with the selected value, and display the price calculated from the active pricing configuration.

For pricing previews, use the pricing calculator or simulator with the same branch, vehicle category or pricing bundle context, and a reservation-only time window. In the resulting rental or price breakdown, reservation charges appear as reservation pricing, paid reservation phases, or priceForReservationGross/reservation-related fields depending on the price response version.

This feature is configured on the operator side:

Configuration area Operations API guide
Free reservation window, max free reservation minutes, reset buffer, same-vehicle block Operations API Guide - Settings and Operations API Rental Guide
Paid reservation pricing in on-demand pricing bundles Operations API Pricing Guide
Branch/category assignment of the relevant on-demand pricing option Operations API Pricing Guide

For an active rental screen:

  1. Keep the current rental detail available from GET /rentals/{rentalId}.
  2. Offer only operations that make sense for the current state and vehicle/category configuration.
  3. Use START to start a reserved rental.
  4. Use PARK and DRIVE for pause/resume flows where supported.
  5. Use OPEN_TAILBOX only if the vehicle supports it.
  6. Use RENEW_RESERVATION only for reservations where extension is allowed.
  7. Re-fetch the rental after every operation.

For the end-rental flow:

  1. Ask the user to park or dock according to the current branch/category/station rules.
  2. Call POST /rentals/{rentalId}/check/end to surface blockers, required photos, parking restrictions, or surcharges before submitting the final end operation.
  3. If a photo or attachment is required, upload it with POST /files.
  4. Submit POST /rentals/{rentalId}/operation with operationType: "END", plus fileId, parkingReport, vehicleCode, reason, or communicationChannel where relevant.
  5. If the response indicates a failed requirement, show the concrete failed condition and let the user fix it.
  6. When the end operation succeeds, use the returned rental and then re-fetch GET /rentals/{rentalId} if the UI needs invoice/payment finalization details.

Update, Attach Files, And Submit Feedback

Task Endpoint
Update rental metadata or feedback PATCH /rentals/{rentalId}
Submit feedback POST /rentals/{rentalId}/feedback
Link condition files during rental POST /rentals/{rentalId}/files
Upload file POST /files
Get file download information GET /files/{fileId}

Use file uploads for rental photos, vehicle-condition images, damage images, parking photos, or other tenant-configured attachment workflows.

Upload Rental And Condition Images

Images are uploaded first, then linked to the relevant object.

Use POST /files to upload the image as multipart form data. The response contains the file id.

Example upload:

POST /files?public=false&mediaType=image/jpeg&fileName=parking-photo.jpg
Content-Type: multipart/form-data

multipart=<binary image data>

Use public=false for normal user-uploaded rental photos unless the tenant explicitly wants public file access. After upload, use the returned file ID in one of these flows:

Use case Link/upload flow
Vehicle condition image before starting or during a rental POST /rentals/{rentalId}/files with an array of file IDs.
Damage report image Include uploaded file objects in POST /vehicles/{id}/damages.
Parking/end-rental photo while ending Pass fileId in POST /rentals/{rentalId}/operation with operationType: "END".
Additional image after the rental is already ended PATCH /rentals/{rentalId} with fileIds.

For vehicle condition images, link the uploaded files to the rental while it is still in RESERVATION or ACTIVE:

POST /rentals/12345/files
Content-Type: application/json

[98765, 98766]

Use this for pre-trip inspection photos, during-rental vehicle condition photos, or other rental-context images that should be stored with the rental but are not a structured damage report.

Rate A Completed Trip

After the trip is finished, show the feedback screen and submit the user’s rating with POST /rentals/{rentalId}/feedback.

Use this flow:

  1. End the trip with POST /rentals/{rentalId}/operation using operationType: "END".
  2. Re-fetch or use the returned rental and confirm the state is ENDED, ENDED_NO_MOVEMENT, or CANCELLED.
  3. Show the feedback screen with a rating control and optional comment field.
  4. Submit POST /rentals/{rentalId}/feedback.
  5. Use the returned rental to update the trip summary and avoid submitting feedback again.

Example request:

POST /rentals/12345/feedback
Content-Type: application/json

{
  "rating": 5,
  "ratingDescription": "Vehicle was clean and easy to unlock."
}

rating is the numeric trip rating, usually rendered as a 1-to-5 star control. ratingDescription is the free-text comment from the feedback screen. The comment can be empty or omitted if the user only wants to rate the trip.

The API returns 201 Created with the updated rental. The returned rental includes feedback.rating and feedback.ratingDescription, so the app can show the submitted rating on the receipt or trip-detail screen.

Feedback is owner-only and one-time. If another user submits feedback, the API returns an authorization error. If the rental is still active or already has feedback, the API returns a conflict. In those cases, re-fetch GET /rentals/{rentalId} and update the UI rather than retrying blindly.

Damages And Vehicle Cards

Task Endpoint
List rental damages GET /rentals/{rentalId}/damages
List vehicle damages GET /vehicles/{id}/damages
Submit vehicle damage POST /vehicles/{id}/damages
List vehicle cards/details for active rentals GET /vehicle-cards

Damage submission can be part of pre-rental inspection, active-rental inspection, post-rental feedback, or support flows. Re-fetch the rental or vehicle after submission if the UI depends on updated status.

Use this decision rule:

User action Recommended API
“I want to document the vehicle condition with photos.” Upload images with POST /files, then link them to the rental with POST /rentals/{rentalId}/files while the rental is active/reserved.
“I found a new scratch, broken part, or other damage.” Submit a structured damage report with POST /vehicles/{id}/damages.
“I need to prove where/how I parked at the end.” Upload the image with POST /files, then pass the file ID in the end-rental operation.

To report a damage:

  1. Upload one or more images with POST /files.
  2. Submit POST /vehicles/{id}/damages.
  3. Include branchId, part, optional description, optional severity, optional vehiclePosition and userPosition, and optional currentRentalId.
  4. Include the uploaded files in the damage payload when the damage should carry photos.
  5. Re-fetch GET /vehicles/{id}/damages or GET /rentals/{rentalId}/damages if the UI needs to show the updated list.

Example:

POST /vehicles/345/damages
Content-Type: application/json

{
  "branchId": 3,
  "part": "front_bumper",
  "description": "Scratch on the front bumper before trip start.",
  "severity": "MINOR",
  "currentRentalId": 12345,
  "files": [
    {
      "id": 98765
    }
  ]
}

Use currentRentalId when the damage is being reported in the context of a specific rental. For pre-trip reporting, this is normally the just-created reservation or active rental. For post-trip reporting, use the rental that just ended if the app still has that context.

Existing damage lists are available through:

Parking Photo At Rental End

If the product requires a parking photo or the user wants to document the final parking state, upload the photo before ending the rental and pass the returned file ID in the end operation.

Example:

POST /files?public=false&mediaType=image/jpeg&fileName=end-parking.jpg
Content-Type: multipart/form-data

multipart=<binary image data>

Then end the rental:

POST /rentals/12345/operation
Content-Type: application/json

{
  "operationType": "END",
  "fileId": 98765,
  "parkingReport": {
    "description": "Parked in bay 14 near the north entrance."
  }
}

If the rental is already ended and the app needs to attach an additional image later, use PATCH /rentals/{rentalId} with fileIds:

PATCH /rentals/12345
Content-Type: application/json

{
  "fileIds": [98765]
}

Do not use damage reporting for generic parking proof. Use damage reporting only when the user is reporting a concrete vehicle damage.

Driving Log

Driving-log endpoints support branches or vehicle categories where users must record trip log details.

Task Endpoint
Get rental driving log GET /rentals/{rentalId}/driving-log
Submit driving log POST /rentals/{rentalId}/driving-log/submit
Validate driving log GET /rentals/{rentalId}/driving-log/validation
List driving-log entries GET /rentals/{rentalId}/driving-log/entries
Create driving-log entries POST /rentals/{rentalId}/driving-log/entries
Get one driving-log entry GET /rentals/{rentalId}/driving-log/entries/{drivingLogEntryId}
Update one driving-log entry PUT /rentals/{rentalId}/driving-log/entries/{drivingLogEntryId}
Delete one driving-log entry DELETE /rentals/{rentalId}/driving-log/entries/{drivingLogEntryId}

Most Relevant APIs

Area Endpoints
Rentals GET /rentals, POST /rentals, GET /rentals/{rentalId}, PATCH /rentals/{rentalId}, DELETE /rentals/{rentalId}
Operations and checks POST /rentals/{rentalId}/operation, POST /rentals/{rentalId}/buy-reservation, POST /rentals/{rentalId}/execute-pre-end-actions, POST /rentals/{rentalId}/check/end, PUT /rentals/{rentalId}/parking-reservation
Requirements and additions GET /rentals/requirements, GET /rentals/additions
Damage and files GET /rentals/{rentalId}/damages, GET /vehicles/{id}/damages, POST /vehicles/{id}/damages, POST /rentals/{rentalId}/files, POST /files, GET /files/{fileId}
Feedback and vehicle cards POST /rentals/{rentalId}/feedback, GET /vehicle-cards
Driving log GET /rentals/{rentalId}/driving-log, POST /rentals/{rentalId}/driving-log/submit, GET /rentals/{rentalId}/driving-log/validation, GET/POST /rentals/{rentalId}/driving-log/entries, GET/PUT/DELETE /rentals/{rentalId}/driving-log/entries/{drivingLogEntryId}

Implementation Notes