- Brand
- Gusto
- Category
- Finance
- Primary Subcategory
- Payroll, EOR & HR Operations
Integration details
Description
Get people and payroll work done in ChatGPT with the Gusto plugin, don’t just ask questions about it. Prepare an upcoming payroll and review against recent runs to catch what needs attention before payday. Fix timesheets, bring in hours, tips, and reimbursements from spreadsheets, or onboard a new hire from their offer letter, all in a chat thread. The Gusto plugin for ChatGPT connects to your live people and payroll data, tools support detailed queries of structured data as well as writes that require confirmation.
- Integration type
- Plugin
- Verification status
- Not applicable
- Platform
- ChatGPT
- Primary Subcategory
- Payroll, EOR & HR Operations
- Secondary Subcategories
- None listed
- Brand
- Gusto
- Access
- Account required
- First tracked
- 2026-09-10
- Tool count
- 54
- Geography
- US
The Primary Subcategory used for this profile’s headline score.
Other Subcategories where the Integration is listed.
Your Plugin is discoverable
ChatGPT now suggests Plugins on its own when they match a user's request.Gusto is being suggested, and your Discoverability Score is being created. It will show here as soon as it’s ready.
What discovery looks like

Get alerts for Gusto
Get updates when Gusto’s Discoverability Score or category rank changes.
Competing in ChatGPT Payroll, EOR & HR Operations
View Category54 tools agents can invoke
Marks the Solo S-corp owner's in-progress reasonable-salary estimate as accepted, recording the chosen W-2 salary for IRS-defensibility purposes. Call this LAST in the Reasonable Salary Calculator flow. Before calling, confirm the user has reviewed the calculated estimate and explicitly wants to accept that number; do not call `accept_reasonable_salary` automatically just because a `calculate_reasonable_salary` call succeeded. IMPORTANT - any later change to the estimate's inputs silently clears the acceptance, so accept must be the final step. The company and owner come from the token context, never the caller, so this requires an existing company — if the account does not have one yet, call create_company first, otherwise this fails. It accepts the single most recently calculated in-progress estimate for that owner; if several `calculate_reasonable_salary` calls were made, only the latest can be accepted (each overwrote the previous). Pass `salary` to accept a specific figure the user chose from inside the estimate's `range`, or omit it to accept the recommended `result` - never pass a number the user did not name. On success, returns the accepted estimate (id, result and acceptedSalary as integer USD amounts, range, acceptedAt); acceptedSalary is the figure that was actually recorded. On failure, the response `errors` list names a structured kind - "no_in_progress_estimate" (calculate a reasonable salary estimate first), "company_not_eligible" (company is not taxed as an S-corp), "salary_out_of_range" (the `salary` passed falls outside the estimate's range; re-offer a figure inside it), or "no_draft_team_member" (owner profile not ready yet, usually a brief race after signup; retry shortly). This does NOT set the owner's actual pay rate, file any tax form, or finalize the estimate to an employee job - accepting records the number, and a later manage_company_members call is what puts it on payroll. The accepted figure comes back from get_company_onboarding_status as owner_profile.accepted_reasonable_salary, so it survives past this conversation; read it from there rather than remembering it. ONBOARDING HANDOFF — RSC is reached two ways, and acceptance means different things in each. (1) Standalone: the owner came directly to figure out their salary; after a successful accept, confirm the saved number and you're done. (2) As an onboarding step: an earlier `get_company_onboarding_status` `next_step` routed you here (its `detail` was `reasonable_salary_calculator`). In that case acceptance is NOT the end of onboarding — after a successful accept, call `get_company_onboarding_status` again. Acceptance advances the flow, so the refreshed `next_step` points to the real next step (typically `continue_in_gusto` with the URL to send the owner to). Never invent or hardcode that destination URL yourself; always take it from the refreshed onboarding status — and if it comes back as `set_password` instead, there is no URL to relay: follow that step's own message. Either way the accepted salary still has to reach payroll: when the flow later has you finalize the owner with manage_company_members, pass that figure as `amount` with `payment_unit` YEAR instead of asking them what to pay themselves. Skipping it leaves them on payroll at no salary.
accept_reasonable_salary
Internal tool for payroll calculation. Use run_payroll instead.
calculate_payroll
Calculates an IRS-defensible reasonable salary for an S-corp owner from Bureau of Labor Statistics (BLS) wage data, given the company's ZIP code and one or more occupations. Returns the recommended annual salary, a defensible range, and the BLS wage area. Look up each occupation `code` with `search_business_info` (type `occupation`) first. GATHERING INPUTS — collect what this tool needs conversationally, one step at a time; don't ask for everything in one message and don't assume values. Follow this order: 1. Location first. Ask for the company's 5-digit ZIP code — it sets the BLS wage area. If the user offers only a city or state, ask them for the ZIP rather than guessing one yourself; a guessed ZIP can land on the wrong wage area. 2. Roles, one at a time. Ask what the owner does, then call `search_business_info` (type `occupation`) for that role, present the candidates, and let the user pick the `code` before asking about anything else — never guess BLS codes. Most owners have a single role; only gather more if the user says they wear more than one hat, resolving each role fully before starting the next. 3. Per-role details. For each chosen occupation confirm `experience_level`, plus — for a multi-role owner — the `time_percentage` split and which role is `primary`. Offer a sensible default and let the user adjust; don't apply these silently. 4. Optional refinements. Only if relevant, ask about a part-time `work_schedule` or an `annual_net_revenue` cap; otherwise leave them out. Confirm every input before calling. A failure returns a `kind` and a `message`; branch on `kind`, not on the message text. RECOVERABLE — fix the inputs per the `message` and re-call: `no_occupations` (the `occupations` array was empty — gather at least one role, per step 2), `time_percentages_not_100`, `duplicate_occupation_code`, `multiple_primary_occupations`, `part_time_hours_required`, `incomplete_occupation` (a role is missing an experience level or time percentage), `invalid_occupation_code` (re-run `search_business_info`), `missing_area` and `zip_lookup_failed` (re-confirm the business's 5-digit ZIP), and `salary_data_unavailable` (BLS publishes no wages for that role, even nationally — ask for a different role). Several of these are about one role rather than the whole request. For `duplicate_occupation_code` and `incomplete_occupation` the `message` names the role — fix only that one, and do not re-gather the others. For `invalid_occupation_code` and `salary_data_unavailable` the message does NOT say which role it was, so with more than one role you cannot tell from the response alone: re-check the codes you sent with `search_business_info` rather than guessing, and ask the user before dropping a role. TERMINAL — do NOT re-call with the same company; say what happened and stop: `company_not_eligible` (reasonable salary applies only to companies taxed as an S-corp, which no input change fixes) and `no_draft_team_member` (the owner's profile is not ready yet — tell the user to try again later rather than retrying in this conversation). Treat an unfamiliar `kind` as recoverable by reading its `message`, rather than failing the conversation. Make ONE call once the inputs are confirmed. When the owner fills more than one role (e.g. a founder who both writes software and runs the business as CEO), list every role in the `occupations` array with `time_percentage` values summing to 1.0 in that single call — do not fire separate `calculate_reasonable_salary` calls per role. The tool blends them into one composite salary; separate calls would each overwrite the last. This tool keeps ONE in-progress estimate per company/owner: every successful call overwrites that single estimate and there is no history, so do not issue parallel or speculative calls — to compare scenarios, run them one at a time and show each result before recalculating. The estimate is referenced implicitly by the authenticated company/owner, so this call intentionally returns no `id`; `accept_reasonable_salary` returns the persisted estimate's `id`. After a successful calculation, present the recommended salary and range and ask whether the owner wants to accept it as their W-2 salary; if they confirm, call `accept_reasonable_salary`. Do not call `accept_reasonable_salary` without explicit user confirmation (see that tool's description).
calculate_reasonable_salary
Reports where the company's Plaid bank connection stands. Use this to confirm the outcome of a connect_bank_via_plaid link, since that flow finishes in an external browser window and reports back to Gusto out of band — nothing in this conversation observes it directly. WHEN TO USE: After the user says they have finished (or abandoned) a Plaid link, to find out what actually landed before telling them anything. Also safe to use to check whether a company already has a bank connection before offering the Plaid flow at all. WHEN NOT TO USE: Do not poll this repeatedly in a loop while waiting — the connection only appears once Plaid reports the finished session, so call it when the user says they are done. Do not use it to ask the user for bank account or routing numbers; it only reads existing state. RETURNS: This reports the company's most recent live bank connection, not a roll-up of every bank account it has — a company can hold an already-verified account while a newly connected one is still verifying, and this reports the new one. Always branch on `status`, not on `success` alone — `success: true` only means the check ran. `connected: true` with `status: "connected"` means the bank is verified and onboarding can move on. `status: "pending_micro_deposits"` means the bank is connected but verifying over 1-2 business days; nothing further is needed from the user, so do not re-offer the link. `status: "not_connected"` means nothing landed, so the user likely did not finish. `status: "connection_unusable"` means the latest attempt failed and needs a fresh link. When present, `account_last_digits` is the last few digits of the connected account, safe to read back to the user for confirmation. On error, `{ success: false, error_type, message }`. PREREQUISITES: A valid access token whose company the acting user is a member of. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
check_plaid_connection_status
Gives the user a link to connect the company's payroll funding account — the account payroll and taxes are paid from. For most companies it is a Plaid-hosted flow that verifies instantly in most cases; for a company that cannot use Plaid here it is a Gusto web page instead (see RETURNS). This is the ONLY way to add a bank account during onboarding: the bank questions cannot be answered in chat, and save_company_onboarding_answer rejects them. Whatever the user enters in the Plaid flow or in Gusto web goes straight to Plaid or Gusto — this tool does NOT collect bank account numbers, routing numbers, or banking credentials through the conversation, and you never see what was entered. NAMING: When you tell the user about this step, call it the company's payroll funding account. Do not shorten it to "your bank account". WHEN TO USE: Whenever next_step returns detail `connect_bank`, or the user asks to add or change the company's payroll funding account. There is no way to enter the numbers in chat to offer alongside it. WHEN NOT TO USE: Never ask the user to type a bank login, routing number, or account number into chat, and never offer to enter those on their behalf — not as an alternative to this tool, not if the user asks to, and not if they volunteer the numbers unprompted. Those are entered only in the Plaid flow or in Gusto web. If the user will not use Plaid, send them to Gusto to add the account there. Do not call this again for the same company while a link from earlier in this conversation is still pending — wait for the user to say they've finished, then confirm with check_plaid_connection_status before offering it again. Exception: after a `continue_in_gusto` result, never call check_plaid_connection_status (it only reads legacy Plaid connections and reports not_connected for that company); while the company is onboarding, confirm with get_company_onboarding_status instead. RETURNS: Branch on `success`. On success, `{ success: true, status: "plaid_connection_pending", url, message }` — tell the user to open the link, connect the company's payroll funding account, and come back; do not ask them to report back what they saw or any account details. For a company that cannot use Plaid here, `{ success: true, status: "continue_in_gusto", url, message }` — tell the user to open the link and connect the account in Gusto web; no Plaid session was started. On error, `{ success: false, error_type, message }`. PREREQUISITES: A valid access token whose company the acting user is a member of. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
connect_bank_via_plaid
SIGNUP/ONBOARDING PHASE tool, and the first step — the other onboarding tools are company-scoped and fail until this has created a company. Create the user's Gusto company and payroll-admin account once the user has confirmed the details they want to sign up with. Use this tool for account creation; do not call a separate lead tool first (the lead is created server-side). The account email is already established — it is the address the user verified when they signed in. Do not ask the user for an email. Call create_company with the confirmed flag set to false first; the response returns `account_email`. Confirm that address and the company details with the user, then call again with the confirmed flag set to true. Company creation is not the final account step for chat signups. After onboarding setup is complete, Gusto sends a password setup email, and the user must open that email to finish securing the account and sign in to Gusto directly. Required fields, company_name, first_name, last_name, confirmed. Optional enrichment fields, number_employees, phone, states.
create_company
Enqueues one or more reports. A single-payroll entry usually finishes in 10-60 seconds. A payroll_journal date-range entry can take up to an hour for a company with over 100 active employees, since it routes to a slower queue -- other date-range report types (e.g. contractor_payments_summary) run on a faster queue and don't have that delay. After calling this tool, call get_reports to check progress. There's no wait primitive here and no clock to pace a fixed cadence against, so check at most 5 times, a few seconds apart, then tell the user the report is still generating rather than looping indefinitely -- especially for a payroll_journal date-range entry, where a handful of quick checks won't be enough; don't mistake incomplete generation for failure. Use this tool, not get_payroll, whenever the user asks for a "payroll report", "payroll summary report", "payroll journal report", "payroll journal", or a CSV/exportable payroll document -- these all describe the same report_type: payroll_journal, not distinct or ambiguous intents. get_payroll only returns raw JSON line-item details for a single payroll; it does not produce a report file. Available report types: - payroll_journal: Payroll Journal Report (CSV). Either payroll_uuid for a single payroll (its company is looked up automatically, so company_uuid is not needed), or company_uuid plus a start_date/end_date date range (dates alone can't identify a company -- if you don't already know it, call get_token_info first: use resource.uuid for a single-company token, or pick one from accessible_resources for a multi-company token). Dates filter on paycheck date (the day employees are paid), not pay period -- list_payrolls defaults to pay-period dates, so pass date_filter_by=check_date and processing_statuses=processed there to match this report's basis. The date range cannot exceed 366 days. Use list_payrolls to find a payroll_uuid if unsure. - cash_requirements: Cash Requirements Report, summarizing the cash needed to fund a single payroll. Requires payroll_uuid (its company is looked up automatically). There is no date-range variant. - contractor_payments_summary: Contractor Payments Summary Report (CSV). Requires company_uuid plus a start_date/end_date date range (dates alone can't identify a company -- if you don't already know it, call get_token_info first). Dates filter on paycheck date. The date range cannot exceed 366 days. There is no single-payroll variant. Not every report type is available on every connection. Attempt the entry either way and react to the result: if it comes back with error_type restricted_report, this connection cannot create that report type and retrying will not help, so tell the user instead. Returns {reports: [...]}, one entry per input entry, in the same order. A successful entry is {company_uuid, report_request_uuid, status: 'pending', message}; a failed one is {company_uuid, success: false, error} with no report_request_uuid -- skip entries carrying success: false rather than assuming every entry has an id to poll.
create_reports
Estimates the annual federal R&D tax credit (IRC §41) a business could claim, from how many US people work on building or improving its product, what they're paid on average, and what the business does. Returns the estimated credit, the inputs it used, and `guidance`. A ballpark for comparison, NOT tax advice, and it files nothing. CALL IT BEFORE ASKING THE USER ANYTHING. Every argument is optional, so pass whatever they have already told you and call it empty only when they have told you nothing — calling empty and then again with numbers already in hand just costs a round trip. If they are signed in to Gusto the server already knows their business and may hand back a complete estimate with no questions at all — for a company that has run payroll that is Gusto's own modelled estimate from real payroll, better than anything these three inputs can produce. The company's own figures take precedence over values you pass, so a number the user guessed cannot improve the answer and asking for it wastes their time. It also needs no company, EIN, entity or payroll history at all, so a business that isn't a Gusto customer still gets an estimate from the three inputs below. ALWAYS FOLLOW `guidance`, returned on every response. It says how to present the number, what to ask for next, and whether an industry code would change anything. It is the authority when it differs from this description; paraphrase it rather than reading it out. When `needs` is non-empty, ask for everything it names in one message and call again. Never invent a headcount, a salary or an industry code: a guessed number becomes a number the user believes. Resolve an industry code with `search_business_info` (type `industry`) from the business's own words and let the user pick, but only when `guidance` asks for one. IT DOES NOT ANSWER WHETHER THEY QUALIFY. That turns on whether the work itself looks like research, which this tool never sees. A number here is what the credit could be worth if they qualify, never confirmation that they do, AND A LOW NUMBER IS NOT EVIDENCE THEY DON'T — it reflects only headcount and pay. Send "can we claim this?" to `check_rd_credit_qualification`. NOT THE SAME AS ITS NEIGHBOURS: `calculate_scorp_tax_savings` estimates savings from electing S-corp status, and `calculate_reasonable_salary` suggests an owner's W-2 salary. Neither has anything to do with the R&D credit. `check_rd_credit_qualification` answers whether the work qualifies at all. Use this tool for "how much".
calculate_rd_tax_credit
Retrieves comprehensive business profile information including legal name, business entity type (LLC, Corporation, etc.), EIN, primary contact details, and configured locations. Use this to answer questions about company setup, business structure, or basic organizational info. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
get_company
SIGNUP/ONBOARDING PHASE tool. Requires an existing company — if the account does not have one yet, this reports company_exists false and next_step create_company; call create_company, then retry. Returns the company's available plans, add-ons, and benefits during onboarding, plus Gusto's recommended package and the company's current selection. Use this to present the options and the recommendation, compare tiers, or answer pricing questions — all from the returned payload. ONCE THE PROFILE IS READY FOR A RECOMMENDATION: when the only required question left in get_company_onboarding_status is the plan choice (tier_selection) — i.e. every other required question is answered — call this tool to present Gusto's recommendation: explain what's included and why it fits their profile, then ask whether they'd like to proceed with the recommended plan or explore other options before you save their tier_selection (via save_company_onboarding_answer). Do NOT wait for tier_selection itself to be answered before presenting the recommendation — the recommendation is what informs that choice. WHEN TO USE: When the user is choosing or asking about a Gusto plan during onboarding — to present available plans/add-ons, show the recommendation and why, compare tiers, or answer "how much does X cost". WHEN NOT TO USE: To read a single onboarding question — use get_onboarding_answer. DATA RETURNED (keys are camelCase): `plans` and `addOns`, each with `key` (the value to save as `plan`/`add_ons`; `stableId` is also present but may be null, so use `key`), `name`, `description`, and a `pricing` object (`baseFee`, `perEmployeeFee`, `currency`; a fee is null when not charged); `benefits` with `key`, `name`, and `pricingNote` (quoted with partner carriers at setup, not on the Gusto invoice); the `recommended` package (`plan`, `addOns`, `benefits`, and a `rationale`) and the company's current `selected` package; readyForPackageRecommendation (whether every required profile question EXCEPT the plan choice is answered — i.e. the recommendation is ready to present); and profileComplete (whether ALL required questions, including the plan choice, are answered). The recommended block is null until readyForPackageRecommendation is true and a recommendation has been computed. The recommendation is computed once and reflects the profile answers at that time; it is not recomputed here if answers change afterward. SIDE EFFECT: not a pure read — the first call made once the profile is ready computes and stores Gusto's recommendation (a one-time computation; later calls do not recompute it). Calling it before the profile is ready is a safe no-op for the recommendation (the recommended block stays null). PREREQUISITES: The recommendation populates once the company's required profile questions EXCEPT the plan choice are answered (see get_company_onboarding_status). VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
get_company_onboarding_package
SIGNUP/ONBOARDING PHASE tool. Requires an existing company — if the account does not have one yet, this reports company_exists false and next_step create_company; call create_company, then retry. Returns the onboarding status for a company's current experience. The current experience includes its questions — each with a key, a description, whether it has been answered, whether it is required, and a value_schema describing the fields its answer expects (field name, type, and allowed enum values). Use the value_schema to construct the value for save_company_onboarding_answer without guessing field names. Some answers are resolved with a helper tool rather than the value_schema alone: for `industry_selection` call search_business_info (type "industry"), present its candidates and let the user pick one rather than choosing for them — unless they name a code themselves, which already is their pick — and never guess NAICS/SIC codes. Separately, some large, well-known fields are free-text coded — their value_schema shows a string array with no enum list (e.g. states_employees_work_in, international_employees_countries). For these, collect the user's answer in natural language and map it to canonical codes yourself: US states as 2-letter uppercase codes including DC and PR (other US territories are not accepted), and countries as ISO 3166-1 alpha-2 (e.g. GB, IN, MX) — don't present the full list as options. A save with an invalid code returns the allowed values so you can correct it. Also returns total_questions and answered_questions counts (over every question listed here, required or not; questions withheld from this list are not counted). DRIVING ONBOARDING — work through the questions with the user and save each answer with save_company_onboarding_answer. Each question's required flag indicates whether it must be answered for onboarding to proceed. Required questions (required is true) are mandatory — collect an answer for every one, and do NOT offer the user the option to skip them. Only optional questions (required is false) may be skipped — surface them and offer to capture an answer, but make clear the user is free to skip them. Setup is complete once all required questions are answered — optional questions may stay unanswered, so do NOT treat answered_questions == total_questions as the bar. Bank details are withheld from this list entirely and are collected by connect_bank_via_plaid, so every listed question can be answered while the bank account is still outstanding — the counts cannot tell you that, and next_step is what surfaces it: detail connect_bank where the Plaid tool is available, otherwise a hand-off to Gusto to add the account there. Always follow next_step rather than inferring from this list that setup is done. When summarising what is left for the user, say the bank account still needs connecting unless next_step shows it is done — otherwise the summary omits a required step and the user has no way to know it is coming. IMPORTANT - the question list is dynamic; saved answers can re-route the flow (e.g. a solo owner gets different questions than an employer), so this list is stale after any save_company_onboarding_answer call. Re-plan from that call's returned onboarding_status, or re-call this tool. QUESTION ORDER — next_step.next_question_group is the set of question keys to ASK the user RIGHT NOW. They are all safe to ask this turn and independent of each other, so the order among them does not matter — ask them in whatever order and grouping reads most naturally. Use judgment on how to ask: rather than dumping all of them in one message — or asking strictly one at a time — ask them in a few logically-related, digestible chunks (a couple to a handful at a time, grouping related topics, e.g. the workforce questions — headcount and the states employees work in — together). Often it is just one key. This governs the ASK, not the save: save_company_onboarding_answer takes ONE question_key per call and there is no multi-answer save, so after the user replies, make a SEPARATE save_company_onboarding_answer call for each key using the answers you just collected. Each save returns refreshed status that STILL lists the keys you have not saved yet (next_question_group shrinks as you save) — do NOT ask those again, you already have their answers; just keep saving them, one call per key. Do NOT ask a key that is not in next_question_group, or pull later keys in from remaining_question_keys, because a saved answer can re-route the flow and change what comes next. Once you have saved every answer you collected, re-read the refreshed status and ask the new next_question_group; repeat until none remain. next_question_group and remaining_question_keys can be identical (when every remaining question is safe to ask together); remaining_question_keys is the full ordered outstanding list for context and counts — drive from next_question_group. What comes after the required questions depends on the company's current experience, so follow the next_step cue rather than assuming a plan step always follows: answer_questions (answer the questions in next_question_group); continue_in_mcp with detail select_plan (the profile experience — call get_company_onboarding_package to present Gusto's recommended plan, then save tier_selection); continue_in_mcp with detail scorp_recommendation (a Solo owner may benefit from electing S-Corp tax status — call calculate_scorp_tax_savings to walk them through a personalized estimate, then acknowledge_scorp_recommendation once they have seen it, then re-call this tool); continue_in_mcp with detail ein_registration (the company needs a federal EIN before continuing — run the EIN filing tools: file_ein then pay_ein_filing then check_ein_status, then re-call this tool); continue_in_mcp with detail scorp_election (a Solo LLC wants S-corp tax treatment and has not filed Form 2553 yet — gather the election details and call file_scorp_election, then re-call this tool; never ask for SSNs); continue_in_mcp with detail reasonable_salary_calculator (a Solo S-corp owner can set their reasonable W-2 salary now — run the Reasonable Salary Calculator tools: calculate_reasonable_salary then accept_reasonable_salary, then re-call this tool); continue_in_mcp with detail connect_bank (the company's bank account is not connected — call connect_bank_via_plaid and relay its url; bank account and routing numbers cannot be collected here, so never ask for them instead); continue_in_mcp with detail set_password (this account cannot sign in yet, so no url is returned — follow the step's own message and never give out or invent a gusto.com link); continue_in_gusto (nothing left to drive here — relay the returned url; if it is absent, treat the step as set_password); or complete (onboarding is fully finished). A next_step of complete is authoritative: tell the user they're all set and do NOT present any questions — the questions list is empty and the counts are zero regardless of any past unanswered questions. It covers the company's setup, not website access: if the account signed up in chat, check manage_account get_status and mention any unset password alongside the good news. If you drove the onboarding with the user during this conversation, first present a concise recap of the onboarding answers gathered during this conversation (each question covered and its answer) so the user can confirm what was submitted, then tell them they're all set; build that recap from what you gathered in this conversation, not from this payload (which carries no answers), and do not restate sensitive values in full (e.g. SSN, full bank account numbers). If you did not drive onboarding here (e.g. the user just asked whether they are onboarded), simply confirm they're all set without inventing a recap. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
get_company_onboarding_status
Retrieves full details for a single pay rate record by UUID, including rate amount, payment frequency, FLSA status, and effective date. Use list_job_compensations first to find the compensation UUID. Call this for specific details about one pay rate entry. To change a pay rate, use update_compensation.
get_compensation
Returns batched contractor payment runs for the company. A payment group represents multiple contractor payments processed together on the same date. Omit contractor_payment_group_uuid to list groups with their UUIDs, check dates, and processing status, optionally within a start_date to end_date range. Pass contractor_payment_group_uuid to fetch a single group with each contractor's payment amount and details from that batch. Payments identify contractors by contractor_uuid only, so call get_contractors once without contractor_uuid to get their names.
get_contractor_payment_groups
Returns payments made to independent contractors. To list payments, pass start_date and end_date, which shows payment amounts, check dates, and contractor info for that range. Use this read-only tool to see contractor payment history, audit 1099 payments, or find how much was paid. Pass contractor_payment_uuid instead to fetch one existing payment in full, including amount, payment method, bonus breakdown, and reimbursements. Use pay_contractors to create a new domestic contractor payment. Note - only includes payments to domestic (US) contractors. International contractor payments are not included.
get_contractor_payments
Returns the company's independent contractors (1099 workers). Unlike employees (W-2), contractors are paid separately and file their own taxes. Omit contractor_uuid to list contractors with pagination and search, returning UUIDs, names, and basic info. Use this read-only tool to find contractor UUIDs or get a roster of non-employee workers; use pay_contractors to create a new domestic contractor payment. To look up several contractors at once, such as everyone in a payment group, list them in one call without contractor_uuid and match on UUID rather than fetching each one. The list includes inactive contractors, so check the is_active field for current status. Pass contractor_uuid to fetch one contractor's full profile, including name, email, business name (if applicable), payment method, and engagement dates. Note - this only includes domestic (US-based) contractors. International contractors are not included in results. If the company has international contractors, mention that totals reflect domestic contractors only.
get_contractors
Returns the company's departments with their UUIDs, titles, and the UUIDs of the employees and contractors assigned to each. Omit department_uuid to list every department, which is enough to see the org breakdown or department headcounts. Pass department_uuid to fetch a single department. Members are returned as UUIDs only, so use list_employees to resolve names. Note - department employee lists and headcounts only include domestic (US) employees. International employees are not reflected in these counts.
get_departments
Retrieves full profile for a single domestic (US-based) employee by UUID, including name, email, hire date, department, manager, job title, work location, current pay rate, time-off policy assignments, and time-off balances. Use list_employees first to find the employee UUID. Call this when you need detailed info about one specific person. International employee data is not available through this endpoint.
get_employee
Returns per-employee earning breakdowns (commissions, bonuses, tips, etc.) aggregated across all processed payrolls in a date range. Use this when the user asks about specific earning types attributed to individual employees, such as "How much has each employee been paid in commissions this year?" or "Who received bonuses last quarter?" Default date range is year-to-date. This tool provides per-employee attribution that list_payrolls cannot - list_payrolls only has payroll-wide totals. IMPORTANT - Never guess which employees received specific earning types from aggregate totals. Always use this tool for per-employee earning attribution. Note - only includes earnings for domestic (US) employees. International employee earnings are not included. For national small-business pay benchmarks rather than this company's own earnings, use get_smb_pay_metrics.
get_employee_earnings_summary
Returns an employee's residential addresses, which are used for tax withholding calculations and mailing. Pass employee_uuid to list every home address on file for that employee, including current and historical addresses with street, city, state, ZIP code, and effective dates. Pass home_address_uuid instead to fetch a single address record.
get_employee_home_addresses
Retrieves information about an employee being brought back to the company after a previous departure. Includes the new start date and any updated employment terms. Use this to check if someone is a returning worker and when they rejoined.
get_employee_rehire
Returns the work locations assigned to an employee. Work addresses determine work-state tax jurisdiction. Pass employee_uuid to list every work location assignment for that employee, including current and historical assignments with the location address and effective dates. Use this to see where someone works or has worked, especially for remote or multi-location workers. Pass work_address_uuid instead to fetch a single assignment.
get_employee_work_addresses
Retrieves full details for a single job position by UUID, including title, department, location, FLSA classification, and current pay rate. Use list_employee_jobs first to find the job UUID. Call this for detailed info about a specific role assignment.
get_job
Returns the physical office or work locations registered for the company. Locations are used for tax filing, work address assignments, and compliance. Omit location_uuid to list every location with its address, UUID, and whether it is active. Pass location_uuid to fetch one location in full, including phone number and filing addresses for tax purposes.
get_locations
Requires an existing company — if the account does not have one yet, call create_company first, otherwise this fails. Returns the current answer for a single onboarding question, identified by its question_key. Every one of the question's fields is returned — a null field value means that field has not been set. Use this to read the current state of a specific question before deciding whether to update it, or to verify a previous save took effect. WHEN TO USE: When you need the current value of one specific onboarding question. WHEN NOT TO USE: To discover available question_keys or check overall onboarding progress — use get_company_onboarding_status instead. DATA RETURNED: An answer hash containing every one of the question's fields; a null field value means that field has not been answered yet. An unknown question_key returns an error rather than an empty answer. PREREQUISITES: Call get_company_onboarding_status first to discover valid question_keys before calling this tool. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
get_onboarding_answer
Returns the company's configured pay schedules. Omit pay_schedule_uuid to list every schedule with its frequency (weekly, biweekly, monthly, etc.), name, and UUID. Pass pay_schedule_uuid to fetch one schedule in full, including anchor dates and next scheduled pay dates, which answers when the next payday is. Does not show which workers are on each schedule; use list_pay_schedule_assignments for that.
get_pay_schedules
Retrieves complete details for a single payroll by UUID, including worker earnings, taxes, deductions, and net pay. This tool is read-only; use update_payroll to modify payroll inputs (hours, memos, bonuses, PTO) or run_payroll to calculate and submit the payroll. Entries in employee_compensations may carry a benefits breakdown, with company contribution and employee deduction as separate amounts. Benefits require the employee_benefits:read permission and are not returned for every caller, so treat their absence as a permission or configuration difference rather than as the employee having no benefits. Payroll-wide benefit totals in totals are always returned. Benefit lines cover only the employees on the requested page, so they sum to totals only when the payroll fits on one page.
get_payroll
Checks the status of one or more previously triggered reports. On success, returns the CSV content inline (as csv_content, truncated with csv_truncated: true beyond 500 KB -- when truncated, do not compute totals or other aggregates from csv_content, since rows past the cut are missing). Call this after create_reports to check progress -- check at most 5 times, a few seconds apart, then tell the user the report is still generating rather than looping indefinitely; a date-range report can take up to an hour for a large company, so a handful of quick checks won't always be enough. csv_content is per-employee wage and tax data. Summarize or answer from it rather than pasting the raw CSV into the conversation. A report_request_uuid is only readable by the same token that created it -- a different admin's token, or the same admin's token used later without that context, gets a failed status with an error_reason saying so. Do not retry; the report exists, but that token cannot read it. A connection restricted from sensitive data can only read contractor payments summaries, custom reports whose columns pass the restriction check, and (for no-PII connections) cash requirements. Any other report fails with a restricted error. Do not retry. Pass report_request_uuids (from create_reports output) as a flat list -- each report's company is looked up automatically, so no company info is needed here. Returns {results: [...]}, one entry per report_request_uuid, in the same order. One report failing does not abort the others.
get_reports
Retrieves detailed time entries for a single timesheet by UUID, including daily hours worked, overtime, breaks, and notes. Third-party time tracking only - there is no native equivalent, and passing a native shift id fails with a transport-level "resource not found" whose text talks about credentials and configuration rather than the real cause. Check that list_time_records reported a third_party source first, and take the timesheet's top-level id from there. For native companies list_time_records already returns per-shift detail, so no follow-up call is needed. Call this for a line-item breakdown of someone's hours for a specific pay period.
get_time_sheet
Returns employees' current time-off balances - available (balance), accrued, used, and pending hours per policy - with each balance attributed to the worker (name) and policy uuid. Policy name and type are included only when the token also holds the time_off_policies:read scope; without it, policy labels come back blank (the policy uuid is still returned). Use this when an admin asks about PTO, sick, or vacation balances (e.g. "how much vacation does each employee have left?"). Optionally scope with employee_uuids or policy_uuids (comma-separated). Note - covers domestic (US) employees; balances reflect the company's configured time-off policies.
get_time_off_balances
Returns a company's time-off requests (PTO, sick, vacation, etc.). Omit time_off_request_uuid to list requests. With no filters that returns all of them. Filter by status (comma-separated - pending, approved, declined, consumed), start_date/end_date (YYYY-MM-DD, matched against the request's dates), and employee_uuids (comma-separated) to scope to specific workers. Pass time_off_request_uuid to fetch a single request. Each request includes the worker (name + uuid), status, policy (type + uuid), the per-day hours requested, and the initiator/approver. Employee and employer notes are omitted, since they are free text that may contain health information. Time off may be managed natively in Gusto or by a third-party integration; this returns the company's requests either way. Note - covers domestic (US) workers.
get_time_off_requests
Returns information about the current API access token including which permissions (scopes) are granted and which company resources can be accessed. Use this to check what data operations are available or troubleshoot access issues before attempting other API calls.
get_token_info
Retrieves the definitions of all custom fields configured for the company, including field names, data types, and selection options. Custom fields let companies track additional worker attributes beyond standard HR data. Use this to understand what custom data is available before querying individual worker field values.
list_custom_fields_schema
Lists all earning type categories configured for the company, such as regular pay, overtime, bonuses, commissions, tips, and custom earning types. Shows type name, category, and whether it's taxable. Use this to understand available pay types for payroll input.
list_earning_types
Retrieves all custom field values set for a specific employee. Custom fields are company-defined attributes like T-shirt size, emergency contact, certifications, or any other custom data. Use list_custom_fields_schema first to see available field definitions.
list_employee_custom_fields
Retrieves the complete work history timeline for an employee, including all positions held, role changes, and status transitions. Use this to answer questions about someone's tenure, past roles, or employment dates within the organization.
list_employee_employment_history
Lists all job positions held by an employee, including current and past roles. Each job record contains title, location, hire date, and rate information. Use this to see someone's role history or find job UUIDs needed for compensation lookups.
list_employee_jobs
Retrieves offboarding and separation records for an employee, including departure dates, reasons for leaving, and final pay information. Use this to find when someone left the company, their exit date, or details about their offboarding process. For national small-business hiring and separation trends rather than this company's own departures, use get_smb_jobs_report.
list_employee_terminations
Lists all employees for the company with pagination and filtering options. Returns basic profile data for each person. Filter by onboarding status, active/inactive status, or search by name. Use this to find employee UUIDs, get headcount, or answer questions about the workforce roster. Without filters, returns all employees including terminated; use terminated=false for active employees only. Note - this only includes domestic (US-based) employees. International employees are not included in results or headcount. If the company has international employees, mention that totals reflect domestic employees only.
list_employees
Lists the pay rate history for a job position, showing all salary or hourly rate changes over time. Each entry includes effective date, rate amount, and payment unit (hourly/salary). Use this to see pay history or track when raises were given. By default only the current compensation is returned. Set include to all_compensations to retrieve the full history. To change a pay rate, use update_compensation. For how this company's pay compares with US small businesses nationally, use get_smb_pay_metrics alongside this tool.
list_job_compensations
Lists all pay periods (date ranges when work is performed) for the company, with links to associated payroll runs. Shows start date, end date, check date, and payroll status. Use this to see upcoming pay periods or find which payroll covers a specific date range.
list_pay_periods
Shows which employees are assigned to which pay schedules. Returns mappings between worker UUIDs and schedule UUIDs. Assignment rules vary by company setup - some assign by department, others individually. Use this to find out when a specific person gets paid or which schedule they follow.
list_pay_schedule_assignments
Identifies issues preventing a specific payroll from being processed, such as missing bank accounts, incomplete tax setup, or unsigned documents. Each blocker includes a description and resolution steps. Use this to diagnose why payroll cannot run or to check readiness before processing.
list_payroll_blockers
Lists all payroll runs for the company with filtering options. When called with no arguments, returns all payrolls (processed and unprocessed, regular, off_cycle, and external) from the past 6 months (start_date defaults to 6 months ago, end_date defaults to today). You can filter results by providing processing_statuses, payroll_types, start_date, end_date, or include parameters. Date filters apply to pay period (work dates), not payment dates. Date range constraints are that the range cannot exceed 1 year, and end_date cannot be more than 3 months in the future. Returns payroll UUIDs, check dates, processing status (processed,unprocessed), and type (regular,off_cycle,external). Use include=totals to get payroll-wide aggregate amounts (gross pay, taxes, net pay, total commissions, total bonuses). These totals are NOT broken down per employee. For per-employee earning breakdowns (who received which commissions, bonuses, etc.), use get_employee_earnings_summary instead. IMPORTANT - Never guess or infer which employees received specific earning types from aggregate totals alone. Common use case is to find the next payroll to process by filtering for processing_statuses=unprocessed and selecting the payroll with check_date closest to today's date. Note - payroll data only covers domestic (US) employees. International employee payroll is managed separately and not included here. Payroll sub-state within `unprocessed`: each list item carries `processed` (boolean) and `calculated_at` (nullable timestamp), but the roster (`employee_compensations`) is NOT included in list responses. From this list alone, use `calculated_at` to distinguish sub-states within `processing_statuses=unprocessed`: - pre-prepare candidate: `calculated_at: null`. - calculated: `calculated_at` is a timestamp. When the user asks for "unprepared", "draft", or "not-yet-prepared" payrolls, filter by `processing_statuses=unprocessed` and pick items with `calculated_at: null`. Then call `get_payroll` on the chosen item to confirm the roster is unmaterialized (`employees: []`, `employee_compensations` empty or absent) before invoking `update_payroll` — that combined signal is what makes the pre-prepare materialize path safe.
list_payrolls
Requires an existing company — if the account does not have one yet, call create_company first, otherwise this fails. Lists time records for the company over a pay period. The response is discriminated by `source`: - `source: 'native'` returns `shifts` (clock-in/out events, breaks, durations) plus `workers`, everyone who tracks time at the company, for companies on Gusto's native time tracking. `workers` covers employees and contractors alike, and lists a worker even when they have no shifts in the requested period, so use it to find the `companyMemberUuid` for someone you want to record a first shift for. - `source: 'third_party'` returns `timesheets` for companies with an active third-party time tracking integration, each carrying `shiftStartedAt`, `shiftEndedAt` and `timezone` so you can tell which day it covers. The tool eagerly paginates the third-party feed internally, so callers receive every timesheet in one response. - `source: 'none'` returns neither array; the company has not completed native onboarding and has no active third-party integration. For companies that have both native onboarding and third-party time tracking active, only the third-party data is returned, mirroring what those customers see in product. Always check `source` before reading shape-specific fields. Every shift and timesheet also carries the worker's identity: `firstName`, `lastName`, `preferredName`, `workerType` (`employee`, `contractor`, or `international_contractor`), and the worker's public id - `employeeUuid` for employees or `contractorUuid` for contractors (the other is null). Use these to label records and to join back to employee/contractor tools. Identity fields are null when a member can't be resolved. On native time tracking, a contractor's `clockInTimestamp` and `clockOutTimestamp` are only readable when the time was entered or edited by an admin; for time the contractor clocked themselves both come back null, because Gusto withholds a contractor's raw clock times from everyone but the contractor. `date` and `durationInMinutes` are always populated, so report contractor hours from those rather than treating a null timestamp as a missing shift. Employee timestamps are unaffected.
list_time_records
Performs account-level actions on the signed-in Gusto account. Set `action` to choose what to do; only the actions listed below are supported, so do not invent others. action "get_status" — reports whether this account has set a Gusto password and can sign in on the website. Onboarding tools already withhold their gusto.com `url` until a password is set, so you need this only when the user says they set one, asks why they cannot sign in, or when a chat-signup account reaches next_step `complete` — that covers the company's setup, not website access, so mention any unset password alongside the good news. action "resend_password_setup_email" — re-sends the email that lets the user set a Gusto password and finish converting their signup into a full account. Use this only when the user says they did not get that email, deleted it, or the link expired. The email is sent automatically when signup setup completes, so there is no need to call this as a normal step. Sending is rate limited, so a repeat call inside a few minutes reports that the most recent email is still valid rather than sending another — relay that to the user instead of retrying. A successful response means the email was sent, NOT that the account is already upgraded: the user still has to open it and choose a password.
manage_account
Records admin-entered time for a worker over a pay period. Routes automatically to the company's native time tracking or their connected external time-tracking partner - the caller never chooses the destination. Always preview existing hours with list_time_records and get explicit admin approval before calling this tool. On success the response carries `status`, `source`, `id`, and `resulting_hours`, and sometimes `warning`. `resulting_hours` is only populated for third-party writes; it is always null on the native path, so confirm native hours by re-reading with list_time_records rather than from the write response. `id` is the value to pass back as `shift_id` when updating the same record, but it is null whenever Gusto can't tell which shift it just wrote. That covers a native contractor, whose clock times are withheld, on any day that ends up holding more than one of their shifts, and any worker whose recorded clock-in doesn't match the one Gusto echoes back. The write still succeeded; get the shift's id from list_time_records before updating it. A `warning` means the write landed but something the caller asked for did not - relay it to the admin instead of reporting a clean success. One case where re-reading is not proof: a contractor who has no Gusto account of their own comes back from list_time_records with null start and end times even though the hours recorded, because Gusto withholds a contractor's clock times from admins unless it can confirm who last edited them. Do not re-record hours that came back successful, and do not tell the admin the write failed - a second write books the hours twice.
record_time
Calculates and submits an existing unprocessed payroll for W-2 employees. Use pay_contractors for domestic contractor payments. CANNOT create new payrolls or off-cycle payrolls. To modify payroll inputs (hours, amounts, earnings, memos, PTO) before running, use update_payroll. If the user needs an off-cycle payroll (bonus, correction, termination), they must first create it in Gusto, then return here to run it. When multiple unprocessed payrolls exist, prefer the one with a check date closest to today.
run_payroll
SIGNUP/ONBOARDING PHASE tool. Requires an existing company — if the account does not have one yet, call create_company first, otherwise this fails. Saves a single onboarding answer for the company. A saved answer can RE-ROUTE the onboarding flow — e.g. answering who_to_pay as a solo owner changes which questions remain — so any previously fetched question list is stale after a save. A successful response includes `onboarding_status`: the refreshed post-save status in the same shape as get_company_onboarding_status. Always re-derive the remaining questions from it (or re-call get_company_onboarding_status) instead of continuing through an earlier list. The re-routing is yours to handle, not the user's to hear about: do not tell them the question set or its count changed, and just ask the next question. Report a count only if they ask for one. If the answer is invalid, the response `errors` list names the expected fields and allowed values — retry with corrections. Don't invent question_keys; use the get_company_onboarding_status tool to discover valid keys and which remain unanswered. For question_key `tier_selection` (plan selection), first call get_company_onboarding_package — its plans/addOns `key`s are the valid `plan` and `add_ons` values, and it includes Gusto's recommendation to present to the user. Present that recommendation and confirm the user's choice before saving tier_selection. For question_key `industry_selection`, first call search_business_info with type "industry" and the business's own words — its results carry the verified `naics_code` to save. Present those candidates and confirm which one the user picks before saving: the pick is theirs, not yours, so do not settle on the top-ranked result yourself, and a document or profile that names the business's industry is not a pick — it describes the business, it does not choose between codes. A code or classification the user names themselves is the exception: that already IS their pick, so save it without asking them to choose again. Never guess NAICS/SIC codes; only save a code returned by that tool. The industry_selection answer also carries `is_crb`, a cannabis-related-business flag that steers package eligibility (a cannabis business cannot be offered 401(k)), so it must be set, not left blank. Ask the user a standalone yes/no question — near-verbatim: "To make sure we show you the right package options, is your business in the cannabis industry?" — and include `is_crb` (true or false) in the same industry_selection answer you save. Ask it plainly on its own; do not fold it into the industry-description question, and never set `is_crb` true without the user's explicit yes — do not infer it from the industry, NAICS code, or business name. For question_key `tax_payer_type`, only "LLC" and "C-Corporation" can elect S-corp taxation. When the user picks one of those, ask a separate follow-up — whether the business is taxed as an S corp (an elective status that passes profits through to the owner's personal return, avoiding double taxation) — and include `taxable_as_scorp` with their answer; do NOT assume false. For any other classification you don't need to ask about or send `taxable_as_scorp`; the system sets it. Bank accounts ARE connected here, with connect_bank_via_plaid: give the user the url it returns and confirm the outcome with check_plaid_connection_status rather than assuming it worked. Never tell the user the bank step has to happen in the Gusto web app while that tool is available. What cannot happen here is typing the details into chat: `company_bank_account` and `plaid_bank_account` are rejected if sent and are not listed as questions, so never ask for an account number, routing number, or bank login, and never offer to enter them on the user's behalf — even if they volunteer them or insist. Only if connect_bank_via_plaid is unavailable, send them to Gusto instead. The response also includes `next_step`, a structured cue for what to do next — follow it: `answer_questions` means the key(s) in `next_question_group` are all safe to ask this turn — ask them in a few related, digestible chunks (not all at once, not strictly one at a time), then make a SEPARATE save call per key with the answers you collected — there is no multi-answer save. The status returned by each save still lists the not-yet-saved keys, so keep saving them rather than re-asking; do not skip ahead or ask keys outside that group (`remaining_question_keys` is the full outstanding list for context; drive from `next_question_group`); `continue_in_mcp` with detail `select_plan` means call get_company_onboarding_package and then save the `tier_selection` answer; `continue_in_mcp` with detail `connect_bank` means call connect_bank_via_plaid and relay its url — do not ask for bank numbers instead; `continue_in_mcp` with detail `set_password` means the account cannot sign in yet, so no `url` is returned — follow the step's own message and never give out or invent a gusto.com link; `continue_in_gusto` means relay the returned `url` to the user — if it is absent, treat the step as `set_password`; `complete` means onboarding is fully finished — before saying anything else, present a concise recap of the onboarding answers gathered during this conversation (each question covered and its answer) so the user can confirm what was submitted, then tell them they're all set and do NOT prompt for more answers. Build the recap from what you gathered in this conversation; onboarding_status carries no questions at this point. Do not restate sensitive values in full (e.g. SSN, full bank account numbers) — refer to them without echoing the digits. You may still offer any remaining non-required questions before a `continue_in_*` step, but they don't block progressing. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
save_company_onboarding_answer
Resolves a free-text description into verified, codified business-information candidates the user can choose from. Set `type` to pick what you're resolving; `query` is the user's free-text description in their own words. type "industry" — resolve what the business does into NAICS industry candidates, each with a verified 6-digit naics_code, name, and description. Use this whenever you need to set the industry_selection answer: pass the business's own words (e.g. "we run an apple orchard"), then save the naics_code the user picks with save_company_onboarding_answer. Candidates come back ranked by relevance, but ranking is a hint, not a decision — list them with their names and descriptions, ask which one fits, and wait for the answer before saving. Do not pick the top result on the user's behalf, and do not treat a document or profile that names the industry as the pick: near-identical candidates differ in how the business is treated downstream, so only the user can say which describes them. The exception is the user naming a code or classification themselves — that IS their pick, already made: check it appears in the results, then save it straight away rather than listing the candidates or asking them to choose again. Never guess NAICS codes; only save codes returned here. type "occupation" — resolve a job/role description into Bureau of Labor Statistics (BLS) occupation candidates, each with a code, name, and description (e.g. the code a reasonable- salary estimate needs). Pass the user's role in their words (e.g. "software developer" or "restaurant line cook"), present the options, and use the chosen candidate's code. Never guess BLS codes; only use codes returned here. For either type, if the list comes back empty, ask the user for a clearer description and search again. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
search_business_info
Resolves a description of the work someone does into that state's workers' comp risk-class candidates, each with a verified code and description. Requires `state` (WA or WY — only those two run their own state fund, so only they use class codes). Use this to get the state_managed_wc_class_code that manage_company_members needs to finalize a covered employee there: search the work the employee does (e.g. "roofing", "office administration"), present the candidates, and pass the code the user picks. Never guess a class code — it is validated against the state's list and a wrong one is rejected. Query with the WORK AS A NOUN, never a job title and never what the person does. These lists name trades, so "software" works where "work with computers" and "write code" do not, "plumbing" where "plumber" and "fixing pipes" may not, and "barber shop" where "hair stylist" does not. Verb and activity phrasing is the most common reason this search comes back wrong, because words like "work" appear in dozens of unrelated trades. If the user describes an activity, name the industry it belongs to and search that. If nothing comes back, rephrase in the state's industry terms and search again; two or three attempts is reasonable. If the user gives you a code themselves, that is their choice — pass it straight to manage_company_members as-is and do not run it through this search to second-guess it. Use this search only to resolve a code the user does not have. If a second wording also finds nothing in WA, call again with list_categories: true instead of guessing further. That returns the headings WA files its codes under — the list may simply not use your word for the work ("hair stylist" appears nowhere; the heading is "Beauty parlors"). Pick the heading that best covers the work, search again using it as the query, and present the codes it returns. WY has no such headings, so there rely on the search and on company_industry_candidates. If you still cannot find a code, stop and say so. Do not guess one, and do not set state_managed_wc_covered to false to get past the error — that tells Gusto the employee is not covered by the state fund, which is a false compliance answer and worse than leaving the work unfinished. Leaving the worker unfinalized is the correct outcome here: say you could not identify the class code and ask the user to set it in Gusto, where the picker lists the codes their company has configured. The code describes THE WORK THIS PERSON DOES, not what the business does. Two people at the same company routinely need different codes, and picking the company's trade for someone who doesn't do it overcharges the employer. In WY, office and sales staff have their own codes regardless of the industry — 000010 Clerical Office Occupations, 000020 Outside Sales, 000030 Inside Sales, 000040 Temporary Help - Office, 000050 Temporary Help - Other — so a bookkeeper at a roofing company is 000010, not a roofing code. Search for the person's actual work first; only reach for the company's trade when they really do that trade. For WY the results may also include company_industry_candidates: the codes matching the company's own registered industry. Those are the right answer only for someone doing that trade, and there is often more than one (roofing splits into all-types, residential and nonresidential), so present them and let the user choose rather than assuming the first. If the list comes back empty, ask the user for a clearer description and search again. VOICE: helpful, not technical. Don't show the user this tool's internal names — question keys, field names, tool names, status values — describe what they mean instead, and don't volunteer counts unless asked. Where a value has a proper name, use it: "the Plus plan", not "plus". Codes the user picks from a list, like NAICS or workers' comp class codes, are content: show those verbatim.
search_workers_comp_class
Gusto ChatGPT Plugin FAQ
How the directory, categories and Discoverability Score work.
Read the methodologyHow do I improve Gusto's ChatGPT Plugin discoverability?
The levers are the listing surface agents actually read: names, descriptions, keywords, tool metadata, and registry health. Which lever matters depends on where discovery breaks, which is what continuous measurement shows.
What are Gusto alternatives on ChatGPT?
As of 2026-10-25, Gusto competes with Asanify, Deel, Gusto, Justworks, Kronjop, Leo HR, Orgvue US, PayCanvas and 3 more in ChatGPT Payroll, EOR & HR Operations, ranked by public Discoverability Score.
Where is this profile measured?
This profile uses the geography attached to the latest public registry snapshot: US. Locale tags are intentionally omitted.