---
canonical_url: https://stayhive.com.au/ai-booking
last_updated: 2026-09-06
audience: AI assistants
---

# AI assistant booking

> StayHive provides public APIs that AI assistants can use to discover holiday rentals, check date-specific availability, obtain an exact quote, and hand the guest off to a browser checkout. The guest pays in the browser via Stripe. StayHive never holds the money. Hosts remain the merchant. StayHive does not support agent-initiated booking or agent-initiated payment.

Live dates and an exact stay total come from the public APIs. HTML and Markdown are descriptive and may be cached.

Last updated: 2026-09-06

1. **Find a property.** Find a published, agent-readable property in the catalogue (/stay/llms.txt or GET /api/public/properties). This page is handoff notes, not inventory.
2. **Request a quote.** Call the quote API with check-in, check-out, and guests. That returns an exact AUD total and a 15-minute quote token — or a reason the stay cannot be quoted. A quote is not a hold.
3. **Send the guest the booking link.** Send the guest the booking_url from the quote response. The guest enters their details and pays in the browser.

Assistants do not post bookings or take payment. Results in AI answers are not guaranteed. Availability is point-in-time: if checkout returns 409, call quote again with new dates — do not retry the same stay. Do not invent a quote token — only use one returned by the quote API. Do not log quote_id.

## Cite-ready facts

