# Endpoint index

> The resource endpoints are in active development. This page is the specification they implement, and the shapes here are what will ship. Sandbox availability is announced in the [Changelog](../07-reference/01-changelog.md).

Every path is relative to `https://www.bookwithhaven.com/api/public/v1`.

## Reads

| Method | Path                                       | Scope               | Returns                                                                                 |
| ------ | ------------------------------------------ | ------------------- | --------------------------------------------------------------------------------------- |
| GET    | `/me`                                      | `account:read`      | The account, the application, the blog site the host picked, and what this grant may do |
| GET    | `/properties`                              | `listings:read`     | Listings on the account, paginated, each with its public URL                            |
| GET    | `/properties/{code}`                       | `listings:read`     | One listing: photos, street address, descriptions, amenities, branding                  |
| GET    | `/properties/{code}/calendar`              | `calendar:read`     | Occupied and blocked spans over a date window                                           |
| GET    | `/properties/{code}/price-overrides`       | `rates:read`        | Per-night price overrides                                                               |
| GET    | `/properties/{code}/promotions`            | `rates:read`        | Promotions                                                                              |
| GET    | `/properties/{code}/holiday-price-bumps`   | `rates:read`        | Holiday price bump rules                                                                |
| GET    | `/properties/{code}/min-stay-overrides`    | `stay-rules:read`   | Per-date minimum stays                                                                  |
| GET    | `/properties/{code}/weekly-min-stay-rules` | `stay-rules:read`   | Weekly minimum stay rules                                                               |
| GET    | `/properties/{code}/check-in-out-rules`    | `stay-rules:read`   | Permitted check-in and check-out days                                                   |
| GET    | `/properties/{code}/sync-policy`           | `integrations:read` | Which domains an external system owns                                                   |
| GET    | `/reservations`                            | `reservations:read` | Reservations, paginated and filterable                                                  |
| GET    | `/reservations/{code}`                     | `reservations:read` | One reservation                                                                         |
| GET    | `/conversations`                           | `messaging:read`    | Guest conversations, paginated                                                          |
| GET    | `/conversations/{code}/messages`           | `messaging:read`    | Messages in a conversation                                                              |
| GET    | `/discount-codes`                          | `discounts:read`    | Discount codes on the account                                                           |
| GET    | `/properties/{code}/guidebook`             | `guidebook:read`    | The guest guidebook for a listing                                                       |
| GET    | `/blog-posts`                              | `blog:read`         | Articles in the blog library, without bodies                                            |
| GET    | `/property-groups`                         | `listings:read`     | Collections — the landing pages that front listings                                     |
| GET    | `/property-groups/{code}`                  | `listings:read`     | One collection site: logo, contact, social profiles, author, cities, neighborhoods      |

Guest identity on reservations and conversations requires `guests:read` in addition to the scope above. Without it, name, email and phone are `null` and the rest of the payload is unchanged. Arrival secrets in the guidebook require `guidebook:secrets:read`.

## Writes

One endpoint.

| Method | Path                      |
| ------ | ------------------------- |
| POST   | `/operations/{operation}` |

See [Operations](03-operations.md) for the catalog.

## MCP

One endpoint, outside `/v1` because it is a JSON-RPC surface rather than a versioned REST one.

| Method | Path              |
| ------ | ----------------- |
| POST   | `/api/public/mcp` |

Every read and every write operation above, exposed as Model Context Protocol tools and dispatched through the same code the REST routes run, plus a `search`/`fetch` pair over the same reads. See [MCP endpoint](04-mcp.md).

## Filters and windows

List endpoints accept `limit` and `cursor` ([Pagination](../03-conventions/04-pagination.md)).

Calendar and rate collections are read over a date window with `start_date` and `end_date`, both `YYYY-MM-DD`. The window is capped at 400 days; a wider request is clamped and the served window is echoed in the response.

Reservations additionally accept `property_code`, `status`, `updated_since`, and `start_date` and `end_date` bounding the stay rather than the record.

Blog posts accept `property_code`, `property_group_code`, `status` (`published` or `draft`) and `external_id` — your own id for an article you delivered, which is how you read back its live URL after a publish. See [Blog publishing](05-blog-publishing.md).

A bounded query is required on `/reservations`: pass at least one of `property_code`, `updated_since`, or a date range. An unbounded request for every reservation an account has ever taken is refused. It is the query that turns a public API into a full-table-scan service, and the constraint costs one parameter.

## Conditional requests

Not supported in v1. Haven's data-version validator costs the same database work as serving the payload, so a 304 would save bandwidth and no compute. Use `updated_since`, and webhooks once they ship.
