Review pay changes before you approve your Gusto payroll

One screen compares this period's gross pay to last period, flags anyone moving more than 5 percent, and lets you approve and submit the run from there.

App
GustoGoogle SheetsSlack BotFinanceOperationsAI ReportsNotifications & Alerts
PromptCreate

Build me a pre-payroll review desk my finance lead opens before every payroll run. It is a single interactive app over Gusto, Google Sheets, and Slack Bot. Nothing in it is ever calculated, submitted, logged, or posted unless a person clicks a button: no schedule, no auto-run on page load, no chaining one action into the next.

The main view is one table covering the current draft payroll. Use Gusto List Payrolls to find the open unprocessed payroll for the company's regular pay schedule, then Gusto Get Payroll to pull its full detail including per-employee compensations, hours, and totals. Use List Payrolls again to find the previous comparable pay period, meaning the most recent processed payroll on the same pay schedule with off-cycle runs excluded, and Get Payroll on that one too. Each row shows the employee name, this period's gross pay, that same person's gross pay from the prior period, the dollar change, and the percent change. Match employees between the two runs by employee UUID, never by name.

Any row moving more than the variance threshold in either direction gets an outlier flag and sorts to the top. The threshold is a stored app setting that defaults to 5 percent and is editable on a settings screen; do not hardcode 5 anywhere in handler logic. Add a companion setting for a minimum dollar change so tiny paychecks do not flood the list. Alongside the variance rows, render two distinct groups with their own headers and their own counts: new hires who appear in this payroll with no prior period at all, and anyone who dropped to zero hours or zero gross this period after being paid last period. Both groups always show regardless of the percent threshold, since a missing paycheck never produces a percentage worth sorting on.

Gusto returns money and hours as decimal strings such as '1234.56' and '8.0'. Do every comparison and every piece of arithmetic with exact decimal math on those strings rather than parsing to floats, and render values back as strings so nothing drifts by a cent. Percent change on a prior gross of zero is not a number, it is the new hire case, so route it to that group instead of dividing.

When a reviewer expands a row, fetch that employee's rate history on demand with Gusto Get Employee Jobs and Gusto List Job Compensations, and show job title, effective dates, rate, and payment unit so the reviewer can see whether a rate changed mid period. Only fetch this when the row is actually expanded, not for the whole table up front.

Every flagged row gets an Explain this swing button that kicks off a background agent embedded in the app. The agent receives that one employee plus both payrolls, inspects their jobs with Get Employee Jobs, their compensation history with List Job Compensations, and their recent payrolls with List Payrolls and Get Payroll, and writes a short plain English explanation back onto the row. The reviewer should read something like 'switched to a new hourly rate mid period, 18 hours at the old rate and 22 at the new one' or 'logged 12 fewer hours than last period' instead of just seeing a red number. Show the explanation state on the row (not started, running, done, failed), persist the explanation so it survives a refresh, and let the reviewer rerun it.

Each flagged row can be cleared or acknowledged by the reviewer with an optional note, and the app records who did it and when. Keep a live count of open flags at the top of the screen.

The Calculate Payroll button stays disabled until every flag is cleared or acknowledged. On click it calls Gusto Calculate Payroll, then polls Gusto Get Payroll and reads processing_request.status through calculating to calculate_success, plus the top level calculated_at field, rather than assuming the call succeeded. Show a calculating state while polling, surface processing_failed with Gusto's own error message, and refresh the on-screen totals and taxes when it lands. The reviewer then clicks Submit Payroll, which calls Gusto Submit Payroll and polls the same way through submitting to submit_success. Both buttons need an explicit click and a confirmation step, and calculate never chains into submit.

Once a run reaches submit_success, append exactly one signed off audit row per run to Google Sheets with Append Values: pay period start and end, payroll id, employee count, total gross, total employer taxes, total net, the variance threshold in effect, how many rows were flagged, how many were cleared versus acknowledged, the reviewer name, and the timestamp. Then post the final totals to the finance channel with Slack Bot Send a Message, including a short list of the flagged employees with their explanations. Write the audit row and the Slack post exactly once per submitted run and guard against duplicates if the reviewer reloads the page.