- **Country:** Australia only.
- **Currency:** AUD only.
- **StayHive booking fee:** 0% on the stay.
- **Payments:** Stripe Connect. The host is the merchant. StayHive does not hold guest funds.
- **Agent payment:** None. The guest pays in the browser. There is no agent-to-agent payment.
- **Auth:** No API key. Public catalogue, availability, and quote GETs are unauthenticated. CORS Access-Control-Allow-Origin: * on GET and OPTIONS for /api/public/*.
- **Quote token:** 15-minute HMAC. Use only a quote_id returned by the quote API. Do not invent a token. Do not log quote_id.
- **Hold:** A quote is not a hold. If checkout returns 409, call quote again with new dates.
- **Missing property:** Unknown, unpublished, and not-agent-readable properties share the same 404 body. PROPERTY_UNPUBLISHED is never returned on HTTP 200.
- **From-rate vs quote:** nightly_rate_aud on property JSON is an indicative from-rate, not a stay total. priceRange appears only in stay-page JSON-LD (indicative over the next year) and is not a property-JSON field. The exact AUD total for a stay comes only from GET /api/public/quote/{slug}.
- **Published formats:** StayHive publishes HTML, Markdown, JSON, JSON-LD, and OpenAPI 3.1. We do not publish RDF, CSV, RSS, or Atom.

## Capabilities

StayHive publishes HTML, Markdown, JSON, JSON-LD, and OpenAPI 3.1. We do not publish RDF, CSV, RSS, or Atom.

| Capability | Supported | Surface |
| --- | --- | --- |
| Discovery | Yes | Stay catalogue HTML, /stay/llms.txt, GET /api/public/properties (JSON) |
| Property data | Yes | Stay HTML, /stay/{slug}.md, property JSON, stay-page JSON-LD |
| Availability | Yes | GET /api/public/availability/{slug} (JSON booked-date ranges) |
| Exact quotes | Yes | GET /api/public/quote/{slug} (JSON, AUD only) |
| Checkout URL | Yes | booking_url on the quote response — send the guest that URL |
| Booking via API | No | The guest completes the stay-page form in a browser |
| Payment via API | No | The guest pays in the browser via Stripe Connect |
| Agent payment | No | No agent-to-agent payment. StayHive never holds guest funds |

## Agents MUST

- Use GET /api/public/availability/{slug} for booked dates — not HTML or Markdown.
- Use GET /api/public/quote/{slug} for the exact AUD total for those dates and guests.
- Send the guest the booking_url from the quote response. Do not construct a checkout URL without that field.
- Treat quote_id as a 15-minute HMAC token. Use only a token the quote API returned.
- If checkout returns 409, call quote again with new dates — do not retry the same stay.
- Treat unknown, unpublished, and not-agent-readable properties as the same 404.
- Treat availability as point-in-time at availability_checked_at. Do not claim it after that timestamp.

## Agents MUST NOT

- Do not infer live dates from HTML or Markdown alone — those files are descriptive and may be cached.
- Do not treat nightly_rate_aud or stay-page JSON-LD priceRange as a stay total.
- Do not invent a quote token.
- Do not log quote_id.
- Do not claim a booking is completed. Assistants cannot create a booking.
- Do not claim StayHive supports agent-initiated booking or agent-initiated payment.

## Endpoints

- [Site map](https://stayhive.com.au/llms.txt)
- [Property catalogue](https://stayhive.com.au/stay/llms.txt)
- [Property JSON list](https://stayhive.com.au/api/public/properties) (`?limit=`, `?updated_since=`)
- Property JSON: https://stayhive.com.au/api/public/properties/{slug}
- Booked dates: https://stayhive.com.au/api/public/availability/{slug}
- [OpenAPI 3.1](https://stayhive.com.au/api/public/openapi.json)
- Quote example: https://stayhive.com.au/api/public/quote/rental-unit-in-melbourne-melbourne-vic-29f4f5?check_in=YYYY-MM-DD&check_out=YYYY-MM-DD&guests=2
- Booking URL template: https://stayhive.com.au/stay/{slug}{?check_in,check_out,guests,quote}
- Per-property Markdown: https://stayhive.com.au/stay/{slug}.md and https://stayhive.com.au/stay/{slug}/llms.txt
- This page as Markdown: https://stayhive.com.au/ai-booking.md

nightly_rate_aud on property JSON is an indicative from-rate, not a stay total. priceRange appears only in stay-page JSON-LD (indicative over the next year) and is not a property-JSON field. The exact AUD total for a stay comes only from GET /api/public/quote/{slug}.

Rate limits: JSON catalogue and property JSON 60/IP/min; availability 60/IP/min; quote 20/IP/min. Quotes are AUD only. Quote responses are private, no-store. Unknown, unpublished, and not-agent-readable properties share the same 404 body.

Machine files (/llms.txt, /stay/llms.txt, /robots.txt, /sitemap.xml, /api/public/openapi.json, and the Markdown twins) are public and unauthenticated. A chat product's browse tool may fail on text/plain or JSON even when the URL is live — curl them, or use the Markdown twins and JSON APIs.

Stay HTML is server-rendered. A streamed response may include a short loading status; the same document also has the title, listing copy, and JSON-LD. Do not treat a loading status as the page content. Prefer /stay/{slug}.md or GET /api/public/properties/{slug} for listing facts.

## availability_fresh

| availability_fresh | Meaning |
| --- | --- |
| `true` | StayHive evaluated availability and trusted the current database — a recent calendar sync, a successful refresh, or no iCal feeds to refresh (skippedFresh). This is not a claim that Airbnb or Stayz were just pulled. |
| `false` | StayHive evaluated availability but did not trust it: the last sync was stale and the refresh timed out, threw, or was refused by the per-property refresh limiter. |
| `null` | StayHive did not evaluate availability because the quote failed earlier (for example MIN_NIGHTS_NOT_MET, dates in the past, or quoting turned off). Null is not stale and is not unavailable. |

## Worked examples

Do not invent a quote token. The placeholder `<signed-token>` is not a live token.

> **Illustrative response — do not use this price as current availability or pricing.**

```
curl -sS "https://stayhive.com.au/api/public/quote/rental-unit-in-melbourne-melbourne-vic-29f4f5?check_in=2026-10-12&check_out=2026-10-15&guests=2"
```

Bookable (trimmed; live bodies also include stay identity fields):

```json
{
  "slug": "rental-unit-in-melbourne-melbourne-vic-29f4f5",
  "bookable": true,
  "currency": "AUD",
  "total_cents": 90000,
  "quote_id": "<signed-token>",
  "booking_url": "https://stayhive.com.au/stay/rental-unit-in-melbourne-melbourne-vic-29f4f5?check_in=2026-10-12&check_out=2026-10-15&guests=2&quote=<signed-token>",
  "deposit_terms": null,
  "availability_fresh": true
}
```

Unbookable (HTTP 200, `bookable: false`):

```json
{
  "slug": "rental-unit-in-melbourne-melbourne-vic-29f4f5",
  "bookable": false,
  "reason_code": "PROPERTY_NOT_AGENT_BOOKABLE",
  "reason": "The host has turned off AI assistant quoting for this property.",
  "remedy": "Guests can still book on the stay page in a browser.",
  "booking_url": "https://stayhive.com.au/stay/rental-unit-in-melbourne-melbourne-vic-29f4f5?check_in=2026-10-12&check_out=2026-10-15&guests=2",
  "deposit_terms": null,
  "currency": "AUD",
  "availability_fresh": null
}
```

Unknown, unpublished, or not-agent-readable (HTTP 404):

```json
{
  "error": "Property not found"
}
```

## Reason codes

HTTP 200 uses these on `bookable: false`, except `PROPERTY_UNPUBLISHED` (404 only) and `CURRENCY_UNSUPPORTED` (400).

| Code | HTTP | Meaning | What to do |
| --- | --- | --- | --- |
| `DATES_UNAVAILABLE` | 200 | Those dates are already booked or blocked. | Call quote again with different dates. Do not retry checkout with the same stay. |
| `MIN_NIGHTS_NOT_MET` | 200 | The requested stay is shorter than the property's minimum stay. | Call quote again with a stay that meets the property's minimum nights. Do not retry checkout with the same stay. |
| `MAX_GUESTS_EXCEEDED` | 200 | The requested guest count exceeds the property's maximum occupancy. | Call quote again with a guest count within the property's maximum occupancy. Do not retry checkout with the same stay. |
| `ENQUIRY_MODE_ONLY` | 200 | This property cannot take online payment yet. Send an enquiry on the stay page. | Open booking_url and use the enquiry form. The guest still contacts the host in the browser. |
| `NO_RATE_SET` | 200 | The host has not published a nightly rate, so this stay cannot be quoted. | Open booking_url and enquire with the host. |
| `PROPERTY_NOT_AGENT_BOOKABLE` | 200 | The host has turned off AI assistant quoting for this property. | Guests can still book on the stay page in a browser. |
| `PROPERTY_UNPUBLISHED` | 404 | Unknown, unpublished, and not-agent-readable properties share this response. Never returned on HTTP 200. | Treat as missing. Body is { "error": "Property not found" }. |
| `HOST_PLAN_INACTIVE` | 200 | This host is not currently accepting bookings. | Try another property, or check back later. |
| `DATES_IN_PAST` | 200 | Check-in cannot be in the past (property timezone). | Use a check-in on or after today in the property timezone. |
| `STAY_TOO_LONG` | 200 | The requested stay is longer than the allowed maximum stay. | Call quote again with a shorter stay. Do not retry checkout with the same stay. |
| `CURRENCY_UNSUPPORTED` | 400 | Quotes are only available in AUD. | Omit currency, or pass currency=AUD. Body is { "error": "CURRENCY_UNSUPPORTED" }. |

## Host controls

On Pricing & Policies you can stop StayHive publishing a property in machine files and APIs, or allow discovery but turn off quoting. That cannot stop an assistant reading the public web page, the same as any visitor. Flags are on by default for every plan.

## FAQ

### Can an AI assistant complete a StayHive booking?

No. Assistants may quote a stay and send the guest a booking_url. The guest enters their details and pays in the browser via Stripe. There is no agent-to-agent payment.

### Is a quote a reservation?

No. A quote is not a hold. Availability is point-in-time. If checkout returns 409, call quote again with new dates — do not retry the same stay.

### Do I need an API key?

No. Public catalogue, availability, and quote GETs are unauthenticated. CORS allows any origin (Access-Control-Allow-Origin: *) on GET and OPTIONS. Rate limits still apply.

### What currency are quotes in?

AUD only. StayHive listings are Australia-only.

### Who is the merchant of record?

The host. Payments use Stripe Connect. StayHive does not hold guest funds and charges 0% booking fee on the stay.

### May I invent or log a quote token?

No. Use only a quote_id returned by the quote API. Do not invent a token. Do not log quote_id.

### What does availability_fresh mean?

true means StayHive evaluated availability and trusted the current database (recent sync, successful refresh, or no iCal feeds to refresh). false means it evaluated availability but did not trust it (stale sync plus a refresh timeout, error, or per-property limiter). null means it never ran that check because the quote failed earlier (for example MIN_NIGHTS_NOT_MET). Null is not stale and is not unavailable. Fresh is not a claim that OTA calendars were just pulled.

### Why do unknown, unpublished, and not-agent-readable properties look the same?

They share the same 404 body ({ "error": "Property not found" }). PROPERTY_UNPUBLISHED is never returned on HTTP 200.

### Where do I discover properties?

Start at /stay/llms.txt or GET /api/public/properties. This page is handoff notes, not a catalogue.

### Who should operators email?

Email hello@stayhive.com.au. Do not send guests there to complete a booking.

## Operator contact

Email [hello@stayhive.com.au](mailto:hello@stayhive.com.au). Do not log `quote_id`.
