# Houzz Pro API

> Every Houzz Pro endpoint on Cotlet: inputs, JSON Schema, cURL, Python and Node.js examples and an example response for each call.

Source: https://cotlet.dev/docs/api/houzz-pro

Docs sections: [Get started](https://cotlet.dev/docs.md) · [REST API](https://cotlet.dev/docs/api.md) · [MCP](https://cotlet.dev/docs/mcp.md) · [SDKs & CLI](https://cotlet.dev/docs/sdks.md) · [Integrations](https://cotlet.dev/docs/integrations.md)

14 endpoints for Houzz Pro. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/houzz-pro`
- Connects with: Your own Houzz Pro account (Time Management permission to log time for other team members)
- Integration page: https://cotlet.dev/integrations/houzz-pro-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_leads` | read | Leads with stage, client, location, project type, source, tags and last activity. |
| `get_lead` | read | Full lead: client contact, address, description, estimated revenue and profit, notes and tasks. |
| `list_projects` | read | Projects with client, address and status. |
| `list_tasks` | read | Tasks from the Task Center, sorted by due date, with assignee and status. |
| `list_estimates` | read | Estimates of a project with title, total and client approval. |
| `list_invoices` | read | Invoices of a project with code, total, status and payments received. |
| `create_lead` | write | New lead in your pipeline. |
| `update_lead_stage` | write | Move a lead to another stage of your pipeline. |
| `convert_lead_to_project` | write | Turn a won lead into a project; the lead address becomes the project address. Cannot be undone. |
| `create_task` | write | Task on a project or lead, assigned to a team member, client or sub. |
| `log_time` | write | Time entry on a project; rate, markup and billable status come from the activity. |
| `create_estimate` | write | Draft estimate on a project from line items. Nothing reaches the client until you send it. |
| `create_invoice` | write | Draft invoice from an estimate: the whole document, selected line items or a percentage. |
| `send_document` | write | Email an estimate or invoice to the client to view, approve or pay online. |

## List leads

`POST https://cotlet.dev/api/v1/houzz-pro/list_leads`

Access: read.

Lists leads from your pipeline, newest first. Filter by stage, source, tags or a keyword to find the leads you need. Stages are New, Followed Up, Connected, Meeting Scheduled, Proposal/Estimate Sent, Won, or a custom stage you added. Pages hold up to 100 leads; pass next_cursor back as cursor for the next page.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `stage` | string | no | Lead stage, e.g. New, Followed Up, Connected, Meeting Scheduled, Proposal/Estimate Sent, Won, or a custom stage. |
| `query` | string | no | Keyword search. |
| `lead_source` | string | no | Only leads from this source. |
| `tags` | string[] | no | Only leads with these tags. |
| `limit` | integer | no | 1 to 100. Default: 50. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/list_leads \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"stage":"Proposal/Estimate Sent","limit":100}'
```

**Python**

```python
result = client.call("houzz-pro", "list_leads", {"stage":"Proposal/Estimate Sent","limit":100})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'list_leads', {"stage":"Proposal/Estimate Sent","limit":100});
```

**CLI**

```bash
cotlet call houzz-pro list_leads --data '{"stage":"Proposal/Estimate Sent","limit":100}'
```

### Example response

```json
{
  "leads": [
    {
      "lead_id": "lead_20418",
      "lead_name": "Miller Kitchen",
      "stage": "Proposal/Estimate Sent",
      "client_name": "Dana Miller",
      "location": "Austin, TX",
      "project_type": "Kitchen remodel",
      "lead_source": "Website",
      "tags": [
        "Spring"
      ],
      "estimated_revenue": 29500,
      "last_activity": "2026-09-24T15:10:00Z"
    }
  ],
  "next_cursor": null
}
```

## Get lead

`POST https://cotlet.dev/api/v1/houzz-pro/get_lead`

Access: read.