A settings screen holds the variance threshold percent, the minimum dollar change, the Google Sheets spreadsheet and tab for the audit log, and the Slack channel for the summary.

What does this prompt do?

  • Loads your current draft payroll and lists every employee with this period's gross pay next to the same person's gross pay last period, plus the dollar and percent change
  • Flags anyone whose pay moved more than your threshold, and gives new hires with no prior period and anyone who dropped to zero hours their own separate groups
  • Puts an Explain this swing button on every flagged row, which sends an assistant to read that person's job and pay history and write a plain English reason back onto the row
  • Once every flag is cleared or acknowledged, lets the reviewer calculate the run, check refreshed totals and taxes, and submit payroll without leaving the screen
  • Logs one signed off row per run to a Google Sheets audit sheet and posts the final totals to your finance channel in Slack

What do I need to use this?

  • A Gusto account with payroll admin access, including permission to run payroll
  • At least one completed pay period in Gusto so there is a prior period to compare against
  • A Google account and a spreadsheet to hold the sign off log
  • A Slack workspace and a finance channel where the final totals should be posted

How can I customize it?

  • Change the variance threshold from the default 5 percent, and set a minimum dollar change so small paychecks do not clutter the list
  • Point the audit log at a different spreadsheet or tab, and send the summary to a different Slack channel
  • Decide which groups a reviewer has to acknowledge before the approve button unlocks, and what the assistant should mention in its explanations

FAQs

Does this run payroll automatically?
No. Nothing is calculated, submitted, logged, or posted unless a person clicks the button. The app is a review desk that waits for you, and calculating and submitting are two separate clicks with a confirmation on each.
Can I change the 5 percent threshold?
Yes. The threshold lives on a settings screen, not buried in the app, so you can tighten it to 3 percent or loosen it to 10 at any time. You can also set a minimum dollar change so a few dollars of variance on a small paycheck does not get flagged.
What happens with someone who just joined and has no prior pay period?
New hires get their own group instead of showing up as an infinite percent increase. Anyone who dropped to zero hours after being paid last period gets a separate group too, since a missing paycheck is easy to overlook when you are scanning percentages.
What does the Explain this swing button actually do?
It sends a background assistant to look at that one employee's job, pay rate history, and recent payrolls, then write a short explanation onto the row. Instead of a red number you read something like switched to a new rate mid period, so you can decide in seconds whether it is expected.
Do I need to be a payroll admin in Gusto?
Yes. Reading the draft run and prior runs needs payroll access, and calculating and submitting need permission to run payroll. If your account can only view reports, the review table still works but the approve and submit buttons will not.
Where does the audit trail go?
After a run is submitted the app appends one row per payroll to a Google Sheets tab you choose, covering the pay period, totals, the threshold in effect, how many rows were flagged and how they were resolved, and who signed off. The same summary gets posted to your finance channel in Slack.

Related templates

Review desk for portal forms your team still fills in by hand

Stage a batch of filings overnight, then approve each completed form from a screenshot before anything is ever submitted.

Kernel
Google Sheets
Slack Bot
App
Client-by-client cold email pipeline review for agencies

Pick a client and a date range to see sent, replies, meetings booked and the real deal value your cold email produced, campaign by campaign.

Instantly
HubSpot
Slack Bot
App
Audit what Intercom's Fin AI actually resolved before you pay

Review every conversation Fin closed as resolved, judge which ones actually stuck, and see what the gap is worth against your bill.

Intercom
Google Sheets
Slack Bot
App
One triage console for every Jira service desk queue

Merge your IT, HR and Facilities queues into one list ranked by SLA time left, then reply, change status and escalate without ever opening Jira.

Jira Service Management
Jira
Slack Bot
App
Returns and warranty claim desk that follows your policy

Work every return, damage and warranty claim in one queue, with the order, the delivery date and a policy-backed recommendation already on screen.

Kustomer
Shopify
Google Sheets
App
Run your Webflow site translations from one review desk

See every page's translation status at a glance, edit translations side by side with the English, and publish only what your team has actually approved.

Webflow
JigsawStack
Slack Bot
+1
App

Stop hunting for payroll surprises in a spreadsheet.

Open one review screen, clear every flag with a reason attached, and approve the run with a record of who signed off.