Optimization Guide
Shopify Rental Product Schema for AI Shopping Agents
AI shopping agents answering "tent rental for weekend camping," "weekly camera rental price," and "formal wear hire near me" need explicit rental intent signals — not a generic Offer that implies purchase. Shopify's default product JSON-LD has no concept of offerType, rental duration, or security deposits, making every rental listing appear as a sale to AI crawlers.
offerType: "https://schema.org/Rental" and rentalDuration (QuantitativeValue with unitCode DAY/WEE/MON) to each rental Offer. For multi-duration pricing, declare one Offer per period in an array. Mark security deposits via additionalProperty: securityDeposit or a PriceSpecification with priceType: Deposit. Drive from a rental.* metafield namespace with a product tag gate.
The Rental Visibility Problem
Rental businesses on Shopify — outdoor gear, photography equipment, formal wear, baby gear, party supplies, tools — face a structural schema.org problem. Shopify's default product JSON-LD template outputs a single Offer block with a price and availability. There is no offerType property, which means every product offer is implicitly treated as a sale by schema.org processors and AI shopping agent indexes.
When a user asks ChatGPT Shopping "where can I rent a 4-person backpacking tent for the weekend" or Perplexity "weekly camera rental price," AI agents cannot distinguish your rental listing from a purchase listing — because the structured data signals are identical. The result is rental businesses either being excluded from rental-specific queries or incorrectly surfaced as purchase options.
The fix requires three explicit signals: offerType to declare the transaction as Rental, rentalDuration to specify the rental period, and deposit schema to communicate total cost of rental including conditionally returned charges.
Rental query types requiring structured data
| Query type | Example | Required signal | AI shopping behavior |
|---|---|---|---|
| Period-specific rental rate | "weekly tent rental price" | rentalDuration: {value: 7, unitCode: "DAY"} + price |
Surfaces rental listing with per-period price for requested duration |
| Rental availability check | "rent a DSLR camera this weekend" | offerType: Rental + availability: InStock |
Identifies items available for immediate rental booking |
| Deposit-inclusive cost | "total cost to rent a projector for a week" | priceSpecification with Deposit type + rental price |
Returns rental rate plus deposit to show total upfront cost |
| Rent vs. buy comparison | "cheaper to rent or buy a pressure washer" | Dual Offer: offerType: Rental + standard Sell Offer |
Compares rental price (per period) against purchase price |
| Minimum rental period | "minimum rental period for scaffolding" | additionalProperty: minimumRentalPeriod |
Surfaces minimum commitment requirement for the rental |
Shopify default vs. rental-aware JSON-LD
{
"@type": "Offer",
"price": "49.00",
"priceCurrency": "USD",
"availability": "InStock"
// rental? purchase? AI can't tell
// no rental duration
// no deposit signal
}
{
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"price": "49.00",
"priceCurrency": "USD",
"availability": "InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "DAY"
}
}
Rental Product JSON-LD Patterns
Minimum viable single-period rental
The baseline pattern: one Offer with offerType Rental and a rentalDuration QuantitativeValue. This is sufficient for stores with a single rental period (e.g., always rented per day):
{
"@context": "https://schema.org",
"@type": "Product",
"name": "4-Person Backpacking Tent — Alpine Pro",
"description": "Lightweight 4-person backpacking tent for weekend and multi-day trips. Daily rental includes tent body, rainfly, and poles.",
"brand": { "@type": "Brand", "name": "TrailGear Rentals" },
"offers": {
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Daily rental",
"price": "28.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "DAY"
}
}
}
Multi-duration rental pricing — daily, weekly, monthly
For stores offering tiered rental rates by period, declare one Offer per duration in an array. Each Offer has its own price and rentalDuration. AI agents surface the appropriate rate for the duration specified in the query:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Sony FX3 Cinema Camera — Rental",
"offers": [
{
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Daily rental",
"price": "195.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "DAY"
}
},
{
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Weekly rental",
"price": "750.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 7,
"unitCode": "DAY"
}
},
{
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Monthly rental",
"price": "2400.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 30,
"unitCode": "DAY"
}
}
]
}
Rental with security deposit using PriceSpecification
Declare the security deposit as a separate PriceSpecification entry alongside the rental price. Use priceType: "https://schema.org/Deposit" so AI agents understand the deposit is a conditional charge returned on item return — not an additional rental fee:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Camping Generator — 2000W Inverter",
"offers": {
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Daily rental",
"price": "75.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 1,
"unitCode": "DAY"
},
"priceSpecification": [
{
"@type": "PriceSpecification",
"name": "Daily rental rate",
"price": "75.00",
"priceCurrency": "USD",
"priceType": "https://schema.org/InvoicePrice"
},
{
"@type": "PriceSpecification",
"name": "Security deposit (refundable)",
"price": "350.00",
"priceCurrency": "USD",
"priceType": "https://schema.org/Deposit"
}
]
}
}
Rent-or-buy dual Offer
For products available both for purchase and for rental — common with tools, equipment, and some formal wear — declare two Offers: one Rental and one standard sale. AI agents answering comparison queries ("rent or buy a pressure washer") can return both options with their respective prices:
{
"@context": "https://schema.org",
"@type": "Product",
"name": "Pressure Washer — 3200 PSI Electric",
"offers": [
{
"@type": "Offer",
"name": "Purchase",
"price": "349.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock"
},
{
"@type": "Offer",
"offerType": "https://schema.org/Rental",
"name": "Weekend rental (2 days)",
"price": "65.00",
"priceCurrency": "USD",
"availability": "https://schema.org/InStock",
"rentalDuration": {
"@type": "QuantitativeValue",
"value": 2,
"unitCode": "DAY"
}
}
]
}
Shopify Liquid implementation with metafields
Store rental configuration in a rental metafield namespace. Gate the rental schema on a product tag so the injection is only added to rental products, not purchase products with a daily price:
{% comment %}
Rental product JSON-LD — only inject when product is tagged 'rental'
Metafields required (rental namespace):
rental.daily_price — number (decimal)
rental.weekly_price — number (decimal, optional)
rental.deposit — number (decimal, optional)
rental.min_days — integer (optional)
{% endcomment %}
{% if product.tags contains 'rental' %}
{% assign rental_daily = product.metafields.rental.daily_price.value %}
{% assign rental_weekly = product.metafields.rental.weekly_price.value %}
{% assign rental_deposit = product.metafields.rental.deposit.value %}
{% endif %}
Rental duration unitCode reference
| Period | unitCode (UN/CEFACT) | QuantitativeValue value | Common use |
|---|---|---|---|
| 1 day | DAY |
1 | Day rate — cameras, tools, party equipment |
| Weekend (2 days) | DAY |
2 | Weekend rate — camping gear, recreational equipment |
| 1 week | DAY |
7 | Weekly rate — cameras, scaffolding, industrial equipment |
| 1 month | MON |
1 | Monthly rate — furniture, baby gear, construction equipment |
| 1 hour | HUR |
1 | Hourly rate — sports courts, co-working spaces, vehicles |
Common Mistakes
1. No offerType — product appears as purchase to AI agents
The most common mistake: listing a rental product with a standard Offer and no offerType. Without offerType: "https://schema.org/Rental", schema.org processors and AI shopping indexes treat the offer as a sale. A user asking "where can I rent camping gear" will not see your listing, even if your product title says "rental" — because the structured data declares it as a purchase.
2. Putting the deposit amount in the base price field
Some rental businesses add the deposit to the rental price in the price field so the Shopify cart total looks correct. This inflates the apparent rental price and prevents AI agents from distinguishing the rental rate from the deposit. Always declare deposit as a separate PriceSpecification with priceType: Deposit — never bake it into the base price.
3. Using a flat daily price for all rental periods without per-period Offers
If your weekly rate is different from 7× your daily rate (e.g., you offer weekly discounts), a single daily-rate Offer is misleading for weekly queries. AI agents answering "weekly camera rental price" will multiply the daily rate — returning an incorrect total. Declare a separate weekly Offer with the correct weekly price to surface accurate pricing for period-specific queries.
4. Setting availability: OutOfStock for booked-out items without explaining rental windows
OutOfStock is ambiguous for rental products — it might mean the item is permanently sold out, or that it is currently booked for the next two weeks but available after. For rental items that are temporarily booked, consider using availability: PreOrder with availabilityStarts set to the next available rental window, rather than OutOfStock. This gives AI agents a more accurate signal about future availability.
5. Missing the rental tag gate in Liquid — injecting rental schema on purchase products
If your store sells both rental and purchase products, failing to gate the rental JSON-LD on a tag (e.g., if product.tags contains 'rental') will inject offerType: Rental on purchase products. This corrupts your purchase product signals and causes AI agents to surface sale items under rental-intent queries — a confusing and conversion-damaging mismatch.
Implementation Checklist
- Add
offerType: "https://schema.org/Rental"to every Offer on rental products - Declare
rentalDurationas a QuantitativeValue with numericvalueand UN/CEFACTunitCode(DAY, WEE, MON, HUR) - For tiered pricing (daily/weekly/monthly), declare one Offer per duration in an
offersarray - Declare security deposit in a separate
PriceSpecificationwithpriceType: "https://schema.org/Deposit" - Store rental config (daily_price, weekly_price, deposit, min_days) in a
rental.*metafield namespace - Gate rental JSON-LD injection on a product tag (e.g.,
rental) to avoid corrupting purchase product signals - For temporarily booked items, use
availability: PreOrderwithavailabilityStartsfor next available window - For rent-or-buy products, declare both a Rental Offer and a standard Offer in the
offersarray - Run CatalogScan to verify offerType and rentalDuration appear correctly in your AI readiness report
Frequently Asked Questions
How do I mark a Shopify product as available for rent rather than purchase?
Add offerType: "https://schema.org/Rental" to the Offer block in your product JSON-LD. Pair it with rentalDuration (a QuantitativeValue with value and unitCode — use DAY for daily, MON for monthly) and price representing the rental fee for that period. This signals to AI shopping agents that the transaction is a time-limited rental, not a permanent sale.
How do I mark up a security deposit for a rental product in schema.org?
Declare a priceSpecification array on the Offer with two entries: the rental rate (priceType: InvoicePrice) and the deposit (priceType: "https://schema.org/Deposit"). The deposit PriceSpecification signals to AI agents that this charge is conditional and returnable — not an additional rental fee. Never bake the deposit into the base price field.
Does Shopify output rental-specific structured data by default?
No. Shopify's default product JSON-LD outputs a standard Offer with no offerType, which AI agents interpret as a purchase (sale). Rental businesses must manually add offerType: "https://schema.org/Rental" and rentalDuration in their product.liquid template to be discovered by rental-intent queries.
How do I handle multiple rental durations (daily, weekly, monthly) in one product?
Declare an offers array with one Offer per duration. Each Offer has its own price for that period and a rentalDuration QuantitativeValue with the appropriate unitCode (1 DAY for daily, 7 DAY for weekly, 1 MON for monthly). AI agents surface the correct rate for the duration specified in the query.
Should I keep Shopify's standard purchase Offer alongside the rental Offer?
Only if your store offers both rental and outright purchase for the same SKU. For rental-only products, declare only Rental offerType Offers. For rent-or-buy products, use an offers array with a Rental Offer (rental rate + rentalDuration) and a standard Offer (sale price, no offerType). AI agents use this to accurately answer "can I buy or only rent this item."