# HubSpot company links (Maison staff) — tool reference

Generated from the OpenAPI document (`https://maison-labs.com/api/v1/openapi.json`). Field types are JSON Schema types; GET/DELETE inputs travel as path or query, other methods as a JSON body.

## `get_hubspot_link` — Get HubSpot link

Return the client's HubSpot company mapping and the last push outcome. The `mapping` field is null when no company is linked — this is a normal state, not an error. 404 when the client itself is not found.

- REST: `GET https://maison-labs.com/api/v1/client/{clientId}/hubspot`
- MCP tool / A2A skill: `get_hubspot_link`
- Needs: hubspot READ (global)
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |

## `link_hubspot_company` — Link HubSpot company

Link a client to a HubSpot company, or create a new one and link it. Provide exactly one of `hubspotCompanyId` (link existing) or `create` (create then link). Returns the updated mapping. 409 on mapping conflict or creation failure.

- REST: `PUT https://maison-labs.com/api/v1/client/{clientId}/hubspot`
- MCP tool / A2A skill: `link_hubspot_company`
- Needs: hubspot WRITE (global)

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `hubspotCompanyId` | body | string | no | Existing HubSpot company id to link (numeric string) |
| `hubspotCompanyName` | body | string \| null | no | HubSpot company display name (for caching) |
| `hubspotCompanyDomain` | body | string \| null | no | HubSpot company domain (for caching) |
| `create` | body | object | no | Create a new HubSpot company instead of linking an existing one |

## `push_hubspot_chat_volume` — Push HubSpot chat volume

Push this week's chat-volume metric to the client's linked HubSpot company. Use `dryRun: true` to preview the values without writing to HubSpot. 409 when the client is not mapped or a sync is already running.

- REST: `POST https://maison-labs.com/api/v1/client/{clientId}/hubspot/push`
- MCP tool / A2A skill: `push_hubspot_chat_volume`
- Needs: hubspot EXECUTE (global)

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
| `dryRun` | body | boolean | no | Preview only — do not write to HubSpot; default false |

## `search_hubspot_companies` — Search HubSpot companies

Search Maison's HubSpot portal for companies by name or domain. Returns up to 20 matches. Use the result's `items[].id` with `link_hubspot_company`. Requires global `hubspot` READ.

- REST: `GET https://maison-labs.com/api/v1/hubspot/companies`
- MCP tool / A2A skill: `search_hubspot_companies`
- Needs: hubspot READ (global)
- Read-only.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `q` | query | string | yes | Search query (name or domain, ≥ 2 chars) |

## `unlink_hubspot_company` — Unlink HubSpot company

Remove the client's HubSpot company mapping. Idempotent — returns `{ removed: false }` when no mapping exists. Destructive.

- REST: `DELETE https://maison-labs.com/api/v1/client/{clientId}/hubspot`
- MCP tool / A2A skill: `unlink_hubspot_company`
- Needs: hubspot WRITE (global)
- Destructive — confirm with the user first.

Inputs:

| Field | Where | Type | Required | Notes |
| --- | --- | --- | --- | --- |
| `clientId` | path | string | yes | Client (hotel) id; format uuid |
