# Thumbtack API

> Every Thumbtack 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/thumbtack

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)

12 endpoints for Thumbtack. Each one is a POST with a JSON body, called with your API key.

- Base URL: `https://cotlet.dev/api/v1/thumbtack`
- Connects with: Your own Thumbtack pro account
- Integration page: https://cotlet.dev/integrations/thumbtack-api-mcp-server

## Endpoints

| Endpoint | Access | Description |
|---|---|---|
| `list_leads` | read | Leads from your Jobs page, newest first, with service, location and whether you replied. |
| `get_lead` | read | Full lead: the customer's answers to the job questions, location and timing. |
| `list_messages` | read | Conversation with the customer on a lead, oldest first, with estimates you sent. |
| `list_opportunities` | read | Open Opportunities you can quote, with the cost shown upfront and when each closes. |
| `list_reviews` | read | Reviews on your profile with rating, text, date and your response if any. |
| `get_budget` | read | Your weekly lead budget and what you have spent against it so far this week. |
| `reply_to_lead` | write | Send your first message to a lead. The conversation moves to your Messages. |
| `send_message` | write | Send a message in an existing conversation with a customer. |
| `reach_out_to_opportunity` | write | Message an Opportunity with an optional quote. You are charged only if the customer responds. |
| `send_estimate` | write | Send an estimate in the conversation with line items, discount and tax. |
| `reply_to_review` | write | Post your public response under a review. Responses cannot be edited. |
| `set_weekly_budget` | write | Set the most you spend on leads in a week. |

## List leads

`POST https://cotlet.dev/api/v1/thumbtack/list_leads`

Access: read.

Lists leads in your Thumbtack pro account, newest first, including older leads that a webhook would never have sent. Filter by creation date to see what came in since your last check. Pass next_cursor back as cursor for the next page. Use get_lead for the customer's full answers.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `since` | date | no | Only leads created on or after this date. |
| `unreplied_only` | boolean | no | Only leads you have not replied to. |
| `limit` | integer | no | 1 to 100. Default: 25. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "list_leads")
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'list_leads');
```

**CLI**

```bash
cotlet call thumbtack list_leads
```

### Example response

```json
{
  "leads": [
    {
      "lead_id": "519153480500518912",
      "customer": "Dana R.",
      "service": "Kitchen Remodel",
      "location": "Austin, TX",
      "created_at": "2026-10-11T07:42:00-05:00",
      "replied": false
    }
  ],
  "next_cursor": "eyJvZmZzZXQiOjI1fQ"
}
```

## Get lead

`POST https://cotlet.dev/api/v1/thumbtack/get_lead`

Access: read.

Returns one lead with the customer's answers to the job questions, the job location and when they want the work done. Read it before replying so the message refers to the actual job.

### 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/thumbtack/get_lead \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"lead_8c41d2"}'
```

**Python**

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

**Node.js**

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

**CLI**

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

### Example response

```json
{
  "lead_id": "519153480500518912",
  "customer": "Dana R.",
  "service": "Kitchen Remodel",
  "location": "Austin, TX",
  "created_at": "2026-10-11T07:42:00-05:00",
  "answers": [
    {
      "question": "What type of project is this?",
      "answer": "Full remodel"
    },
    {
      "question": "When do you want to start?",
      "answer": "Within 2 weeks"
    }
  ],
  "replied": false
}
```

## List messages

`POST https://cotlet.dev/api/v1/thumbtack/list_messages`

Access: read.

Returns the messages of one conversation, oldest first, so the agent reads the thread in order before answering or pricing. Estimates you sent appear in the thread.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `lead_id` | string | yes | Lead ID from list_leads. |
| `limit` | integer | no | 1 to 200. Default: 50. |

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "list_messages", {"lead_id":"lead_8c41d2"})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'list_messages', {"lead_id":"lead_8c41d2"});
```

**CLI**

```bash
cotlet call thumbtack list_messages --data '{"lead_id":"lead_8c41d2"}'
```

### Example response

```json
{
  "lead_id": "519153480500518912",
  "messages": [
    {
      "from": "customer",
      "body": "Can you start the week of Oct 20?",
      "sent_at": "2026-10-11T08:05:00-05:00"
    },
    {
      "from": "you",
      "body": "Yes, I have an opening that week.",
      "sent_at": "2026-10-11T08:20:00-05:00"
    }
  ]
}
```

## List Opportunities

`POST https://cotlet.dev/api/v1/thumbtack/list_opportunities`

Access: read.

Lists Opportunities open to you, with the cost Thumbtack shows before you reach out. Thumbtack charges that cost only if you reach out and the customer responds. An Opportunity closes to quotes after 48 hours, once five pros have shown interest, or if the customer cancels; closes_at is the 48 hour mark.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `service` | string | no | Only Opportunities for this service, e.g. Deck Repair. |
| `limit` | integer | no | 1 to 50. Default: 25. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "list_opportunities")
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'list_opportunities');
```

**CLI**

```bash
cotlet call thumbtack list_opportunities
```

### Example response

```json
{
  "opportunities": [
    {
      "opportunity_id": "opp_30418",
      "customer": "Dana R.",
      "service": "Deck Repair",
      "location": "Austin, TX",
      "cost": 19,
      "closes_at": "2026-10-13T09:10:00-05:00"
    }
  ],
  "next_cursor": null
}
```

## List reviews

`POST https://cotlet.dev/api/v1/thumbtack/list_reviews`

