Overview
Getting Started
MARKETPLACE
Widgets
MCP Server
Find Pros
Categories
Keywords
Requests
Leads
Messages
On-Demand Orders
Reviews
User Accounts
Testing Your Marketplace Integration
PRO INTEGRATIONS
Leads
Messages
Reviews
Pro Profiles
Business Phone Numbers
Manage Webhooks
Testing Your Pro Integration
Support
Changelog
Terms and Policies
Tools for pricing, paying for, and booking preset jobs. In development, subject to change.
The preset job toolset has nine tools. These tools are not read-only. Completing the flow will result in a preset job being booked for the user. These tools are available only to configured partners. Each partner has its own categories and must contact Thumbtack to enable the tools.
The server publishes instructions in its initialize response that guide AI agents on how to use the tools of the partner's toolset. The recommended workflow is:
Tool name: list_preset_job_categories
Lists the service categories that the partner can book at a fixed price. This is the primary entry point for the preset job workflow. It is the only tool that supplies a categoryID and a configurationID, which all other preset job tools need.
This tool takes no parameters.
Field | Type | Description |
|---|---|---|
categories | array of PresetJobCategory | The complete set of categories that can be booked at a fixed price |
count | integer | Number of bookable categories |
Each PresetJobCategory includes:
Field | Type | Description |
|---|---|---|
categoryID | string | Thumbtack category ID. Pass to check_preset_job_availability. |
categoryName | string | Human-readable category name, for matching against what the customer asked for |
configurationID | string | Order configuration ID. Pass to the request form, pricing, times, and booking tools. |
- Returns the categories configured for the calling partner. If a category has more than one configuration, the most recent configuration is returned.
- The list is exhaustive. If a service is not on the list, it cannot be booked at a fixed price. The assistant must tell the customer that the service is not available for instant booking, and must not guess a categoryID.
- If no categories are configured for the partner, the tool returns a text message and no categories.
Tool name: check_preset_job_availability
Checks whether enough preset job pros are available in the customer's area for a given category. Must be called after list_preset_job_categories.
Parameter | Type | Required | Description |
|---|---|---|---|
categoryID | string | Yes | Category ID from list_preset_job_categories. Never guess this value. |
zipCode | string | Yes | US ZIP code where the service is needed (5 digits) |
Field | Type | Description |
|---|---|---|
available | boolean | Whether there is enough pro supply to fulfill a preset job in this market |
eligibleProCount | integer | Number of eligible pros in this market |
categoryID | string | The category ID that was checked |
configurationID | string | Order configuration ID for this category. Pass to subsequent preset job tools. |
zipCode | string | The ZIP code that was checked |
- Looks up the partner's configuration for the category and checks pro supply in the ZIP code.
- If the category is not configured for the partner, the tool returns a text message that tells the assistant to call list_preset_job_categories. No structured result is returned.
- If available is false, the tool also returns a text message. The assistant should tell the customer that preset job booking is not available in this area yet, and can suggest a different ZIP code.
Tool name: get_preset_job_request_form
Returns the questions the customer must answer for the job. The answers refine the service and the price.
Parameter | Type | Required | Description |
|---|---|---|---|
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
Field | Type | Description |
|---|---|---|
requestFormID | string | Request form ID. Required by the pricing tools when answers are submitted. |
questions | array of Question | Questions the customer needs to answer |
prefilledQuestions | array of Question | Questions already answered by the configuration. Read-only, for context. Do not re-submit these answers. |
Each Question uses the same schema as the request form returned by search_home_service_pros (see Search Pros Tools).
- Returns only the questions that the configuration does not already answer.
- For choice-based questions (radioOption, checkboxOption), the assistant shows the text to the customer but submits the answerID, not the text.
Tool name: get_preset_job_available_times
Returns the appointment times that are available for the job in the customer's area.
Parameter | Type | Required | Description |
|---|---|---|---|
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
zipCode | string | Yes | US ZIP code where the service is needed (5 digits) |
Field | Type | Description |
|---|---|---|
availableDates | array of AvailableDate | Dates with available appointment times, sorted chronologically |
Each AvailableDate includes:
Field | Type | Description |
|---|---|---|
date | string | Date in YYYY-MM-DD format |
times | array of string (optional) | Exact start times in RFC 3339 format. Present when the configuration uses exact start times. |
slots | array of TimeSlot (optional) | Arrival windows, each with a startTime and an endTime in RFC 3339 format. Present when the configuration uses time windows. |
- Each date has either times or slots, depending on the configuration.
- All times are in the local time zone of the ZIP code.
- The value passed later as requestedTime is one of the times values, or the startTime of one of the slots.
- If no times are available, the tool returns a text message and no dates.
Tool name: get_preset_job_pricing
Returns the fixed price for the job, based on the configuration, location, request form answers, and appointment time. This tool creates a priced search project, which the booking tools use later.
Parameter | Type | Required | Description |
|---|---|---|---|
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
zipCode | string | Yes | US ZIP code where the service is needed (5 digits) |
requestFormID | string | Conditional | Request form ID from get_preset_job_request_form. Required when requestFormAnswers is provided. |
requestFormAnswers | array of PresetJobRequestFormAnswer | No | Customer answers to the request form. Omit to get a base price. Answers are added to the configuration's prefilled answers. |
requestedTime | string | No | Appointment time in RFC 3339 format. Must be at least 72 hours in the future and not more than 31 days ahead. |
Each PresetJobRequestFormAnswer includes:
Field | Type | Description |
|---|---|---|
questionID | string | Question ID from the request form |
answerIDs | array of string | Selected answer IDs, for choice-based questions (radioOption, checkboxOption) |
freeFormAnswer | string | Text answer, for text questions (singleLineText, multipleLineText) |
Field | Type | Description |
|---|---|---|
searchID | string | Priced search project ID. Save this value. Pass it to update_preset_job_pricing, create_preset_job_payment_terms, and create_preset_job. |
price | string | Formatted price (e.g., "$149.00") |
- Can be called without answers to show a base price early in the conversation.
- Each call creates a new search project. Use update_preset_job_pricing to change an existing one.
- The answers and the appointment time on the search project are carried onto the booked job.
Tool name: update_preset_job_pricing
Updates an existing priced search project with new or changed answers, or with a new appointment time, and returns the updated price. Must be called after get_preset_job_pricing.
Parameter | Type | Required | Description |
|---|---|---|---|
searchID | string | Yes | Search project ID from get_preset_job_pricing or a previous update_preset_job_pricing call |
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
requestFormID | string | Yes | Request form ID from get_preset_job_request_form |
requestFormAnswers | array of PresetJobRequestFormAnswer | Yes | Updated answers. These replace the answers submitted before. |
requestedTime | string | No | Appointment time in RFC 3339 format. Must be at least 72 hours in the future and not more than 31 days ahead. |
Field | Type | Description |
|---|---|---|
searchID | string | Updated search project ID. Use this value for all subsequent calls. |
price | string | Updated formatted price (e.g., "$179.00") |
- The answers in requestFormAnswers replace all previous answers. Send the full set of answers each time, not only the changed ones.
- The appointment time is stored on the search project. To change the appointment time, call this tool with the new requestedTime. The booking tools do not accept a time.
Tool name: create_preset_job_payment_terms
Returns the payment terms that a Stripe shared payment token must be minted against. This tool does not create the job and does not charge the customer. Call it only when the customer intends to book, because it creates or links the customer's Thumbtack account.
Before this tool is called, the assistant must:
- Tell the customer that the service is subject to Thumbtack's Terms of Use and Privacy Policy, and show both links as clickable links.
- Ask the customer to explicitly agree.
- Set termsAccepted to true only after the customer agrees.
The inputs are the same job details that are passed to create_preset_job, without the payment fields.
Parameter | Type | Required | Description |
|---|---|---|---|
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
user | PresetJobUser | Yes | Customer information: firstName, lastName, email, phoneNumber. The email is used to link or create a Thumbtack account. |
address | PresetJobAddress | Yes | Service address: address1, address2 (optional), city, state (2-letter code), zipCode. Must match the ZIP code the job was priced for. Sales tax is estimated for this address. |
externalOrderID | string | Yes | The partner's own reference ID for this order |
productDetails | array of PresetJobProductDetail | Yes | At least one product or service, each with name and sku, and optional description and imageURL. These name the service in the charge the customer approves, so pass the same items that will be booked. |
searchID | string | Yes | Search project ID from the most recent pricing call |
termsAccepted | boolean | Yes | Must be true. See the prerequisite above. |
The phoneNumber must be a US number. Common formats such as "(415) 555-0123" and "4155550123" are accepted and normalized to E.164.
Field | Type | Description |
|---|---|---|
amountCents | integer | The exact total to authorize, in cents, including sales tax |
currency | string | ISO 4217 currency code (e.g., usd) |
subtotalCents | integer | Pre-tax price of the job, in cents |
salesTaxCents | integer | Sales tax included in amountCents, in cents |
lineItems | array of PaymentLineItem | Breakdown to show the customer, each with a description and amountCents |
description | string | Description of the purchase, for the customer's approval screen |
networkID | string | Stripe business profile that the token must be scoped to |
idempotencyKey | string | Idempotency key to use when minting the token |
livemode | boolean | Whether the token must be minted with live Stripe credentials. False on staging, where no money moves. |
expiresAt | string | RFC 3339 time after which these terms are no longer honored. This is not the token expiry. |
minTokenExpiresAt | string | RFC 3339 earliest time the token may expire. Mint the token with an expires_at at or after this time. |
- Quotes the job from the priced search project. Call update_preset_job_pricing with the customer's chosen requestedTime first, so that the quote is for that time.
- The agent mints a Stripe shared payment token for exactly amountCents in currency, scoped to networkID, using idempotencyKey. A token for a lower amount, or a token scoped to a different profile, cannot be redeemed.
- The token's expires_at must be at or after minTokenExpiresAt. A token that expires earlier is refused at booking. Stripe allows an expires_at up to 90 days after the token is minted.
- Use idempotencyKey only for the first token of a booking. If create_preset_job declines the payment, its error names a different key for the replacement token.
- The assistant shows lineItems and description to the customer before the customer approves the charge.
- If expiresAt passes before the customer approves, call this tool again. The new terms can have a different amount, which needs a new token.
- 400, appointment too far away: No token can last long enough for this appointment. The error gives the latest appointment time that can be quoted. Ask the customer for an earlier time, call update_preset_job_pricing with it, then call this tool again. Do not book without a token.
- 409, configuration paid by the partner: There is nothing for the customer to pay. Do not ask the customer to authorize a charge. Call create_preset_job with no sharedPaymentToken and no authorizedAmountCents.
- 409, order already booked and paid: This externalOrderID was already used. To book another job, call this tool again with a new externalOrderID.
Tool name: create_preset_job
Books the preset job. This tool creates or links the customer's Thumbtack account, books the job for the appointment time on the priced search project, charges the customer when the customer is the payer, and sends the job to a pro to claim. There is no scheduling page for the customer to visit after booking.
The same consent requirement as create_preset_job_payment_terms applies. The assistant must get explicit consent before it sets termsAccepted to true.
Parameter | Type | Required | Description |
|---|---|---|---|
configurationID | string | Yes | Configuration ID from check_preset_job_availability |
user | PresetJobUser | Yes | Customer information: firstName, lastName, email, phoneNumber. The phone number must be a US number and is shared with the pro who claims the job. |
address | PresetJobAddress | Yes | Service address. Must match the ZIP code the job was priced for. |
externalOrderID | string | Yes | The partner's own reference ID for this order |
productDetails | array of PresetJobProductDetail | Yes | The same products or services passed to create_preset_job_payment_terms |
searchID | string | Yes | Search project ID from the most recent pricing call. It carries the answers and the appointment time onto the job. |
sharedPaymentToken | string | Conditional | Stripe shared payment token minted against the terms from create_preset_job_payment_terms. Required unless the partner pays. |
authorizedAmountCents | integer | Conditional | The amountCents that the token was minted for. Required with sharedPaymentToken. |
termsAccepted | boolean | Yes | Must be true. See the prerequisite above. |
Field | Type | Description |
|---|---|---|
orderID | string | Thumbtack order ID. Use it with get_preset_job_order_status. |
status | string | Status of the booked job |
categoryID | string | Category ID of the job |
externalOrderID | string | The partner's external order ID, echoed back |
customerID | string | Thumbtack customer ID that the job was booked for |
- If the job price changed after the shared payment token was minted, the booking is rejected before the job is created. The customer is never charged an amount they did not approve.
- If the customer's email matches a Thumbtack account, the job is linked to that account. If not, a new account is created and the customer receives an email to set a password.
- The job is created before the charge is attempted. If create_preset_job is retried for a job that already exists, the existing job is returned and the customer is not charged again. Use get_preset_job_order_status to confirm payment.
- 409, payment did not go through: The order exists but is unpaid. The error names an idempotency key for the replacement token. Mint the new token with that key, not the idempotencyKey from the payment terms, then call this tool again with the same externalOrderID.
Tool name: get_preset_job_order_status
Returns the current status and details of a booked preset job.
Parameter | Type | Required | Description |
|---|---|---|---|
orderID | string | Yes | Order ID from create_preset_job |
Field | Type | Description |
|---|---|---|
orderID | string | Thumbtack order ID |
status | enum | Scheduling status. One of: schedulingNotReady, schedulingReady, schedulingComplete, proMatchComplete, jobComplete, jobCancelled, jobRescheduled, proCancelled |
paymentStatus | enum (optional) | Payment status. One of: unpaid, pending, paid, failed, voided. Absent when the job has no charge to report yet. |
categoryID | string | Category ID of the job |
externalOrderID | string | The partner's external order ID |
appointmentStartsAt | string (optional) | Scheduled appointment start time in RFC 3339 format |
orderSchedulingURL | string (optional) | URL for the customer to complete scheduling on Thumbtack, if applicable |
userEmail | string | Customer email address |
userFirstName | string | Customer first name |
userLastName | string | Customer last name |
- status reports scheduling progress only. It does not report payment.
- A job with status schedulingComplete is booked, but is not necessarily paid. Read paymentStatus to confirm payment.
- For a customer-paid job, unpaid or failed means that the customer was not charged. The job needs a new shared payment token.
Last Updated: Oct 21st, 2026
On this page