- Base URL and sign-in
- Who may do what
- Sub-rentals
- Statuses
- The sub-rental object
- GET /wc-sibooking/v1/subrentals
- GET /wc-sibooking/v1/subrentals/shortages
- GET /wc-sibooking/v1/subrentals/{id}
- POST /wc-sibooking/v1/subrentals
- PATCH /wc-sibooking/v1/subrentals/{id}
- POST /wc-sibooking/v1/subrentals/{id}/status
- POST /wc-sibooking/v1/subrentals/{id}/receive
- POST /wc-sibooking/v1/subrentals/{id}/return
- GET /wc-sibooking/v1/subrentals/{id}/charges
- POST /wc-sibooking/v1/subrentals/{id}/charges
- Suppliers
- Examples
- Hooks
The REST API for Sub-Rentals: list and read the sub-rentals that cover short bookings, see which bookings are still short, create a cover, move a sub-rental through its statuses, count units in and out, add supplier charges, and manage the suppliers. Everything the Sub-rentals screens do goes through these endpoints, so an outside system (a purchasing tool, a warehouse app, your own dashboard) can do the same. The setup and the conventions shared by every endpoint (keys, errors, pagination) are in <a href=”/docs/rest-api/”>REST API overview and authentication</a>.
Base URL and sign-in #
| Namespace | What lives there | Needs |
|---|---|---|
/wp-json/ | subrentals (list, create, read, update, status, receive, return, charges, shortages) and suppliers | Sub-Rentals, with Rentals & Bookings Regular |
wc-sibooking/v1takes a WooCommerce REST API key (WooCommerce > Settings > Advanced > REST API) sent as HTTP Basic, like the other rental endpoints. A read key can call the GET routes; the routes that change something need a read/write key. The key’s user decides what the call may do (next section), so make the key under a user who has the abilities you need.- The routes have been in Sub-Rentals since 1.0.0.
- Send bodies as JSON (
Content-Type: application/json). - Dates are
Y-m-dorY-m-d H:iorY-m-d H:i:sin the store’s time. A bare date means the start of that day forcollect_by, and the end of that day forreturn_by. Responses giveY-m-d H:i:s. - Money is a plain number in the store’s currency (
120or35.5), never in cents. Money fields are sent as a string or a number. - Errors use the WordPress shape
{"code", "message", "data": {"status"}}. The Sub-Rentals codes start withsisubrent_. - Nothing here emails a supplier. Moving a sub-rental to
requestedrecords the move and thesent_attime, and staff still press Send on the screen to email the request.
STORE="https://example.com/wp-json"
curl -u "ck_your_key:cs_your_secret" "$STORE/wc-sibooking/v1/subrentals?segment=open"
Who may do what #
Anyone with manage_woocommerce (shop managers and administrators) has all four Sub-Rentals abilities without any setup, and a role editor can still give or take each one on a role or a user.
| Ability | Who has it | Opens |
|---|---|---|
sisubrent_create | Users with manage_woocommerce, and any role given it | Creating and editing sub-rentals, moving their status (except closing), receiving and returning units |
sisubrent_manage | Users with manage_woocommerce, and any role given it | The suppliers routes, closing a sub-rental, adding charges, a back-dated at on a receive or return |
sisubrent_view_costs | Users with manage_woocommerce, and any role given it | The cost, money and margin fields, and GET /subrentals/ |
sisubrent_approve | Users with manage_woocommerce, and any role given it | Sending or confirming a sub-rental over the approval limit |
operate (Rentals & Bookings) | Users with manage_woocommerce | Listing and reading sub-rentals, and receiving and returning units, for a user who has no Sub-Rentals ability |
A user without the ability gets 401 (not signed in) or 403, code sisubrent_forbidden.
Who sees what in the answers:
- Without
sisubrent_view_costs, a sub-rental comes back without themoneyobject and its lines withoutcost, andfeeson an update is ignored. notescomes back empty unless the user hassisubrent_createorsisubrent_manage. Anoperateuser sees the status and the lines, and no more.
Sub-rentals #
A sub-rental is one supplier order that covers one or more short bookings. Its number is SR- followed by a counter (SR-1104). A sub-rental is created draft.
Statuses #
| Status | Meaning | Can become |
|---|---|---|
draft | Made, not sent | requested, confirmed, cancelled |
requested | Asked of the supplier | confirmed, received, declined, cancelled |
confirmed | The supplier said yes | received, declined, cancelled |
received | The units are in | returned |
returned | The units went back to the supplier | closed |
closed, declined, cancelled | Finished | Nothing |
Moving to the status a sub-rental is already in is accepted and changes nothing. A move not in the table answers 409 with code sisubrent_status. A sub-rental with no lines cannot move to requested, confirmed or received (400, sisubrent_empty). Moving from draft to requested or confirmed also checks the approval limit (Sub-rentals > Settings > Money): a sub-rental over the limit answers 409, sisubrent_approval, unless the user has sisubrent_approve.
The sub-rental object #
| Field | Notes |
|---|---|
id, number | The id and SR-1104 |
status | One of the statuses above |
supplier_id, supplier | The supplier’s id and name |
location_id | The location that takes delivery; 0 = none (Multi Location Inventory) |
delivery_mode | collect (default), to_shop or on_site |
collect_by, return_by | The window the supplier’s units are in your hands |
notes | Staff notes; empty for users who may not see them |
sent_at, confirmed_at, received_at, returned_at, closed_at | Set when the status moved there; null before |
lines | The bookings this sub-rental covers (below) |
money | Only with sisubrent_view_costs (below) |
Each entry in lines:
| Field | Notes |
|---|---|
id | The line id; the key of lines in a receive or return |
booking_id, order_id | The short booking it covers and its WooCommerce order |
product_id, variation_id, product_name | What it covers |
quantity, received_qty, returned_qty | Units ordered, counted in and counted back |
asset_tags | Serial or asset tags written on the line |
cover_state | Whether the line covers its booking, as covers |
cost | The line’s cost; only with sisubrent_view_costs |
money, only with sisubrent_view_costs:
| Field | Notes |
|---|---|
lines | The cost of the lines |
invoice | The supplier’s invoice total, or null until one is entered |
billed_on | The part billed on to customers |
invoice_covers | true when the invoice replaces the line costs in the total |
fees | Fees on the sub-rental |
charges | The sum of the charges |
total | What the sub-rental costs |
revenue, margin, margin_percent | What the covered bookings bring in, the margin on total, and the percent (a string) |
GET /wc-sibooking/v1/subrentals #
The list, the same as the Sub-rentals screen. Needs sisubrent_create, sisubrent_manage or operate.
| Parameter | Notes |
|---|---|
segment | open (default: not closed, declined or cancelled), all, to_send (draft), awaiting (requested), collect (requested or confirmed, collect-by within 7 days), out (received), return_due (received, return-by within the store’s “show as return due” hours), overdue (received, return-by passed), to_close (returned), closed (closed, declined and cancelled). An unknown value reads as open |
supplier_id | Only this supplier’s sub-rentals |
search | Matches the number, the supplier’s name, a product name on a line, or an order id |
page, per_page | Default 1 and 25; per_page is capped at 500 |
Sorted by collect_by, earliest first. The answer is an array of sub-rental objects. The X-WP-Total header holds the count; there is no X-WP-TotalPages.
GET /wc-sibooking/v1/subrentals/shortages #
The bookings the stock cannot hold and nothing covers yet. Needs the same ability as the list.
| Parameter | Notes |
|---|---|
page, per_page | Default 1 and 25; per_page is capped at 500 |
| Field | Notes |
|---|---|
product_id | The product that is short (the stock pool’s product) |
booking_id, order_id | The short booking and its order |
short | How many units are short |
from, to | The span that is short, in store time |
The X-WP-Total header holds the count. A booking leaves this list once a sub-rental covers it, and comes back if that sub-rental is cancelled or declined.
GET /wc-sibooking/v1/subrentals/{id} #
One sub-rental object. Errors: 404 sisubrent_missing when it does not exist.
POST /wc-sibooking/v1/subrentals #
Covers one short booking with a new draft sub-rental. Needs sisubrent_create. It answers 201 with the sub-rental object.
| Parameter | Notes |
|---|---|
booking_id | Integer, required. A booking from the shortages list |
supplier_id | Integer, required. An active supplier |
units | Integer, required. At least the booking’s short |
collect_by, return_by | Strings, required. The supplier’s window. It has to reach over the whole rental: collect earlier or return later than the booking’s own dates |
cost | Optional. The line cost you were quoted. Without it the supplier’s rate for the product is used |
fees | Optional. Fees on the sub-rental |
| Error | When |
|---|---|
409 sisubrent_window | The dates do not cover the rental |
409 sisubrent_units | units is below what is short |
409 sisubrent_ | The booking is not short, or is already covered |
409 sisubrent_approval | The total is over the approval limit and the user has no sisubrent_approve. Nothing is saved |
400 sisubrent_dates | A date is missing or unreadable |
400 sisubrent_ | The supplier is missing or inactive |
400 sisubrent_no_booking | No booking to cover was found |
400 rest_ | A required parameter is missing |
PATCH /wc-sibooking/v1/subrentals/{id} #
Changes dates, delivery, notes or fees (PUT works too). Send only what changes. Needs sisubrent_create. It answers with the sub-rental object.
| Parameter | Notes |
|---|---|
collect_by, return_by | Strings. The return has to be after the collect |
delivery_mode | collect, to_shop or on_site; another value is ignored |
notes | String |
fees | Number or string. Ignored without sisubrent_view_costs |
| Error | When |
|---|---|
404 sisubrent_missing | No such sub-rental |
409 sisubrent_locked | The sub-rental is closed, declined or cancelled |
400 sisubrent_dates | The return is not after the collect, or a date is unreadable |
POST /wc-sibooking/v1/subrentals/{id}/status #
Moves the sub-rental to another status. Needs sisubrent_create; moving to closed needs sisubrent_manage.
| Parameter | Notes |
|---|---|
status | Required. One of the eight statuses. Another value answers 400 rest_invalid_param |
note | Optional. A note kept in the sub-rental’s history |
It answers with the sub-rental object. Errors: 409 sisubrent_status (the move is not allowed), 409 sisubrent_moved (someone changed it at the same moment: read it again), 409 sisubrent_approval, 400 sisubrent_empty, 403 sisubrent_forbidden (closing without sisubrent_manage).
POST /wc-sibooking/v1/subrentals/{id}/receive #
Counts the units in and moves a requested or confirmed sub-rental to received. Needs sisubrent_create or operate.
| Parameter | Notes |
|---|---|
lines | Optional object of line id to units counted, for example {"105": 1}. A line left out counts its whole quantity. A count above quantity is cut to quantity |
at | Optional date and time of the count. Used only for users with sisubrent_manage; everyone else gets the time of the call |
POST /wc-sibooking/v1/subrentals/{id}/return #
The same for giving the units back: moves a received sub-rental to returned and sets returned_qty. Same parameters and errors as receive.
GET /wc-sibooking/v1/subrentals/{id}/charges #
The sub-rental’s charges, oldest first. Needs sisubrent_view_costs.
| Field | Notes |
|---|---|
id | The charge id |
line_id | The line it belongs to, or 0 |
kind | late, damage, loss, freight, cancellation or other |
amount | A number in the store’s currency |
notes | What the charge is for |
rebill_order_id | The customer order it was billed on to, or 0 |
late_bill | true when it was added after the sub-rental finished |
POST /wc-sibooking/v1/subrentals/{id}/charges #
Adds a charge. Needs sisubrent_manage. It answers 201 with the charge object. There is no route to remove or edit a charge: do that on the sub-rental’s screen.
| Parameter | Notes |
|---|---|
kind | Required. late, damage, loss, freight, cancellation or other |
amount | Required. A number above zero |
line_id | Optional. A line id of this sub-rental |
notes | Optional while the sub-rental is open. Required for a late bill |
Suppliers bill late, so a finished sub-rental still takes some charges:
| Status | What it takes |
|---|---|
draft, requested, confirmed, received, returned | Every kind except cancellation |
closed | Every kind except cancellation, as a late bill: notes are required and the charge comes back with late_bill: true |
cancelled | Only cancellation, as a late bill |
declined | Nothing: it never happened |
| Error | When |
|---|---|
409 sisubrent_charge_kind | A cancellation charge on a sub-rental that is not cancelled |
409 sisubrent_locked | Any other kind on a cancelled sub-rental, or any charge on a declined one |
400 sisubrent_charge_note | A late bill without notes |
400 sisubrent_ | amount is zero or less |
403 sisubrent_forbidden | The user lacks sisubrent_manage |
Suppliers #
All the suppliers routes need sisubrent_manage.
The supplier object:
| Field | Notes |
|---|---|
id, active | The id, and whether the supplier is offered in the pickers |
name | Required |
contact, email, phone | Who to ask |
address_1, address_2, city, postcode, country | country is a two-letter code, saved upper case |
notes, terms | Free text |
lead_days | Days of notice the supplier needs, 0 to 365, or null |
GET /wc-sibooking/v1/suppliers #
Active suppliers, sorted by name.
| Parameter | Notes |
|---|---|
search | Matches name, contact or email |
page, per_page | Default 1 and 25; per_page is capped at 500 |
The X-WP-Total header holds the count. A supplier made inactive on the screen is not listed.
GET /wc-sibooking/v1/suppliers/{id} #
One supplier. Errors: 404 sisubrent_.
POST /wc-sibooking/v1/suppliers #
Creates a supplier and answers 201 with it. name is required (400 sisubrent_ when empty); any other field of the object can be sent. The supplier is active. A supplier’s rates per product and its late-fee policy are set on the screen: this route does not take them.
PATCH /wc-sibooking/v1/suppliers/{id} #
Changes the fields you send (PUT works too) and answers with the supplier. Fields you leave out keep their value. Errors: 404 sisubrent_, 400 sisubrent_ (the name was set to empty). There is no route to deactivate or delete a supplier: do that on the screen.
Examples #
Which bookings are short:
curl -u "ck_your_key:cs_your_secret" \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/shortages"
[
{
"product_id": 456,
"booking_id": 773,
"order_id": 7929,
"short": 1,
"from": "2027-02-01 00:00:00",
"to": "2027-03-01 23:59:00"
}
]
Create a supplier, then cover booking 773 with a sub-rental. The supplier’s window starts three days before the rental and ends three days after:
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"name": "Cooper Rentals", "contact": "James Cooper", "email": "[email protected]", "lead_days": 2}' \
"https://example.com/wp-json/wc-sibooking/v1/suppliers"
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"booking_id": 773, "supplier_id": 123, "units": 1, "collect_by": "2027-01-29", "return_by": "2027-03-04", "cost": "120.00", "fees": "10"}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals"
{
"id": 104,
"number": "SR-1104",
"status": "draft",
"supplier_id": 123,
"supplier": "Cooper Rentals",
"delivery_mode": "collect",
"collect_by": "2027-01-29 00:00:00",
"return_by": "2027-03-04 23:59:59",
"lines": [
{
"id": 105,
"booking_id": 773,
"order_id": 7929,
"product_id": 456,
"quantity": 1,
"received_qty": 0,
"returned_qty": 0,
"cover_state": "covers",
"cost": 120,
"...": "..."
}
],
"money": { "lines": 120, "fees": 10, "charges": 0, "total": 130, "...": "..." },
"...": "..."
}
Mark it requested, count it in, count it back, close it, and add a late bill from the supplier:
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"status": "requested", "note": "Sent by phone"}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/104/status"
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"lines": {"105": 1}}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/104/receive"
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" -d '{}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/104/return"
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" -d '{"status": "closed"}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/104/status"
curl -u "ck_your_key:cs_your_secret" -X POST \
-H "Content-Type: application/json" \
-d '{"kind": "late", "amount": "20", "notes": "One extra day"}' \
"https://example.com/wp-json/wc-sibooking/v1/subrentals/104/charges"
The last call answers 201:
{
"id": 30,
"line_id": 0,
"kind": "late",
"amount": 20,
"notes": "One extra day",
"rebill_order_id": 0,
"late_bill": true
}
A cover that does not fit answers 409 and saves nothing:
{
"code": "sisubrent_window",
"message": "Those dates do not cover the rental. Collect earlier or return later.",
"data": { "status": 409 }
}
Hooks #
sisubrent_ fires after every status move made through the API, with the sub-rental id, the old status, the new status and a context array. It is listed in the plugin’s hooks reference, in the plugin’s docs folder.
