Before you start
This guide assumes you have:- An access token or OAuth 2.0 credentials — see Authentication
- Familiarity with Stora’s domain model — see Core concepts
- A webhook endpoint configured to receive events — see Webhooks
How it works
Your application controls the experience up to payment. After that, Stora takes over. Choose the order creation flow that matches your checkout.- Multi-step order
- Single-request order
Step 1: Display available storage
Start by fetching the operator’s sites, then the unit types and pricing at each site. If you’re serving this data to many customers, consider caching these resources locally rather than fetching them on every page load.Fetch sites
address, access_hours, and description to build a site selection UI.
Fetch unit types at a site
Unit types represent the categories of storage available — for example “50 sq ft indoor” or “20 ft container.”live_prices— the current Unit Type prices to show customers and use forunit_typeorder line items. Each entry is scoped to abilling_period. Use the matching entry for the customer’s selected billing period.prices— the base configured prices for the Unit Type. These are useful for reference, but your booking flow should uselive_priceswhen displaying or submitting Unit Type pricing.status— should bebookablefor unit types you display.require_insurance_coverage/require_security_deposit— indicate what the operator expects. The API doesn’t enforce these, but your checkout should prompt for them whentrue. See operator expectations.selling_points— operator-defined features you can display in your UI.
Check availability
Check whether a unit type has available stock by querying its units filtered by status:unit_type line item. Specific units are allocated or reserved later through Stora’s completion and allocation flow.
Fetch protection levels and products
If your checkout lets customers add protection or products, fetch the available options:cover_level (the coverage amount) and prices per billing period. Products return a charge_type (one_time or recurring) and prices. Both are referenced by ID when adding line items to an order.
Step 2: Capture customer details
Every order needs a contact — the person renting the storage.email is required. All other fields are optional but recommended — the operator will see this information in their back office.
Step 3: Create the order
Create an order indraft status with at least one unit_type line item:
- With existing contact
- With inline contact
status: "draft" and calculated totals you can use to build an order summary for the customer.
Key request fields:
site.id(required) — the site the customer is booking at.contact— either anidreferencing an existing contact, or inline contact fields.billing_period—weekly,monthly,every_four_weeks,every_three_months,every_six_months, oryearly.payment_method—card,bacs_debit, orsepa_debit.starts_at— when the tenancy begins. ISO 8601 date-time or"now"for immediate move-in.coupon.id— optional coupon to apply to the order. For automation or AI-created orders, use the selectedunit_type.promotionwhen present.email_notifications.payment_details— set totrueto email the customer a payment link when the order is finalized.line_items— at least oneunit_typeline item is required.
Add more line items
While the order is indraft status, you can add protection, products, and security deposits:
Step 4: Finalize the order
Finalizing locks the order and generates a hosted checkout page. Optionally validate first to catch any issues:finalize.cancel_redirect_url request field is required and controls where the customer lands if they abandon checkout. Use "cancel_redirect_url": "default" if you do not have your own URL to redirect to. The finalized order response includes a payment_url. See Handling payment for when to redirect the customer or send the link by email.
Handling payment
Finalizing an order generates a hostedpayment_url. In an interactive booking flow, redirect the customer to this URL so they can enter their payment details.
If the order is created by automation, AI, or another flow where you cannot redirect the customer immediately, set email_notifications.payment_details to true. Stora emails the customer a payment link when the order is finalized.
Use one payment path per order: redirect the customer to payment_url, send the payment details email, or do both only when that is intentional for your customer experience.
Create and finalize in one step
For single-page checkouts, include thefinalize field in the create request. You can reference an existing contact or create the contact inline in the same request.
- With existing contact
- With inline contact
payment_url. If finalization fails, the order is not stored.
Step 5: Handle completion
After payment, Stora emitsorder.completed to confirm that the booking is complete. It then creates the tenancy and subscription and attempts auto-reservation when the operator has enabled it. Everything is communicated via webhooks.
What Stora creates
1
Tenancy
The storage agreement — linking the contact, site, and unit type with start and end dates.
2
Subscription
The billing agreement — recurring charges, billing period, and payment method. See invoicing for when each charge type is billed.
3
Unit allocation
For storefront and Public API orders, Stora attempts to reserve the requested units automatically when the operator has enabled auto-reservation. Use the dedicated
tenancy.auto_reservation.* events to determine the outcome. For partial or failed attempts, use the reserve endpoint to allocate unreserved units manually.4
Contract (if configured)
If a contract template was specified on the order, Stora generates a contract for the customer to sign.
Webhook events
order.completed is the primary signal that the booking is done. Stora triggers it before tenancy creation and auto-reservation processing, but webhook delivery order is not guaranteed. It may arrive after later tenancy or auto-reservation events. Use the tenancy.auto_reservation.* events to determine the complete reservation outcome. Each successfully reserved unit also emits unit.reserved. For partial or failed attempts, allocate the unreserved units manually.
See Webhooks for setup, payload structure, and signature verification.
Understanding orders in detail
Line items
There are four line item types:
Every line item needs a
type, quantity, price.amount, and item.id. For unit_type line items, set price.amount from the matching unit_type.live_prices entry for the selected billing period. For protection and product line items, use the relevant resource’s prices array.
The API requires at least one unit_type line item but does not enforce protection or security deposit inclusion — your application controls the checkout experience.
Operator expectations
The unit type’srequire_insurance_coverage and require_security_deposit flags indicate what the operator expects. When true, your checkout should prompt the customer accordingly. The API won’t reject an order missing these.
Tax
Tax is calculated automatically based on the operator’s configuration at the site level — you don’t set it yourself. Each line item type can have its own tax rate. Security deposits are never taxed. Each line item returnstax and total_excluding_tax fields, and the order has aggregate tax fields across all line items.
Promotions
Unit types can include apromotion when a promotional coupon is associated with them. Expand or inspect the selected Unit Type before creating the order so you can apply that promotion consistently.
When an order is created by automation or AI, use unit_type.promotion as the order coupon when it is present:
unit_type.promotion takes precedence before creating the order.
Coupons
You can apply one coupon per order by including thecoupon field:
GET /coupons and match by the code field.
Coupons fall into two categories based on their auto_apply_to configuration:
- Subscription-level (
auto_apply_to.subscriptions: true) — apply to the subscription as a whole. - Line-item level — apply individually to matching line items. The
auto_apply_toobject controls which types:unit_types,protections, and/orproducts.
total_discount field reflects the result.
- Only one coupon per order.
- Fixed-amount coupons can only apply at the subscription level.
- One-off products and security deposits are never discounted.
Invoicing
The hosted checkout page collects the customer’s payment method — not an immediate payment. After checkout, charges are split across separate invoices:Order summary fields
Every order response includes calculated totals that update as line items change:
Each line item also returns
price, tax, total, total_excluding_tax, and discount_total for per-item breakdowns. Use the formatted field on any money object for display-ready strings.
Email notifications
Stora sends the customer a booking confirmation and move-in day reminder by default. The content is customised by the operator in the BackOffice. Useemail_notifications to control these emails per order. Set payment_details to true when Stora should email the customer a payment link after the order is finalized:
Metadata
Attach up to 20 key-value pairs for your own references:Edge cases
Availability races
Stora does not hold units during checkout. If a unit type sells out between browsing and payment, the order still completes but no unit is allocated. The operator handles this from the back office. Refresh availability data at your order summary page to reduce the risk.Abandoned orders
Orders that are finalized but never completed stay infinalized status. Track order.finalized events and flag orders that don’t receive order.completed within a reasonable timeframe.
Validation errors
Common issues:- “Line items must include at least one unit type line item” — every order needs at least one storage unit.
- “Billing period must exist” — ensure the billing period matches one available on the unit type.
Idempotency
Use theIdempotency-Key header on POST requests to safely retry on network errors. See Idempotent requests.