π Rental
Car rental management with bookings, returns, insurance, invoicing, and add-ons.
Overview
The Rental API simulates a car rental service with a full lifecycle: browse the fleet, make bookings, get approved, return cars, and pay invoices. It includes manager-only operations (approve, return, fleet management), insurance options, optional add-ons, and a payment method vault.
15000 = $150.00.Quick Start
curl "https://qacloud.dev/api/rental/cars?start_date=2026-05-01&end_date=2026-05-05" \ -H "x-api-key: YOUR_KEY"
curl -X POST https://qacloud.dev/api/rental/bookings \
-H "x-api-key: YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"car_id": "CAR_UUID",
"start_date": "2026-05-01",
"end_date": "2026-05-05",
"insurance_type": "BASIC"
}'
Car & Booking Statuses
Car Statuses
RENTED cannot have its status changed manually β a return must be processed first. Returns 409.Booking Statuses
Insurance Options
Fleet Management
Each API key manages its own fleet. A car record contains: make, model, year, daily_rate (cents), status, image_url, and deletion state.
Soft delete (DELETE /cars/:id) sets a deleted_at timestamp rather than physically removing the record. Use ?show_deleted=true on GET /cars to see deleted cars.
Date Availability Filter
Pass ?start_date= and ?end_date= to GET /cars to receive only cars that are AVAILABLE and have no conflicting PENDING/APPROVED/ACTIVE bookings during that period.
Booking Lifecycle
Rental day calculation is inclusive on both ends: a booking from May 1 to May 5 is 4 days. The total cost = daily_rate Γ days + insurance_rate Γ days + add-on costs.
Availability Conflict Detection
Creating a booking checks for overlapping PENDING/APPROVED/ACTIVE bookings. A conflict returns 409 Conflict.
Manager Operations
- Approve: PATCH /bookings/:id/approve β sets car to RENTED
- Return: POST /bookings/:id/return β triggers invoice generation, sets car to RETURNED
- View all: GET /bookings/all β see all customers' bookings (regular users only see their own)
Invoices
An invoice is automatically generated when a return is processed. It includes rental cost, insurance cost, add-on costs, and any damage fees. Invoices start as UNPAID.
Use PATCH /invoices/:id/pay to mark an invoice as paid. Payment is linked to the user's default payment method if one is set.
Payment Methods
Users can store multiple payment methods (e.g. credit cards). One card can be set as default. The default is used automatically when paying an invoice.
Add-ons
Add-ons are optional extras (GPS, child seat, roadside assistance, etc.) that can be added to a booking at creation time via addon_ids. Each add-on has a flat rate in cents.
Managers create and update add-ons via POST/PUT /addons. Regular users can only list available add-ons.
Cars API
| Query Param | Description |
|---|---|
start_date | ISO date β with end_date, filters to available cars only |
end_date | ISO date β must be after start_date |
status | AVAILABLE | RENTED | RETURNED | DAMAGED | IN_SHOP |
show_deleted | true to include soft-deleted cars |
image_url | true to filter cars with images; false to strip image_url from response |
| Field | Required | Description |
|---|---|---|
make | required | e.g. Toyota |
model | required | e.g. Camry |
year | required | Integer year |
daily_rate | required | Integer in cents (e.g. 8500 = $85/day) |
image_url | optional | URL to car photo |
Returns the full car record including current status.
Update make, model, year, daily_rate, or image_url. Cannot change status via this endpoint β use /status instead.
| Field | Required | Description |
|---|---|---|
status | required | AVAILABLE | RETURNED | DAMAGED | IN_SHOP (RENTED is auto-set via booking approval) |
Returns 409 if car is currently RENTED β process a return first.
Sets deleted_at on the car. The car no longer appears in availability results but booking history is preserved.
Bookings API
Returns all bookings created by the current API key user.
Returns all bookings across all users in the system. Manager-level endpoint.
| Field | Required | Description |
|---|---|---|
car_id | required | UUID of the car to book |
start_date | required | ISO date string |
end_date | required | ISO date string, must be after start_date |
insurance_type | optional | BASIC | FULL | OWN. Default: OWN |
addon_ids | optional | Array of add-on UUIDs |
notes | optional | Customer notes |
Changes booking status to APPROVED and sets the car status to RENTED.
Cancels the booking and frees up the car. Can be done by the customer (own booking) or a manager.
| Field | Description |
|---|---|
damage_notes | Optional description of any damage found |
damage_fee | Damage charge in cents to add to the invoice |
mileage_returned | Odometer reading at return |
Automatically generates an invoice and sets car to RETURNED.
Invoices API
Returns all invoices with status (UNPAID/PAID), line items, and totals in cents.
Marks the invoice as PAID. Uses the default payment method if one is stored.
Payment Methods API
Returns all payment methods for the current user. Indicates which is the default.
| Field | Required | Description |
|---|---|---|
card_last4 | required | Last 4 digits |
brand | optional | e.g. Visa, Mastercard |
exp_month | optional | 1β12 |
exp_year | optional | 4-digit year |
Clears the default flag from all other methods and sets it on this one.
Permanently removes the payment method.
Add-ons API
Returns [{ id, name, description, price_cents }]
| Field | Required | Description |
|---|---|---|
name | required | e.g. GPS Navigator |
price_cents | required | Flat fee in cents per booking |
description | optional | Short description |
Update name, price_cents, or description.
Test Cases
Steps: Create a booking for car X on May 1β5. GET /cars?start_date=2026-05-02&end_date=2026-05-04 β car X must NOT appear in results (conflict overlap).
Steps: Create booking for car X on May 1β5 (PENDING). Attempt a second booking for same car, overlapping dates β expect 409 Conflict.
Steps: Create booking β approve β return with no damage β GET /invoices β verify invoice created with correct total (daily_rate Γ days + insurance).
Steps: PUT /cars/:id/status with { "status": "RENTED" } β expect 400 Bad Request (RENTED is set automatically).
Steps: Approve a booking (car becomes RENTED) β PUT /cars/:id/status with "AVAILABLE" β expect 409: cannot change status from RENTED.
Steps: Create 3-day booking with FULL insurance ($35/day) β complete return β verify invoice includes $105 insurance line item.
Steps: DELETE /cars/:id β GET /cars β car does not appear. GET /cars?show_deleted=true β car appears with deleted_at set.
Steps: Process return with damage_fee: 15000 ($150) β GET /invoices β verify damage fee line item present in invoice total.