Access: read.

Lists reviews on your pro profile, newest first, with rating, text and your response if you wrote one. Set unanswered_only to see the reviews that still need a reply. Use review_id with reply_to_review.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `unanswered_only` | boolean | no | Skip reviews you already responded to. |
| `limit` | integer | no | 1 to 100. Default: 25. |
| `cursor` | string | no | Next page cursor from the previous call. |

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "list_reviews")
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'list_reviews');
```

**CLI**

```bash
cotlet call thumbtack list_reviews
```

### Example response

```json
{
  "reviews": [
    {
      "review_id": "rev_8841",
      "rating": 5,
      "author": "Maria S.",
      "text": "Fixed our leaking sink in an hour. Great communication.",
      "created_at": "2026-10-08T16:30:00-05:00",
      "response": null
    }
  ],
  "next_cursor": null
}
```

## Get budget

`POST https://cotlet.dev/api/v1/thumbtack/get_budget`

Access: read.

Returns your weekly budget, the spend so far this week and the day it resets. The weekly budget limits spend on leads; Opportunities are paid separately and are not counted against it.

### Parameters

No parameters.

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "get_budget")
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'get_budget');
```

**CLI**

```bash
cotlet call thumbtack get_budget
```

### Example response

```json
{
  "weekly_budget": 300,
  "spent_this_week": 112,
  "resets": "Monday"
}
```

## Reply to lead

`POST https://cotlet.dev/api/v1/thumbtack/reply_to_lead`

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

Sends your first message to one lead, with optional photos or files by URL. The customer sees it right away and the conversation then lives in your Messages. 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. |
| `body` | string | yes | Message text. |
| `attachment_urls` | string[] | no | Photos or files to attach, by URL. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/thumbtack/reply_to_lead \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"519153480500518912","body":"Hi! Thanks for reaching out about your kitchen remodel. Could you send a few photos of the space?"}'
```

**Python**

```python
result = client.call("thumbtack", "reply_to_lead", {"lead_id":"519153480500518912","body":"Hi! Thanks for reaching out about your kitchen remodel. Could you send a few photos of the space?"})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'reply_to_lead', {"lead_id":"519153480500518912","body":"Hi! Thanks for reaching out about your kitchen remodel. Could you send a few photos of the space?"});
```

**CLI**

```bash
cotlet call thumbtack reply_to_lead --data '{"lead_id":"519153480500518912","body":"Hi! Thanks for reaching out about your kitchen remodel. Could you send a few photos of the space?"}'
```

### Example response

```json
{
  "lead_id": "519153480500518912",
  "message_id": "msg_7f3a91c2",
  "status": "sent",
  "sent_at": "2026-10-11T09:14:00-05:00"
}
```

## Send message

`POST https://cotlet.dev/api/v1/thumbtack/send_message`

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

Adds a message to a conversation that already exists, with optional photos or files by URL. The customer sees it right away. 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. |
| `body` | string | yes | Message text. |
| `attachment_urls` | string[] | no | Photos or files to attach, by URL. |

### Request

**cURL**

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

**Python**

```python
result = client.call("thumbtack", "send_message", {"lead_id":"lead_8c41d2","body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'send_message', {"lead_id":"lead_8c41d2","body":"body"});
```

**CLI**

```bash
cotlet call thumbtack send_message --data '{"lead_id":"lead_8c41d2","body":"body"}'
```

### Example response

```json
{
  "lead_id": "519153480500518912",
  "message_id": "msg_7f3a91d8",
  "status": "sent",
  "sent_at": "2026-10-11T09:30:00-05:00"
}
```

## Reach out to Opportunity

`POST https://cotlet.dev/api/v1/thumbtack/reach_out_to_opportunity`

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

Reaches out to one Opportunity with a message and an optional quote price. Thumbtack charges the cost shown in list_opportunities only if the customer responds, using your payment method, not your weekly budget. Fails if the Opportunity has closed. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `opportunity_id` | string | yes | Opportunity ID from list_opportunities. |
| `body` | string | yes | Message text. |
| `quote_price` | integer | no | Quote in whole currency units of your account, if you want to include one. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/thumbtack/reach_out_to_opportunity \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"opportunity_id":"opp_30418","body":"Hi Dana, I can replace the damaged deck boards this week. My price is $150 for the repair, materials included.","quote_price":150}'
```

**Python**

```python
result = client.call("thumbtack", "reach_out_to_opportunity", {"opportunity_id":"opp_30418","body":"Hi Dana, I can replace the damaged deck boards this week. My price is $150 for the repair, materials included.","quote_price":150})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'reach_out_to_opportunity', {"opportunity_id":"opp_30418","body":"Hi Dana, I can replace the damaged deck boards this week. My price is $150 for the repair, materials included.","quote_price":150});
```

**CLI**

```bash
cotlet call thumbtack reach_out_to_opportunity --data '{"opportunity_id":"opp_30418","body":"Hi Dana, I can replace the damaged deck boards this week. My price is $150 for the repair, materials included.","quote_price":150}'
```

### Example response

```json
{
  "opportunity_id": "opp_30418",
  "lead_id": "519153480500518977",
  "status": "sent",
  "quote_price": 150,
  "cost_if_customer_responds": 19
}
```

## Send estimate

`POST https://cotlet.dev/api/v1/thumbtack/send_estimate`

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

