---
name: "maison-hierarchy"
description: "Manage hotel groups: read a hotel's parent and children, find attachable candidates, attach or detach child properties, and run property discovery on a group website (start, read, edit candidates, approve/reject in bulk, approve to provision). Use when onboarding a brand or group site with several hotels, or when a property must move between groups. Tools: approve_property_discovery, attach_child_property, decide_property_candidates, detach_child_property, get_client_hierarchy, get_property_discovery, list_child_candidates, list_children_feature_counts, start_property_discovery, update_property_candidate."
license: "Proprietary. Use with a Maison API key under the Maison terms of service."
metadata:
  author: "maison-labs"
  version: "1.0.0"
  category: "hierarchy"
  api-base: "https://maison-labs.com"
  openapi: "https://maison-labs.com/api/v1/openapi.json"
  docs: "https://docs.maison-labs.com/skills/maison-hierarchy/"
---

# Maison — Multi-property groups (Maison staff)

Manage hotel groups: read a hotel's parent and children, find attachable candidates, attach or detach child properties, and run property discovery on a group website (start, read, edit candidates, approve/reject in bulk, approve to provision). Use when onboarding a brand or group site with several hotels, or when a property must move between groups.

Part of the Maison public API. Read the `maison-public-api` skill first for authentication, discovery and transport details (`https://docs.maison-labs.com/skills/maison-public-api/SKILL.md`).

## When to use

- A group website was onboarded with `multiProperty: true` — `start_property_discovery` then review candidates.
- Link an existing hotel under a group — `attach_child_property`.

## Before you start

1. Send `x-api-key: <key>` on every call; the key only reaches `/api/v1`.
2. `GET /api/v1/tools` (or MCP `tools/list`) returns the tools THIS key may run — if a tool below is missing there, you lack a grant; do not retry it.
3. Client-scoped tools take `clientId` (a hotel id). `whoami` lists the ids you can act on.

## Tools

| Tool | What it does | REST | Needs |
| --- | --- | --- | --- |
| `approve_property_discovery` | Provision the APPROVED candidates of an AWAITING_REVIEW run as child clients. | `POST /api/v1/client/{clientId}/propertydiscovery/{sessionId}/approve` | clients WRITE (global); plan: `property-discovery` |
| `attach_child_property` | Attach an existing client as a child property of a parent group. | `POST /api/v1/client/{clientId}/child` | clients WRITE (global) |
| `decide_property_candidates` | Apply a bulk decision (APPROVED or REJECTED) to candidates. | `POST /api/v1/client/{clientId}/propertydiscovery/{sessionId}/decisions` | clients WRITE (global); plan: `property-discovery` |
| `detach_child_property` | Detach a child property from its parent group. | `DELETE /api/v1/client/{clientId}/child/{childClientId}` | clients WRITE (global); destructive |
| `get_client_hierarchy` | Return the client's parent group and its list of child properties. | `GET /api/v1/client/{clientId}/hierarchy` | clients READ (global); read-only |
| `get_property_discovery` | Return a discovery session. | `GET /api/v1/client/{clientId}/propertydiscovery` | clients READ (global); plan: `property-discovery`; read-only |
| `list_child_candidates` | Search active clients that could be attached as children of a parent group. | `GET /api/v1/client/{clientId}/children/candidates` | clients WRITE (global); read-only |
| `list_children_feature_counts` | For a group client: how many active child properties it has (`children`) and, per catalogue feature, how many of them are entitled to it (`items[].entitled`). | `GET /api/v1/client/{clientId}/children/features` | client-feature-management READ (global); read-only |
| `start_property_discovery` | Kick off automated nearby-property discovery for a multi-property group client. | `POST /api/v1/client/{clientId}/propertydiscovery` | clients EXECUTE (global); plan: `property-discovery` |
| `update_property_candidate` | Edit one proposed property candidate: correct its name, location, URL prefixes or decision. | `PATCH /api/v1/client/{clientId}/propertydiscovery/{sessionId}/candidate/{candidateId}` | clients WRITE (global); plan: `property-discovery` |

Full input fields for every tool: [references/tools.md](references/tools.md).

## Recommended workflows

### Discover and provision a group's properties

1. `start_property_discovery` on the parent (202; 409 if a run is active).
2. Poll `get_property_discovery` until candidates appear; fix names/URLs with `update_property_candidate`.
3. `decide_property_candidates` with `decision: "APPROVED"` (all, or `candidateIds`), then `approve_property_discovery` — 202 `{ status: "PROVISIONING", sessionId, approved }` at once; the run continues in the background.
4. Poll `get_property_discovery` until PROVISIONING turns COMPLETED (or FAILED); `get_client_hierarchy` shows the resulting children.

## Tips

- `grant_feature_to_children` (features skill) propagates a plan feature to every child; `list_children_feature_counts` first shows which features are only partly rolled out.

## Pitfalls

- Hierarchy tools need GLOBAL `clients` grants; discovery additionally requires the parent's plan to include `property-discovery` (waived for Maison staff holding it globally).
- Attaching a child that is already a parent elsewhere, or would create a cycle, answers 409.
- `approve_property_discovery` answers 409 when the run is not awaiting review or no candidate is approved.

## Calling conventions

Same tool, three transports — pick whichever your runtime already speaks. Always send `x-api-key`.

```bash
# REST
curl -X POST "https://maison-labs.com/api/v1/client/<clientId>/propertydiscovery/<sessionId>/approve" -H "x-api-key: $MAISON_API_KEY" -H "content-type: application/json" -d '{}'
```

```json
// MCP (https://maison-labs.com/mcp, Streamable HTTP): tools/call
{ "jsonrpc": "2.0", "id": 1, "method": "tools/call", "params": { "name": "approve_property_discovery", "arguments": {} } }
```

```json
// A2A (https://maison-labs.com/a2a): tasks/send with a data part
{ "jsonrpc": "2.0", "id": 1, "method": "tasks/send", "params": { "message": { "role": "user", "parts": [{ "type": "data", "data": { "tool": "approve_property_discovery", "input": {} } }] } } }
```

Errors are the same everywhere: `401` no/invalid key; `403 forbidden` with `details.missing` (the grants you lack — fall back to the composite's parts or stop); `403 not_entitled` (the hotel's plan lacks the feature); `404`, `409`, `413 too_large`, `503`. Inputs that fail validation return `400 invalid_input` with the Zod issues — fix and retry once.
