View Categories

Launching soon on the Shopify App StoreJoin the waitlist

REST API reference: Late fees

9 min read

The late fee endpoints of the Rentals & Bookings REST API v1. When late fees are on (Settings › Late fees, see Late fees), a late check-in creates a late fee for the order. Staff review it, then it is collected by a payment link on the order, at the counter, or from a held refundable deposit. These endpoints do the same as the Late fees page in the app. The rest of the core REST API is in REST API reference: bookings and availability and REST API reference: warehouse, stock and settings. Keys, limits, pagination and the error format are in the API overview. The same operations are in GraphQL: GraphQL API reference: Late fees.

Every endpoint on this page needs the Rentals & Bookings app. GET needs a read key; everything else needs a key with Allow changes (write). A read key gets 403 rentals_rest_forbidden on a change. The Free plan’s API can read only: a change answers 403 rentals_rest_plan_required with data.plan: "free" and data.required_plan: "regular". The examples use two shell variables:

API="https://YOUR-API-ADDRESS/api/v1"   # the REST address from Settings › API
KEY="sirb_your_secret_key"

Ids in the examples are made up: late fee 12, order 5550001 (#1042), bookings 42 and 43.

The late fee #

One late fee per order, numbered LF-<order number>-<n>. A later late return on the same order adds lines while the fee is accruing or to_review.

FieldNotes
id, numberThe fee’s id and its number, LF-1042-1.
order_id, order_name, customer_idThe Shopify order and customer (numbers).
statusWhere the fee stands (below).
amount, currencyBefore the fee is accepted: the amount in the store currency, before tax. Once it is on the order: what the order owes for it, in the order’s currency, tax included.
amount_shop, shop_currencyThe amount in the store currency, before tax, at every stage.
calculatedWhat the calculation gave, before any change by staff.
adjustedStaff changed an amount or added a line.
taxThe tax on the fee, once known.
so_far, per_dayOnly while stock is still out: the fee so far, and what each further day adds.
long_overdueThe rental is long overdue.
due_back, returned_atThe earliest due moment and the latest check-in, Y-m-d H:i in the store’s time zone.
location_idThe Shopify location of the check-in.
routeOnce accepted: link, counter or deposit.
methodOnce on Shopify: edit (on the order) or invoice (a separate invoice).
paid_via, paid_amount, paid_atOnce paid: link, counter, shopify or deposit; the amount; when (ISO 8601).
counter_methodFor a counter payment: cash, terminal, bank or other.
refundedThe amount refunded so far.
note_customerThe note shown to the customer in the emails.
reason_staff, waive_reasonStaff’s reason for a change, and the reason it was waived.
last_errorWhy charging failed (status failed).
reviewed_at, created_atISO 8601.
linesThe lines (below).
booking_idsThe bookings the fee is for.
payment_urlOnly in GET /late-fees/{id}, and only for a write key: the payment link (Shopify’s page for the order, or the invoice). Anyone with it can pay: keep it private.

Amounts are decimal strings ("25.00").

statusMeaning
accruingStock is still out: the fee grows each day.
to_reviewWaiting for staff to accept, change or waive it.
chargingBeing charged (from the deposit, or added to the order).
pay_link_sentOn the order; the customer has the payment link.
paidPaid.
failedCharging failed: last_error says why.
needs_confirmationShopify’s answer was unclear: check the order.
waivedWaived by staff.
cancelledNothing was late after all (a corrected return time), or the order was cancelled.
refunded, part_refundedRefunded in full or in part.

A line is one late rental item, the fixed late return fee, or a line staff added:

FieldNotes
keyStable key: change a line’s amount with it (flat is the fixed late return fee, x1, x2… the lines staff added).
title, quantityWhat the line is for.
amount, calculatedThe amount (store currency, before tax) and what the calculation gave.
editedStaff changed the amount.
extraA line staff added (cleaning, a lost part).
accruingThe item is still out.
booking_id, due_back, returned_at, late_minutesThe booking, when it was due, when it came back (null while out) and how late it was.

Bookings carry their late fee too: late_fee on a booking (see Bookings) is {id, number, status, amount, currency, so_far, per_day, long_overdue} or null.

Endpoints #

GET /api/v1/late-fees #

Late fees, newest first. Paged with page and per_page; the totals are in the X-Total and X-Total-Pages headers.

ParameterNotes
statusall (default), to_review (to review and failed), unpaid (payment link sent, needs confirmation, charging), accruing (largest first), paid (paid, refunded, part refunded; last paid first) or waived (last waived first).
order_idOnly this order’s fees.
searchA fee number, order name, customer name or email.
curl -s "$API/late-fees?status=to_review" -H "Authorization: Bearer $KEY"
# 200, X-Total: 1
[{"id": 12, "number": "LF-1042-1", "order_id": 5550001, "order_name": "#1042", "customer_id": 7001234,
  "status": "to_review", "amount": "36.00", "currency": "USD", "amount_shop": "36.00", "shop_currency": "USD",
  "calculated": "36.00", "adjusted": false, "tax": null, "so_far": null, "per_day": null, "long_overdue": false,
  "due_back": "2026-11-18 17:00", "returned_at": "2026-11-20 10:15", "location_id": 801,
  "route": null, "method": null, "paid_via": null, "paid_amount": null, "counter_method": null, "paid_at": null,
  "refunded": null, "note_customer": null, "reason_staff": null, "waive_reason": null, "last_error": null,
  "reviewed_at": null, "created_at": "2026-11-20T15:15:02+00:00",
  "lines": [{"key": "b42-m9101", "title": "Touring kayak", "quantity": 1, "amount": "36.00", "calculated": "36.00",
             "edited": false, "extra": false, "accruing": false, "booking_id": 42,
             "due_back": "2026-11-18 17:00", "returned_at": "2026-11-20 10:15", "late_minutes": 2475}],
  "booking_ids": [42]}]

GET /api/v1/late-fees/{id} #

One late fee. With a write key it also has payment_url. An unknown id is 404 rentals_rest_not_found.

curl -s "$API/late-fees/12" -H "Authorization: Bearer $KEY"

PUT or PATCH /api/v1/late-fees/{id} #

Change a fee that is waiting for review (to_review). Only the fields you send change. Answers the fee.

FieldNotes
linesNew amounts by line key: {"b42-m9101": "30.00"}. An item still out can’t be changed.
extraThe lines staff added, as [{"title": "Cleaning", "amount": "15.00"}], up to 10. It replaces the extra lines; [] removes them.
note_customerThe note to the customer in the emails.
reason_staffWhy it was changed (for staff).
curl -s -X PATCH "$API/late-fees/12" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" \
  -d '{"lines": {"b42-m9101": "30.00"}, "extra": [{"title": "Cleaning", "amount": "15.00"}], "reason_staff": "One day forgiven, mud inside"}'

409 rentals_rest_not_reviewable when the fee isn’t waiting for review any more; 400 rentals_rest_invalid_param with data.field for an amount below 0, a line without a title or more than 10 extra lines.

POST /api/v1/late-fees/{id}/accept #

Accept a fee waiting for review: it is collected the way route says. Answers the fee.

FieldNotes
routeauto (default): the store’s first way to collect that can work, as set in Settings › Late fees. link: on the order, and the customer gets the payment link. counter: paid at the counter. deposit: kept from the order’s refundable deposit (Refundable Security Deposits app); the rest of that deposit is refunded.
methodFor counter: cash (default), terminal, bank or other.
toFor link: send the payment link to this email address instead of the customer’s.
curl -s -X POST "$API/late-fees/12/accept" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"route": "link"}'

