Renting Products
The Rentals module lets a catalog product be rented for a time period. You mark a product as rentable (with a capacity and rental terms), check date-ranged availability, create a rental agreement, confirm it to hold capacity, and record returns. SynthesQ guarantees a product is never double-booked beyond its capacity.
All endpoints are under /api/v1/rentals and require a Bearer token.
Catalog products are referenced by id
Rentals never modifies your catalog. A rentable product simply points at an existing product by its product_id. Create the product through the Operations API first.
Concepts
- Rentable product — a catalog product you have enabled for rent, with a pooled
capacityand rentalterms(unit period + min/max duration). - Rental agreement — the contract with a customer. It owns one or more lines.
- Line — a single dated hold:
[period_from, period_to)against a rentable product, for aquantity. The line is the reservation. - Availability —
capacityminus the peak number of overlapping held lines over the requested window. It is computed live, so it is always correct.
Rental terms
| Field | Meaning |
|---|---|
unit_period | Granularity for durations. One of: hour, day, week, month, year. |
min_duration | Minimum number of unit_periods a single hold may span (≥ 1). |
max_duration | Maximum number of unit_periods, or omit for unbounded. |
auto_release_default | Whether holds free capacity automatically at their end date (see below). |
capacity | How many units may be held at the same time. |
Agreement lifecycle
| Status | Meaning | Can transition to |
|---|---|---|
draft | Created, capacity not yet held. | confirmed, cancelled |
confirmed | Capacity is held for every line. | completed, cancelled |
completed | All lines have ended/returned. | — (final) |
cancelled | Cancelled; capacity freed. | — (final) |
draft ──confirm──▶ confirmed ──(all lines ended)──▶ completed
│ │
└──cancel──▶ cancelled◀──cancel──┘Auto-release vs. manual return
Each line is either auto-release or manual-release (resolved when you confirm, from the agreement's auto_release override or the product's auto_release_default):
- Auto-release — the hold frees capacity automatically at
period_to. Good for time-boxed bookings (e.g. a nightly room booking). - Manual-release — the hold persists until you record a return. Past its
period_towithout a return, the line is overdue and appears in the overdue feed.
Line states (read-only)
Each line reports a derived state:
| State | Meaning |
|---|---|
scheduled | The hold has not started yet. |
active | Currently within [period_from, period_to). |
completed | Returned, or auto-released past its end. |
overdue | Manual-release, past its end, not yet returned. |
Walkthrough
1. Make a product rentable
curl -X POST https://api.synthesq.com/api/v1/rentals/rentable-products \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"product_id": "01hwxyz123abc456def789ghi0",
"capacity": 3,
"unit_period": "day",
"min_duration": 1,
"max_duration": 30,
"auto_release_default": true
}'Returns 201 with the rentable product. Re-posting for the same product_id updates it (there is one rentable record per product).
2. Check availability for a window
curl "https://api.synthesq.com/api/v1/rentals/rentable-products/01hwxyz123abc456def789ghi0/availability?from=2026-08-02&to=2026-08-04" \
-H "Authorization: Bearer <token>"{
"success": true,
"data": {
"product_id": "01hwxyz123abc456def789ghi0",
"period": { "from": "2026-08-02T00:00:00+00:00", "to": "2026-08-04T00:00:00+00:00" },
"capacity": 3,
"available": 2
}
}Half-open intervals
Periods are half-open: a hold that ends exactly when another begins does not collide, so back-to-back bookings both fit.
3. Create a draft agreement
curl -X POST https://api.synthesq.com/api/v1/rentals/agreements \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{
"customer_id": "01hwxyzcustomer000000000aa",
"lines": [
{
"product_id": "01hwxyz123abc456def789ghi0",
"quantity": 1,
"period_from": "2026-08-01",
"period_to": "2026-08-05"
}
]
}'A draft does not hold capacity yet. Each line's period must be in the future, end after it starts, and fit the product's rental terms; the product must be rentable.
4. Confirm to hold capacity
curl -X POST https://api.synthesq.com/api/v1/rentals/agreements/01hwxyzagreement0000000aa/confirm \
-H "Authorization: Bearer <token>"Returns 200 with data.status.value = confirmed. If the window is already fully booked, you get 409:
{ "success": false, "message": "Insufficient availability for [..]: requested 1, available 0" }No double-booking
Confirmation is the point where capacity is checked and held under a lock. Two confirmations competing for the last unit cannot both succeed — one gets 409.
5. Record a return (manual-release lines)
curl -X POST https://api.synthesq.com/api/v1/rentals/agreements/01hwxyzagreement0000000aa/lines/01hwxyzline00000000000aa/return \
-H "Authorization: Bearer <token>" \
-H "Content-Type: application/json" \
-d '{ "returned_at": "2026-08-05T10:00:00Z" }'When the last open line is returned (or auto-releases), the agreement becomes completed. Omit returned_at to use the current time.
6. Cancel
curl -X POST https://api.synthesq.com/api/v1/rentals/agreements/01hwxyzagreement0000000aa/cancel \
-H "Authorization: Bearer <token>"Cancelling a confirmed agreement frees its held capacity immediately.
Finding overdue rentals
curl https://api.synthesq.com/api/v1/rentals/agreements/overdue \
-H "Authorization: Bearer <token>"Returns the lines that are confirmed, manual-release, past their end date, and not yet returned.
Roles
| Role | Capabilities |
|---|---|
rentals-admin | Everything, including configuring rentable products and cancelling agreements. |
rentals-agent | View, create, confirm, and record returns — but not configure products or cancel. |
See also
- Interactive API Explorer — full request/response schemas for every endpoint.