Returns one lead with the client contact, address, description, the optional estimated revenue, profit and budget, and its open tasks. Use it before following up so your agent sees what is already planned.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `lead_id` | string | yes | Lead ID from list_leads. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/get_lead \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"lead_8c41d2"}'
```

**Python**

```python
result = client.call("houzz-pro", "get_lead", {"lead_id":"lead_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'get_lead', {"lead_id":"lead_8c41d2"});
```

**CLI**

```bash
cotlet call houzz-pro get_lead --data '{"lead_id":"lead_8c41d2"}'
```

### Example response

```json
{
  "lead_id": "lead_20418",
  "lead_name": "Miller Kitchen",
  "stage": "Proposal/Estimate Sent",
  "client": {
    "name": "Dana Miller",
    "email": "dana@example.com",
    "phone": "+1 555 0100"
  },
  "address": "12 Oak Street, Austin, TX",
  "description": "Full kitchen remodel, new cabinets and counters.",
  "estimated_revenue": 29500,
  "tasks": [
    {
      "task_id": "tsk_5521",
      "title": "Send revised layout",
      "due_date": "2026-10-09",
      "status": "open"
    }
  ]
}
```

## List projects

`POST https://cotlet.dev/api/v1/houzz-pro/list_projects`

Access: read.

Lists your projects, newest first, with client name and address. Search by project or client name. Use the project_id with the estimate, invoice, task and time tools. Pages hold up to 100 projects.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `query` | string | no | Search by project or client name. |
| `limit` | integer | no | 1 to 100. Default: 50. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/list_projects \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("houzz-pro", "list_projects")
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'list_projects');
```

**CLI**

```bash
cotlet call houzz-pro list_projects
```

### Example response

```json
{
  "projects": [
    {
      "project_id": "prj_30871",
      "name": "Oak Street Kitchen",
      "client_name": "Dana Miller",
      "address": "12 Oak Street, Austin, TX",
      "status": "active"
    }
  ],
  "next_cursor": null
}
```

## List tasks

`POST https://cotlet.dev/api/v1/houzz-pro/list_tasks`

Access: read.

Returns tasks as the Task Center shows them, sorted by due date, each with assignee, due date, status and the lead or project it belongs to. Assignees can be team members, clients or subs.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `project_id` | string | no | Only tasks of this project or lead. |
| `status` | enum | no | open, completed or all. Default: open. |
| `assignee` | string | no | Team member, client or sub name. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/list_tasks \
  -H "Authorization: Bearer $COTLET_API_KEY"
```

**Python**

```python
result = client.call("houzz-pro", "list_tasks")
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'list_tasks');
```

**CLI**

```bash
cotlet call houzz-pro list_tasks
```

### Example response

```json
{
  "tasks": [
    {
      "task_id": "tsk_5521",
      "title": "Send revised layout",
      "project": "Miller Kitchen",
      "assignee": "Sam Rivera",
      "due_date": "2026-10-09",
      "status": "open"
    }
  ]
}
```

## List estimates

`POST https://cotlet.dev/api/v1/houzz-pro/list_estimates`

Access: read.

