HQ Rental Software
    • Getting started
    • Authentication
    • Base URLs, regions and versioning
    • Errors
    • Responses and pagination
    • HQ concepts and glossary
    • Custom fields and item types
    • Dates, time zones and money
    • Filtering and incremental sync
    • Guide: build a booking engine on your website
    • Guide: connect an OTA or broker
    • Guide: sync your fleet and prices to a website
    • Guide: sync invoices and payments to accounting
    • Guide: sync customers with a CRM
    • Guide: take payments
    • Guide: bill tolls and fines
    • Rate limits and idempotency
    • Webhooks
    • Car Rental
      • Comments
        • List the comments of a record
        • Create a comment
        • Update a comment
        • Delete a comment
        • List the comments of a reservation
        • Add a comment to a reservation
        • Delete a reservation comment
      • Currencies
        • List currencies
      • Emails
        • List email templates
        • Send an email template for a record
        • Send the reservation confirmation email
        • Send the rental agreement email
        • List the email templates of a reservation
        • Send an email template for a reservation
        • Create a quote and email it
      • Addresses
        • List the addresses of a record
        • Create an address
        • Get an address
        • Update an address
        • Delete an address
      • Fields
        • List the fields of a record type
        • Get a field by its column
        • List the customer form fields (booking step 5)
      • Blocked Days
        • List blocked days
      • Customer Credits
        • List the credit transactions of a customer
        • Add credit to a customer
        • Update a credit transaction
        • Delete a credit transaction
      • Fines
        • List fines
        • Create a fine
        • Get a fine
        • Update a fine
        • Delete a fine
      • Packages
        • List package items
        • Get a package item
        • List packages
        • Get a package
      • Quotes
        • List quotes
        • Get a quote
      • Rate Types
        • List rate types
        • Create a rate type
        • Get a rate type
        • Delete a rate type
        • Update a rate type
      • Rates
        • List rates
        • Create a rate
        • Get a rate
        • Delete a rate
        • List rates (v2)
        • Update a rate
      • Reservation Attempts
        • List reservation attempts
        • List reservation attempts by email
      • Extensions
        • List the extensions of a reservation
        • Extend a rental
        • Delete an extension
      • External Charges
        • List the external charges of a reservation
        • Add an external charge to a reservation
        • Delete an external charge
      • Adjustments
        • List the adjustments of a reservation
        • Add an adjustment to a reservation
        • Delete an adjustment
      • Payments
        • List the payments of a reservation
        • Record a payment on a reservation
        • Update a payment
        • Release an offline security deposit
        • Refund an online security deposit
        • Charge the customer's saved card
      • Refunds
        • List the refunds of a reservation
        • Record a refund on a reservation
        • Update a refund
      • Reservations
        • Confirm a reservation
        • Cancel a reservation
        • Set a reservation to pending
        • Set a reservation to quote
        • Mark a reservation as no-show
        • Mark a reservation as ready for pick-up
        • Get the options for the dates step (booking step 1)
        • Validate dates and list available vehicle classes (booking step 2)
        • Change the vehicle class of a reservation
        • List additional charges for a vehicle class (booking step 3)
        • Price a vehicle class with selected charges (booking step 4)
        • Create or update the booking customer (booking step 6)
        • Create the reservation (booking step 8)
        • Update a reservation
        • List reservations
        • Get the rental agreement link
        • Mark the rental agreement as signed
        • Get a reservation
        • Assign a vehicle to a reservation
        • Detach the vehicle from a reservation
        • List the vehicles available for a reservation
        • List the free vehicle class upgrades of a reservation
        • Apply a free vehicle class upgrade
        • Upload the driver signature
        • Upload pick-up or return photos
        • Search availability and prices for all vehicle classes
        • List reservations (API v2)
      • Vehicle Replacements
        • List the vehicle replacements of a reservation
        • Replace the vehicle of a rental
        • Delete a vehicle replacement
      • Reservation Agents
        • List the users that can be assigned as agents
        • Assign the agents of a reservation
        • Assign the return agents of a reservation
      • Seasons
        • List seasons
        • Create a season
        • Get a season
        • Update a season
        • Delete a season
      • Security Deposits
        • List security deposit rules
        • Get a security deposit rule
      • Availability
        • List availability of vehicle classes
        • Get availability of a vehicle class
      • Driver Licenses
        • Read a driver license barcode
        • Save a driver license barcode to a reservation customer
        • Upload a driver license image for a reservation customer
    • Filters
      • List filter types and operators
    • Contacts
      • List contact categories
      • Get a contact category
      • List contacts of a category
      • Create a contact
      • Get a contact
      • Update a contact
      • Merge contacts
    • Fleets
      • Additional Charges
        • List additional charges
        • Get an additional charge
      • Features
        • List features
        • Get a feature
      • Locations
        • List locations
      • Blocked Periods
        • List the blocked periods of a vehicle
        • Create a blocked period
        • Update a blocked period
        • Delete a blocked period
      • Branches
        • List vehicle makes
        • Get a vehicle make
        • List branches
      • Damages
        • List the damages of a vehicle
        • Create a vehicle damage
        • Get a vehicle damage
        • Update a vehicle damage
      • Vehicles
        • Models
          • List vehicle models
          • Get a vehicle model
        • Types
          • List vehicle types
          • Get a vehicle type
        • List the maintenance status of a vehicle
        • List vehicles
        • Get a vehicle
        • Update a vehicle
        • List vehicles for toll matching
      • Relocations
        • Create a relocation
        • Delete a relocation
        • List the relocations of a vehicle
      • Telematics
        • List the OBD readings of a vehicle
        • List OBD readings of all vehicles since a reading ID
        • List the telematics alerts of a vehicle
        • List the trips of a vehicle
        • List vehicle alert types
      • Maintenance
        • List repair orders
        • Create a repair order line
        • Update a repair order line
        • Delete a repair order line
        • Get a repair order
        • List maintenance types
      • Vehicle Classes
        • List vehicle classes
        • Get a vehicle class
    • Payment Gateways
      • List saved credit cards of a customer
      • Delete a saved credit card
      • List payment methods
      • Get a payment method
      • Get a payment button
      • Get a payment transaction by UUID
      • Create a payment transaction
      • Refund a payment transaction
      • Re-check a payment transaction
      • List payment transactions
    • Sheets
      • List sheet items
      • Create a sheet item
      • Get a sheet item
      • Update a sheet item
      • List sheets
      • Get a sheet
    • Files
      • List files of a record
      • Upload a file
      • Delete a file
    • Inventory
      • List inventory categories
      • Get an inventory category
      • Shows a list of inventory items
      • Finds inventory item by id
      • Finds inventory price by id
      • shows a list of inventory purchase order
      • Create purchase order
      • Finds purchase order by id
      • Returns report of purchase order
      • Cancels purchase order by id
      • Finds inventory stock by id
    • Invoice
      • List invoices available as e-invoices
      • Download e-invoices
      • Create invoice item
      • List invoice payments
      • Create an invoice payment
      • Get an invoice payment
      • Update an invoice payment
      • Spread a payment over a contact's open invoices
      • List invoices
      • Create an invoice
      • Get an invoice
      • Email an invoice
      • Void an invoice
      • Download an invoice PDF
    • Audit Logs
      • Lists the audit log entries
    • Countries
      • List countries
    • Taxes
      • List taxes
      • Get a tax
    • Users
      • List users
    • Products
      • Categories
        • List product categories
        • Create a product category
        • Update a product category
        • Delete a product category
      • List products
      • Create a product
      • Update a product
      • Delete a product
    • Schemas
      • RequestBodies
      • Money
      • SaveRepairOrderLine
      • ErrorBusinessRule
      • SaveBlockedPeriod
      • ErrorValidation
      • SaveVehicleDamage
      • ErrorNotFound
      • ErrorUnauthorized
      • ReservationSummary
      • ReservationTotal
      • AvailableVehicleClass
      • AdditionalCharge
      • ReservationOverview
      • ReservationPayment
      • FleetsPageInfo
      • FleetsEmptySuccess
      • VehicleDamage
      • BillingAmount
      • InvoiceLine
      • ReservationRefund
      • CustomField
      • Comment
      • PaginationFields
      • Country
      • CustomFieldAddress
      • FilterDescriptor
      • Tax
      • VehicleClassAvailability
      • CustomerCreditTransaction
      • DriverLicenseData
      • DriverLicenseResult
      • Fine
      • FineInput
      • PackageItem
      • Package
      • Quote
      • RateType
      • RateTypeWrite
      • RatePriceInterval
      • RateRecord
      • RateWrite
      • ReservationAttempt
      • ReservationExtension
      • ReservationAdjustment
      • ReservationStatusResult
      • VehicleReplacement
      • ReservationRecord
      • ReservationListItem
      • ReservationListPage
      • ReservationDetail
      • ReservationOverviewWithVehicles
      • Season
      • SeasonWrite
      • SecurityDepositRule
      • OtaVehicleClassAvailability
      • RateV2
      • ReservationDriverV2
      • ReservationListItemV2
      • ContactCategory
      • Contact
      • ContactInput
      • AttachedFile
      • FleetAdditionalCharge
      • Branch
      • VehicleFeature
      • Location
      • VehicleMaintenanceStatus
      • RepairOrder
      • ObdReading
      • VehicleAlert
      • VehicleTrip
      • BlockedPeriod
      • VehicleMake
      • VehicleClassImage
      • VehicleClassFeature
      • VehicleClass
      • VehicleRelocation
      • VehicleType
      • Vehicle
      • InventoryCategory
      • InvoicePayment
      • Invoice
      • InvoiceDetail
      • SavedCreditCard
      • PaymentGatewaySummary
      • PaymentMethod
      • PaymentTransaction
      • ProductCategory
      • Product
      • SheetItem
      • SheetItemInput
      • Sheet

    Guide: build a booking engine on your website

    This guide is for rental companies, and the developers they hire, that build their own booking form on their website instead of using HQ's ready-made booking snippets.
    The flow follows the steps of HQ's own booking engine: dates, vehicle class, extras, price, customer, driver's license, and confirmation.
    The booking steps are stateless.
    The reservation is created only in the last step, and no step remembers what an earlier one received, so send the full booking context again on every call: dates, times, locations, brand_id, vehicle_class_id from step 3 on, and the selected additional_charges from step 4 on.
    Step 6 does save the customer, and the reservation attempt below is recorded from step 2 on.

    Before you start#

    Load your locations, vehicle classes and extras as described in Guide: sync your fleet and prices to a website.
    Check the role of the API user.
    For administrators, and for roles that do not set Can skip date validations to Deny, step 2 skips the minimum and maximum rental period, the advance booking time and the allowed times.
    For a public website, use a user whose role sets it to Deny, or enforce those rules yourself.
    Send the same reservation_attempt_uuid, your own identifier for the visitor's session, on every step.
    HQ records the booking as a reservation attempt, so you can follow up on abandoned bookings, and closes it when the booking is confirmed.

    Step 1 - Build the dates form#

    GET /car-rental/reservations/dates?brand_id=1 returns what you need for the first form: pick-up and return locations, their opening hours, default and minimum dates, rental period limits and the age ranges you can send later as customer_age.

    Step 2 - Validate the dates and list vehicle classes#

    POST /car-rental/reservations/dates with pick_up_date, pick_up_time, return_date, return_time, pick_up_location, return_location and brand_id validates them against your opening hours and rental rules.
    It returns the vehicle classes that have a rate for the period, with their availability and price.
    Offer only the classes with availability.selectable true and availability.quantity greater than 0.

    Step 3 - List the extras#

    GET /car-rental/reservations/additional-charges with the booking context and the chosen vehicle_class_id returns the extras, insurances and fees that can be added, with their prices.
    Charges with mandatory true are always included.
    Charges selected by default, such as those with selected true, are added by HQ on steps 4, 6 and 8 even when you leave them out of additional_charges[].
    When the visitor can untick them, send includes_selected_by_default_additional_charges=false (the string false) on those steps and list in additional_charges[] every charge the visitor kept.
    Build the selection from each charge: send {id} for an only_one charge, and a key of its dropdown_options ({id}_{quantity}) for a multiple charge.
    A charge with distance_package_rates true is a mileage package: send a key of its distance_package ({id}_{distance}, such as 12_100) instead.
    With only {id}, no package is matched and the charge is priced at zero.

    Step 4 - Price the selection#

    POST /car-rental/reservations/additional-charges with the booking context and additional_charges[] returns the full price breakdown.
    data.total holds the total, the amount due and the security deposit, ready for your summary.
    HQ can add more charges here, such as location or outside-hours fees, so treat selected_additional_charges in this response as the final selection.
    To apply a coupon configured in HQ, add coupon_code; separate several codes with commas.
    An invalid code returns a business-rule error, so show its message next to the coupon field.
    manual_discount, with manual_discount_is_percentage=1 for a percentage, needs the role permission Can add Manual Discount? and is meant for internal tools, not for a public website.
    Steps 3 and 4 share a limit of 60 requests per minute per user (see Rate limits and idempotency).

    Step 5 - Build the customer form#

    GET /car-rental/reservations/fields/customer returns the fields of your customer form, in order, with their label, type and required flag.
    It also returns contact_category_id, the contact category your customers are saved in.
    When it is null, no customer category is set in the Car Rental settings, and step 6 returns 404 until one is set.
    The response has no success envelope.

    Step 6 - Save the customer#

    POST /car-rental/reservations/customer with the booking context and the form values saves the customer and checks the driver against the age and driver's license rules of the vehicle class.
    Send first_name, last_name and birthdate by name, and every other field as field_<id> (see Custom fields and item types).
    Store data.customer.id: it is the customer_id of the booking.
    Without contact_id, a new contact is created on every call, even when a contact with the same email exists.
    When the visitor goes back and edits the form, send the stored ID as contact_id, or identify the visitor with external_contact_type and external_contact_id from your own system.
    When you update a contact this way, the form fields you leave out are cleared; send ignore_empty_fields=1 to keep the ones you do not send.

    Step 7 - Upload the driver's license (optional)#

    POST /files/upload as multipart/form-data attaches the license image to the customer:
    filename is required and becomes the file's label.
    item_type is contacts. followed by the contact_category_id from step 5.
    item_id is the customer ID from step 6.
    field_id is the id of the license field in step 5.
    To send the image as base64 instead, see POST /files/upload.

    Step 8 - Confirm the booking#

    POST /car-rental/reservations/confirm with the booking context, the same additional_charges[] and coupon_code, and customer_id creates the reservation.
    Send an Idempotency-Key header, so that a retry after a timeout does not create a second booking (see Rate limits and idempotency).
    Store data.reservation.id.
    HQ emails the customer a confirmation unless your settings disable confirmation emails for API bookings; send skip_confirmation_email=1 when your website sends its own.

    Take the payment#

    To charge the customer online when they book, add return_payment_link=1, payment_method_id and payment_external_redirect, the page the customer returns to after paying.
    The response has the link in data.transaction.payment_link.
    See Guide: take payments for these fields, for how to choose the payment method and for how to check that the customer paid.
    Show the payment page in one of two ways:
    In an iframe on your website, so the customer stays on your site.
    HQ allows its payment page to be framed.
    Some gateways change their page during the payment, for example for 3-D Secure, so test every gateway you use.
    In a new tab or a redirect, which works with every gateway.
    Put the payment gateway in test mode while you build, and check that the payment appears on the reservation in HQ and in the gateway.

    Change a booking#

    POST /car-rental/reservations/{reservation_id}/update changes a booking and prices it again.
    Send only what changes:
    ChangeSend
    Datespick_up_date with pick_up_time, return_date with return_time. A date without its time is ignored.
    Locationspick_up_location and return_location, or custom with pick_up_location_custom and return_location_custom. A pick-up location of another branch also needs a vehicle_class_id of that branch.
    Vehicle classvehicle_class_id. Add free_upgrade=1 to give the customer the new class at the price of the class they booked. The class must be available and belong to the booking's branch.
    Extrasadditional_charges[] with the full new selection: it replaces the current one, so leave a charge out to remove it.
    Customercustomer_id of the other contact, in a call of its own.
    Couponadd_discount=1 with coupon_code, or remove_discount=1 with coupon_code. When the reservation has a manual discount and the API user's role can add one, resend manual_discount and manual_discount_is_percentage with add_discount=1: leaving them out removes it.
    Always resend additional_drivers with the full list of their contact IDs.
    See POST /car-rental/reservations/{reservation_id}/update for the statuses that allow each change.
    The update can succeed without applying everything you sent: an extra that is not available leaves the selection unchanged, and a coupon that cannot be applied is ignored.
    Before you show a change as done, check selected_additional_charges and applicable_discounts in the response.
    To record a payment taken at the counter or charge the customer's saved card later, see Guide: take payments.

    Errors to handle#

    Failed steps return "success": false, usually with HTTP 200: errors holds the messages per field and errors.error_message all of them, to show the customer (see Errors).
    On confirm, such a failure also uses up the Idempotency-Key, so send a new key once the request is fixed.
    A confirm retried with an Idempotency-Key already used returns HTTP 422, with the ID of the reservation the first request created in errors.idempotency_value.
    When it holds an ID, the booking exists, so show it instead of an error.
    When it is empty, look the reservation up before you retry (see Rate limits and idempotency).
    "The selected vehicle class is not available anymore": the class sold out while the customer was filling in the form.
    Send them back to step 2, and confirm with a new Idempotency-Key.
    Modified at 2026-10-29 14:10:30
    Previous
    Filtering and incremental sync
    Next
    Guide: connect an OTA or broker
    Built with