409 rentals_rest_not_reviewable when it isn’t waiting for review; 400 rentals_rest_no_lines when there is nothing to charge; 400 rentals_rest_no_deposit when no refundable deposit on the order covers the whole fee; 400 rentals_rest_deposit_failed when Shopify refused the deposit refund (the fee stays to review); 400 rentals_rest_no_order when the booking has no Shopify order to add the fee to. Accepting a fee a second time answers it as it is.

POST /api/v1/late-fees/{id}/waive #

Waive the fee. The customer gets no email; lines already on the order are taken off.

FieldNotes
reasonRequired: why it is waived.
curl -s -X POST "$API/late-fees/12/waive" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"reason": "Storm closed the road"}'

400 rentals_rest_reason_required without a reason; 409 rentals_rest_paid for a paid fee (it can only be refunded); 409 rentals_rest_not_waivable when it can no longer be waived.

POST /api/v1/late-fees/{id}/send-link #

Email the payment link again, to the customer or to to.

FieldNotes
toOptional: an email address.

409 rentals_rest_not_unpaid when the fee isn’t waiting for payment; 404 rentals_rest_no_link when there is no payment link yet.

POST /api/v1/late-fees/{id}/counter-payment #

Record a payment taken at the counter. A fee waiting for review is accepted at the counter (it goes on the order and is marked paid); a fee waiting for its payment link is marked paid.

FieldNotes
methodcash (default), terminal, bank or other.
curl -s -X POST "$API/late-fees/12/counter-payment" -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"method": "terminal"}'

409 rentals_rest_outstanding_differs (with data.outstanding) when the order owes more than the fee: record the payment on the order in Shopify instead. 502 rentals_rest_shopify_error when Shopify can’t be reached.

Errors #

Errors have the shape described in the API overview. The codes these endpoints add:

StatusCodeWhen
404rentals_rest_not_foundNo late fee with that id.
409rentals_rest_not_reviewableThe fee isn’t waiting for review any more.
409rentals_rest_busySomeone is working on this fee right now: try again in a moment.
409rentals_rest_paidThe fee is paid: it can only be refunded.
409rentals_rest_not_waivableThe fee can no longer be waived.
409rentals_rest_not_unpaidOnly an unpaid fee can be sent a link or marked paid.
409rentals_rest_outstanding_differsThe order owes more than the fee (data.outstanding).
400rentals_rest_no_linesThere is nothing to charge.
400rentals_rest_no_depositNo refundable deposit on the order covers the whole fee.
400rentals_rest_deposit_failedThe fee couldn’t be taken from the deposit.
400rentals_rest_no_orderThe booking has no Shopify order to add the fee to.
400rentals_rest_reason_requiredWaiving needs a reason.
400rentals_rest_invalid_paramA value is wrong: data.field or data.params names it.
404rentals_rest_no_linkThere is no payment link yet.
502rentals_rest_shopify_errorShopify couldn’t be reached.