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
Thumbtack 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

read

POST 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

Parameters: list_leads
NameTypeDescription
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
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_leads \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("thumbtack", "list_leads")
Node.js
const result = await cotlet.call('thumbtack', 'list_leads');
CLI
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

read

POST 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

Parameters: get_lead
NameTypeDescription
lead_id required string Lead ID from list_leads.

Request

cURL
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
result = client.call("thumbtack", "get_lead", {"lead_id":"lead_8c41d2"})
Node.js
const result = await cotlet.call('thumbtack', 'get_lead', {"lead_id":"lead_8c41d2"});
CLI
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
}

POST 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

Parameters: list_messages
NameTypeDescription
lead_id required string Lead ID from list_leads.
limit integer 1 to 200. Default: 50.

Request

cURL
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
result = client.call("thumbtack", "list_messages", {"lead_id":"lead_8c41d2"})
Node.js
const result = await cotlet.call('thumbtack', 'list_messages', {"lead_id":"lead_8c41d2"});
CLI
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"
    }
  ]
}

POST 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

Parameters: list_opportunities
NameTypeDescription
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
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_opportunities \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("thumbtack", "list_opportunities")
Node.js
const result = await cotlet.call('thumbtack', 'list_opportunities');
CLI
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
}

POST 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

Parameters: list_reviews
NameTypeDescription
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
curl -X POST https://cotlet.dev/api/v1/thumbtack/list_reviews \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("thumbtack", "list_reviews")
Node.js
const result = await cotlet.call('thumbtack', 'list_reviews');
CLI
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

read

POST 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
curl -X POST https://cotlet.dev/api/v1/thumbtack/get_budget \
  -H "Authorization: Bearer $COTLET_API_KEY"
Python
result = client.call("thumbtack", "get_budget")
Node.js
const result = await cotlet.call('thumbtack', 'get_budget');
CLI
cotlet call thumbtack get_budget

Example response

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

Reply to lead

write Confirm

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

Parameters: reply_to_lead
NameTypeDescription
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
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
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
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
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"
}

Send message

write Confirm

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

Parameters: send_message
NameTypeDescription
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
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
result = client.call("thumbtack", "send_message", {"lead_id":"lead_8c41d2","body":"body"})
Node.js
const result = await cotlet.call('thumbtack', 'send_message', {"lead_id":"lead_8c41d2","body":"body"});
CLI
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"
}

Reach out to Opportunity

write Confirm

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

Parameters: reach_out_to_opportunity
NameTypeDescription
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
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
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
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
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
}

Send estimate

write Confirm

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

Parameters: send_estimate
NameTypeDescription
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
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
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
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
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
}

Reply to review

write Confirm

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

Parameters: reply_to_review
NameTypeDescription
review_id required string Review ID from list_reviews.
body required string Response text.

Request

cURL
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
result = client.call("thumbtack", "reply_to_review", {"review_id":"review_8c41d2","body":"body"})
Node.js
const result = await cotlet.call('thumbtack', 'reply_to_review', {"review_id":"review_8c41d2","body":"body"});
CLI
cotlet call thumbtack reply_to_review --data '{"review_id":"review_8c41d2","body":"body"}'

Example response

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

Set weekly budget

write Confirm

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

Parameters: set_weekly_budget
NameTypeDescription
amount required integer Weekly budget in whole currency units of your account.

Request

cURL
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
result = client.call("thumbtack", "set_weekly_budget", {"amount":1})
Node.js
const result = await cotlet.call('thumbtack', 'set_weekly_budget', {"amount":1});
CLI
cotlet call thumbtack set_weekly_budget --data '{"amount":1}'

Example response

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