REST API reference
Thumbtack API
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
- Thumbtack
| 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
readPOST https://cotlet.dev/api/v1/thumbtack/list_leads
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 | Description |
|---|---|---|
| since | date | Only leads created on or after this date. |
| unreplied_only | boolean | Only leads you have not replied to. |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_leads \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("thumbtack", "list_leads") const result = await cotlet.call('thumbtack', 'list_leads'); cotlet call thumbtack list_leads Example response
{
"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
readPOST https://cotlet.dev/api/v1/thumbtack/get_lead
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 | Description |
|---|---|---|
| lead_id required | string | Lead ID from list_leads. |
Request
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"}' result = client.call("thumbtack", "get_lead", {"lead_id":"lead_8c41d2"}) const result = await cotlet.call('thumbtack', 'get_lead', {"lead_id":"lead_8c41d2"}); cotlet call thumbtack get_lead --data '{"lead_id":"lead_8c41d2"}' Example response
{
"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
readPOST https://cotlet.dev/api/v1/thumbtack/list_messages
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 | Description |
|---|---|---|
| lead_id required | string | Lead ID from list_leads. |
| limit | integer | 1 to 200. Default: 50. |
Request
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"}' result = client.call("thumbtack", "list_messages", {"lead_id":"lead_8c41d2"}) const result = await cotlet.call('thumbtack', 'list_messages', {"lead_id":"lead_8c41d2"}); cotlet call thumbtack list_messages --data '{"lead_id":"lead_8c41d2"}' Example response
{
"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
readPOST https://cotlet.dev/api/v1/thumbtack/list_opportunities
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 | Description |
|---|---|---|
| service | string | Only Opportunities for this service, e.g. Deck Repair. |
| limit | integer | 1 to 50. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_opportunities \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("thumbtack", "list_opportunities") const result = await cotlet.call('thumbtack', 'list_opportunities'); cotlet call thumbtack list_opportunities Example response
{
"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
readPOST https://cotlet.dev/api/v1/thumbtack/list_reviews
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 | Description |
|---|---|---|
| unanswered_only | boolean | Skip reviews you already responded to. |
| limit | integer | 1 to 100. Default: 25. |
| cursor | string | Next page cursor from the previous call. |
Request
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_reviews \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("thumbtack", "list_reviews") const result = await cotlet.call('thumbtack', 'list_reviews'); cotlet call thumbtack list_reviews Example response
{
"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
readPOST https://cotlet.dev/api/v1/thumbtack/get_budget
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 -X POST https://cotlet.dev/api/v1/thumbtack/get_budget \
-H "Authorization: Bearer $COTLET_API_KEY" result = client.call("thumbtack", "get_budget") const result = await cotlet.call('thumbtack', 'get_budget'); cotlet call thumbtack get_budget Example response
{
"weekly_budget": 300,
"spent_this_week": 112,
"resets": "Monday"
} POST https://cotlet.dev/api/v1/thumbtack/reply_to_lead
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 | Description |
|---|---|---|
| lead_id required | string | Lead ID from list_leads. |
| body required | string | Message text. |
| attachment_urls | string[] | Photos or files to attach, by URL. |
Request
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?"}' 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?"}) 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?"}); 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
{
"lead_id": "519153480500518912",
"message_id": "msg_7f3a91c2",
"status": "sent",
"sent_at": "2026-10-11T09:14:00-05:00"
} POST https://cotlet.dev/api/v1/thumbtack/send_message
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 | Description |
|---|---|---|
| lead_id required | string | Lead ID from list_leads. |
| body required | string | Message text. |
| attachment_urls | string[] | Photos or files to attach, by URL. |
Request
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"}' result = client.call("thumbtack", "send_message", {"lead_id":"lead_8c41d2","body":"body"}) const result = await cotlet.call('thumbtack', 'send_message', {"lead_id":"lead_8c41d2","body":"body"}); cotlet call thumbtack send_message --data '{"lead_id":"lead_8c41d2","body":"body"}' Example response
{
"lead_id": "519153480500518912",
"message_id": "msg_7f3a91d8",
"status": "sent",
"sent_at": "2026-10-11T09:30:00-05:00"
} POST https://cotlet.dev/api/v1/thumbtack/reach_out_to_opportunity
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 | Description |
|---|---|---|
| opportunity_id required | string | Opportunity ID from list_opportunities. |
| body required | string | Message text. |
| quote_price | integer | Quote in whole currency units of your account, if you want to include one. |
Request
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}' 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}) 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}); 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
{
"opportunity_id": "opp_30418",
"lead_id": "519153480500518977",
"status": "sent",
"quote_price": 150,
"cost_if_customer_responds": 19
} POST https://cotlet.dev/api/v1/thumbtack/send_estimate
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 | Description |
|---|---|---|
| lead_id required | string | Lead ID from list_leads. |
| line_items required | object[] | List of { name, unit, quantity, unit_price }. |
| discount | object | { type: percent or amount, value }. |
| tax_percent | number | Tax rate in percent. |
| message | string | Note to the customer. |
Request
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."}' 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."}) 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."}); 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
{
"lead_id": "519153480500518912",
"estimate_id": "est_5521",
"status": "sent",
"subtotal": 900,
"discount": 90,
"total": 810
} POST https://cotlet.dev/api/v1/thumbtack/reply_to_review
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 | Description |
|---|---|---|
| review_id required | string | Review ID from list_reviews. |
| body required | string | Response text. |
Request
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"}' result = client.call("thumbtack", "reply_to_review", {"review_id":"review_8c41d2","body":"body"}) const result = await cotlet.call('thumbtack', 'reply_to_review', {"review_id":"review_8c41d2","body":"body"}); cotlet call thumbtack reply_to_review --data '{"review_id":"review_8c41d2","body":"body"}' Example response
{
"review_id": "rev_8841",
"status": "published"
} POST https://cotlet.dev/api/v1/thumbtack/set_weekly_budget
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 | Description |
|---|---|---|
| amount required | integer | Weekly budget in whole currency units of your account. |
Request
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}' result = client.call("thumbtack", "set_weekly_budget", {"amount":1}) const result = await cotlet.call('thumbtack', 'set_weekly_budget', {"amount":1}); cotlet call thumbtack set_weekly_budget --data '{"amount":1}' Example response
{
"weekly_budget": 200,
"previous_weekly_budget": 300,
"spent_this_week": 112
}