App proxy endpoints
Rentshelf uses Shopify’s App Proxy to expose dynamic data to the storefront. All endpoints are served from your shop domain:
https://<your-shop>.myshopify.com/apps/rental/<endpoint>Shopify proxies these to the app at /proxy/<endpoint> with a signed HMAC.
GET /apps/rental/config
Section titled “GET /apps/rental/config”Returns rental configuration for a single product.
Query params
| Param | Description |
|---|---|
product_id | Shopify product GID (or numeric ID). |
handle | Product handle (alternate lookup). |
start | Optional ISO date, for availability lookups. |
end | Optional ISO date. |
200 response (product is configured as a rental):
{ "productId": "gid://shopify/Product/123", "pricePerDay": 10, "pricingMode": "DAILY", "minDays": 1, "maxDays": 30, "currency": "USD", "addons": [ { "id": "...", "name": "Insurance", "price": 5, "priceType": "PER_DAY", "isRequired": false, "maxQuantity": 1 } ], "tiers": [ { "days": 7, "price": 60, "label": null } ], "blockedDates": ["2026-10-14", "2026-10-15"], "widget": { "heading": "Rent this product", "...": "..." }}404 response — the product isn’t configured as a rental (or is paused). The storefront picker uses this to remove itself from the DOM on non-rental products.
GET /apps/rental/quote
Section titled “GET /apps/rental/quote”Returns an authoritative server-side quote for a date range, including availability check and add-ons.
Query params
| Param | Description |
|---|---|
product_id | Shopify product GID. |
start | ISO start date. |
end | ISO end date. |
addons | JSON-encoded add-on selections. |
units | Number of units to rent (default 1). |
200 response:
{ "available": true, "days": 4, "subtotal": 40, "addonsTotal": 20, "total": 60, "deposit": 12, "currency": "USD"}This endpoint is used for defensive confirmation before adding to cart. The current storefront picker does client-side quoting with the same logic as calculateQuote, but you can opt to call this for a final server-blessed number (useful for custom integrations).
POST /apps/rental/reserve
Section titled “POST /apps/rental/reserve”Creates or updates a CHECKOUT / PENDING booking as a soft hold on dates.
Body (JSON):
{ "productId": "gid://shopify/Product/123", "start": "2026-10-14", "end": "2026-10-17", "days": 3, "subtotal": 30, "total": 50, "deposit": 10, "addons": [{ "id": "...", "name": "Insurance", "qty": 1, "price": 5 }], "currency": "USD", "cartToken": "z1abc..."}200 response:
{ "bookingId": "cln..."}The hold prevents two customers from checking out the same unit on overlapping dates. Holds expire after 60 minutes if no order is placed. On successful order placement, the orders/create webhook upgrades the hold to a real Booking.
Security
Section titled “Security”All proxy calls include an HMAC signature added by Shopify. The Remix handlers at /proxy/*.tsx verify the signature via authenticate.public.appProxy() before responding. Direct calls to the app’s URL (bypassing the shop domain) will fail authentication.
Rate limits
Section titled “Rate limits”The app uses Shopify’s standard Admin API rate limit bucket. App proxy calls themselves aren’t rate-limited by Shopify, but the underlying work (database reads, product sync) may be throttled if the shop is high-traffic. Contact support if you see sustained 429s.