# 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.

- Workflow type: app
- Services: Gusto, Google Sheets, Slack Bot
- Categories: Finance, Operations
- Published: 2026-08-24

## What it does

- 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 you'll need

- 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

## Prompt

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.

## How to customize

- 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

## FAQ

### 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.

Use this prompt in General Input: https://www.generalinput.com/prompts/review-pay-changes-before-you-approve-your-gusto-payroll