Returns the estimates of one project with title, total and whether the client approved, declined or has not answered. Pass estimate_id to create_invoice.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `project_id` | string | yes | Project ID from list_projects. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/list_estimates \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":"project_8c41d2"}'
```

**Python**

```python
result = client.call("houzz-pro", "list_estimates", {"project_id":"project_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'list_estimates', {"project_id":"project_8c41d2"});
```

**CLI**

```bash
cotlet call houzz-pro list_estimates --data '{"project_id":"project_8c41d2"}'
```

### Example response

```json
{
  "estimates": [
    {
      "estimate_id": "est_48213",
      "title": "Kitchen remodel",
      "subtotal": 29500,
      "currency": "USD",
      "approval": "approved"
    }
  ]
}
```

## List invoices

`POST https://cotlet.dev/api/v1/houzz-pro/list_invoices`

Access: read.

Returns the invoices of one project with invoice code, total, status (for example draft or sent) and payments received. Issued invoices are locked in Houzz Pro.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `project_id` | string | yes | Project ID from list_projects. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/list_invoices \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":"project_8c41d2"}'
```

**Python**

```python
result = client.call("houzz-pro", "list_invoices", {"project_id":"project_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'list_invoices', {"project_id":"project_8c41d2"});
```

**CLI**

```bash
cotlet call houzz-pro list_invoices --data '{"project_id":"project_8c41d2"}'
```

### Example response

```json
{
  "invoices": [
    {
      "invoice_id": "inv_77105",
      "code": "INV-0012",
      "subtotal": 8850,
      "currency": "USD",
      "status": "draft",
      "paid": 0
    }
  ]
}
```

## Create lead

`POST https://cotlet.dev/api/v1/houzz-pro/create_lead`

Access: write.

Adds a lead to your pipeline. Lead name and client name are required; everything else is optional. Source can be any in your Lead Sources list. The lead reaches no client and is fixed by hand if wrong, so this tool runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `lead_name` | string | yes | Lead name. |
| `client_name` | string | yes | Client full name. |
| `email` | string | no | Client email. |
| `phone` | string | no | Client phone. |
| `address` | string | no | Lead address. |
| `project_type` | string | no | Project type. |
| `lead_source` | string | no | Where the lead came from. |
| `stage` | string | no | Lead stage. Default: New. |
| `tags` | string[] | no | Lead tags. |
| `estimated_revenue` | integer | no | Estimated revenue, whole currency units. |
| `description` | string | no | Notes about the project. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/create_lead \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_name":"lead name","client_name":"client name"}'
```

**Python**

```python
result = client.call("houzz-pro", "create_lead", {"lead_name":"lead name","client_name":"client name"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'create_lead', {"lead_name":"lead name","client_name":"client name"});
```

**CLI**

```bash
cotlet call houzz-pro create_lead --data '{"lead_name":"lead name","client_name":"client name"}'
```

### Example response

```json
{
  "lead_id": "lead_20457",
  "lead_name": "Miller Kitchen",
  "stage": "New",
  "lead_source": "Website",
  "tags": [
    "Spring"
  ],
  "status": "created"
}
```

## Update lead stage

`POST https://cotlet.dev/api/v1/houzz-pro/update_lead_stage`

Access: write.

Moves a lead to another stage, such as Connected or Won. Reaches no client and is undone by moving the lead back, so it runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `lead_id` | string | yes | Lead ID from list_leads. |
| `stage` | string | yes | Target stage, e.g. Connected or Won. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/update_lead_stage \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"lead_8c41d2","stage":"stage"}'
```

**Python**

```python
result = client.call("houzz-pro", "update_lead_stage", {"lead_id":"lead_8c41d2","stage":"stage"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'update_lead_stage', {"lead_id":"lead_8c41d2","stage":"stage"});
```

**CLI**

```bash
cotlet call houzz-pro update_lead_stage --data '{"lead_id":"lead_8c41d2","stage":"stage"}'
```

### Example response

```json
{
  "lead_id": "lead_20418",
  "stage": "Won",
  "status": "updated"
}
```

## Convert lead to project

`POST https://cotlet.dev/api/v1/houzz-pro/convert_lead_to_project`

Access: write. Confirm: waits for the user's OK before it runs.

Converts a lead to a project and carries the lead address over as the project address. Estimated start date and estimated revenue are optional. Houzz Pro cannot turn a project back into a lead. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `lead_id` | string | yes | Lead ID from list_leads. |
| `estimated_start` | date | no | Estimated start date. |
| `estimated_revenue` | integer | no | Estimated revenue, whole currency units. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/convert_lead_to_project \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"lead_8c41d2"}'
```

**Python**

```python
result = client.call("houzz-pro", "convert_lead_to_project", {"lead_id":"lead_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'convert_lead_to_project', {"lead_id":"lead_8c41d2"});
```

**CLI**

```bash
cotlet call houzz-pro convert_lead_to_project --data '{"lead_id":"lead_8c41d2"}'
```

### Example response

```json
{
  "project_id": "prj_30871",
  "name": "Miller Kitchen",
  "address": "12 Oak Street, Austin, TX",
  "estimated_start": "2026-11-03",
  "status": "converted"
}
```

## Create task

`POST https://cotlet.dev/api/v1/houzz-pro/create_task`

Access: write.

Creates a task on a lead or project and assigns it to a team member, client or sub; it then shows in the Task Center. Tasks for clients can be private or shared; this tool creates tasks for your team and subs, so nothing reaches a client. Runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `title` | string | yes | Task title. |
| `project_id` | string | no | Project or lead the task belongs to. |
| `assignee` | string | no | Team member or sub name. |
| `due_date` | date | no | Due date. |
| `description` | string | no | Task details. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/create_task \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"title":"title"}'
```

**Python**

```python
result = client.call("houzz-pro", "create_task", {"title":"title"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'create_task', {"title":"title"});
```

**CLI**

```bash
cotlet call houzz-pro create_task --data '{"title":"title"}'
```

### Example response

```json
{
  "task_id": "tsk_5530",
  "title": "Follow up on the Miller kitchen estimate",
  "project_id": "lead_20418",
  "assignee": "Sam Rivera",
  "due_date": "2026-10-14",
  "status": "open"
}
```

## Log time

`POST https://cotlet.dev/api/v1/houzz-pro/log_time`

Access: write.

Adds a time entry to a project. The activity sets rate, markup and taxable or billable status. By default the entry is yours; logging for another team member needs the Time Management permission. If time approval is on, the entry waits for approval. Entries linked to an issued invoice cannot be changed. Reaches no client, so it runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `project_id` | string | yes | Project ID from list_projects. |
| `activity` | string | yes | Activity name from your Time Management list. |
| `date` | date | yes | Day worked. |
| `hours` | string | yes | Time worked, e.g. 6 or 1.5. |
| `team_member` | string | no | Who worked. Default: you. Needs Time Management permission. |
| `description` | string | no | Notes. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/log_time \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":"project_8c41d2","activity":"activity","date":"2026-10-01","hours":"hours"}'
```

**Python**

```python
result = client.call("houzz-pro", "log_time", {"project_id":"project_8c41d2","activity":"activity","date":"2026-10-01","hours":"hours"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'log_time', {"project_id":"project_8c41d2","activity":"activity","date":"2026-10-01","hours":"hours"});
```

**CLI**

```bash
cotlet call houzz-pro log_time --data '{"project_id":"project_8c41d2","activity":"activity","date":"2026-10-01","hours":"hours"}'
```

### Example response

```json
{
  "entry_id": "te_9042",
  "project_id": "prj_30871",
  "activity": "Site Supervision",
  "date": "2026-10-11",
  "hours": 6,
  "status": "logged"
}
```

## Create estimate

`POST https://cotlet.dev/api/v1/houzz-pro/create_estimate`

Access: write.

Creates a draft estimate on a project from line items, each with description, quantity, unit price and a taxable flag. The draft stays in Houzz Pro until send_document emails it to the client, so this tool runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `project_id` | string | yes | Project ID from list_projects. |
| `title` | string | no | Estimate title. |
| `items` | object | yes | List of { description, quantity, unit_price, taxable }. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/create_estimate \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"project_id":"project_8c41d2","items":"items"}'
```

**Python**

```python
result = client.call("houzz-pro", "create_estimate", {"project_id":"project_8c41d2","items":"items"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'create_estimate', {"project_id":"project_8c41d2","items":"items"});
```

**CLI**

```bash
cotlet call houzz-pro create_estimate --data '{"project_id":"project_8c41d2","items":"items"}'
```

### Example response

```json
{
  "estimate_id": "est_48213",
  "project_id": "prj_30871",
  "title": "Kitchen remodel",
  "status": "draft",
  "subtotal": 29500,
  "currency": "USD",
  "items": 3
}
```

## Create invoice

`POST https://cotlet.dev/api/v1/houzz-pro/create_invoice`

Access: write.

Creates a draft invoice from an estimate: the whole estimate, selected line items or a percentage of the total, as progressive invoicing in Houzz Pro does. A code is generated at creation. Nothing reaches the client until send_document, so this tool runs without asking.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `estimate_id` | string | yes | Estimate ID from list_estimates. |
| `percent` | integer | no | Bill this percentage of the estimate (progressive invoicing). |
| `item_ids` | string[] | no | Bill only these line items. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/create_invoice \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"estimate_id":"est_48213","percent":30}'
```

**Python**

```python
result = client.call("houzz-pro", "create_invoice", {"estimate_id":"est_48213","percent":30})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'create_invoice', {"estimate_id":"est_48213","percent":30});
```

**CLI**

```bash
cotlet call houzz-pro create_invoice --data '{"estimate_id":"est_48213","percent":30}'
```

### Example response

```json
{
  "invoice_id": "inv_77105",
  "code": "INV-0012",
  "project": "Oak Street Kitchen",
  "status": "draft",
  "subtotal": 8850,
  "currency": "USD"
}
```

## Send document

`POST https://cotlet.dev/api/v1/houzz-pro/send_document`

Access: write. Confirm: waits for the user's OK before it runs.

Emails an estimate or invoice to the client, who can open it on a computer, phone or tablet. For invoices, issue_on_send locks the invoice when it is sent. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `document_id` | string | yes | Estimate or invoice ID. |
| `message` | string | no | Email message to the client. |
| `issue_on_send` | boolean | no | Invoices only: lock the invoice when sent. Default: false. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/houzz-pro/send_document \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"document_id":"document_8c41d2"}'
```

**Python**

```python
result = client.call("houzz-pro", "send_document", {"document_id":"document_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('houzz-pro', 'send_document', {"document_id":"document_8c41d2"});
```

**CLI**

```bash
cotlet call houzz-pro send_document --data '{"document_id":"document_8c41d2"}'
```

### Example response

```json
{
  "document_id": "inv_77105",
  "type": "invoice",
  "status": "sent",
  "issued": false,
  "sent_to": "dana@example.com"
}
```