Sends an estimate in the lead's conversation with custom line items, an optional discount, tax and a message to the customer. The total is computed from the line items. Thumbtack cannot cancel a sent estimate; send a new one to correct it. 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. |
| `line_items` | object[] | yes | List of { name, unit, quantity, unit_price }. |
| `discount` | object | no | { type: percent or amount, value }. |
| `tax_percent` | number | no | Tax rate in percent. |
| `message` | string | no | Note to the customer. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/thumbtack/send_estimate \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"lead_id":"519153480500518912","line_items":[{"name":"Bedroom painting, walls","unit":"room","quantity":2,"unit_price":450},{"name":"Ceiling painting","unit":"ceiling","quantity":2,"unit_price":120}],"discount":{"type":"percent","value":10},"tax_percent":8.25,"message":"Includes paint and two coats. Start date as discussed."}'
```

**Python**

```python
result = client.call("thumbtack", "send_estimate", {"lead_id":"519153480500518912","line_items":[{"name":"Bedroom painting, walls","unit":"room","quantity":2,"unit_price":450},{"name":"Ceiling painting","unit":"ceiling","quantity":2,"unit_price":120}],"discount":{"type":"percent","value":10},"tax_percent":8.25,"message":"Includes paint and two coats. Start date as discussed."})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'send_estimate', {"lead_id":"519153480500518912","line_items":[{"name":"Bedroom painting, walls","unit":"room","quantity":2,"unit_price":450},{"name":"Ceiling painting","unit":"ceiling","quantity":2,"unit_price":120}],"discount":{"type":"percent","value":10},"tax_percent":8.25,"message":"Includes paint and two coats. Start date as discussed."});
```

**CLI**

```bash
cotlet call thumbtack send_estimate --data '{"lead_id":"519153480500518912","line_items":[{"name":"Bedroom painting, walls","unit":"room","quantity":2,"unit_price":450},{"name":"Ceiling painting","unit":"ceiling","quantity":2,"unit_price":120}],"discount":{"type":"percent","value":10},"tax_percent":8.25,"message":"Includes paint and two coats. Start date as discussed."}'
```

### Example response

```json
{
  "lead_id": "519153480500518912",
  "estimate_id": "est_5521",
  "status": "sent",
  "subtotal": 900,
  "discount": 90,
  "total": 810
}
```

## Reply to review

`POST https://cotlet.dev/api/v1/thumbtack/reply_to_review`

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

Posts your public response under one review, under your business name. Thumbtack does not let you edit a response once it is submitted. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `review_id` | string | yes | Review ID from list_reviews. |
| `body` | string | yes | Response text. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/thumbtack/reply_to_review \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"review_id":"review_8c41d2","body":"body"}'
```

**Python**

```python
result = client.call("thumbtack", "reply_to_review", {"review_id":"review_8c41d2","body":"body"})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'reply_to_review', {"review_id":"review_8c41d2","body":"body"});
```

**CLI**

```bash
cotlet call thumbtack reply_to_review --data '{"review_id":"review_8c41d2","body":"body"}'
```

### Example response

```json
{
  "review_id": "rev_8841",
  "status": "published"
}
```

## Set weekly budget

`POST https://cotlet.dev/api/v1/thumbtack/set_weekly_budget`

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

Sets your weekly lead budget. Once the budget is reached, new leads stop until it resets the following Monday. Opportunities are paid separately. By default you confirm each call; you can switch that off for this tool.

### Parameters

| Name | Type | Required | Description |
|---|---|---|---|
| `amount` | integer | yes | Weekly budget in whole currency units of your account. |

### Request

**cURL**

```bash
curl -X POST https://cotlet.dev/api/v1/thumbtack/set_weekly_budget \
  -H "Authorization: Bearer $COTLET_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"amount":1}'
```

**Python**

```python
result = client.call("thumbtack", "set_weekly_budget", {"amount":1})
```

**Node.js**

```js
const result = await cotlet.call('thumbtack', 'set_weekly_budget', {"amount":1});
```

**CLI**

```bash
cotlet call thumbtack set_weekly_budget --data '{"amount":1}'
```

### Example response

```json
{
  "weekly_budget": 200,
  "previous_weekly_budget": 300,
  "spent_this_week": 112
}
```
