How to reset a QuickBooks Online sandbox and refill it in minutes
A QuickBooks Online (QBO) sandbox drifts. After a few weeks of testing it holds half-finished invoices from a bug you fixed, customers a colleague added for a demo, and a chart of accounts nobody remembers changing. Tests that passed on a clean company start failing for reasons that have nothing to do with your code. This is the short, practical version of getting back to a known state and refilling the sandbox with realistic data, in minutes rather than an afternoon. (If you are new to sandboxes, start with the sandbox guide.)
You need Node.js 22.13 or newer, a free Intuit developer account with a sandbox company, and an app with Development keys whose redirect URIs include http://localhost:8085/callback.
Step 1: pick how clean you need it
There are three ways to clear a sandbox, from gentlest to most drastic. Most days the first one is enough.
A. Purge by tag (keeps everything you made by hand)
If the clutter came from EasyTestData, clear it by tag. Every record it creates carries the EZTD tag, so it can remove its own data and nothing else:
npx easytestdata purge --mode generated
Purge deletes the transactions it added, makes its customers, vendors, employees and items inactive (accounts stay), and never touches records you made by hand (details). If you loaded several datasets with different --tag values, pass --tag to clear one at a time.
B. Delete every transaction (keeps the chart of accounts)
If the leftovers came from other tools or manual entry, delete all transactions in the company and make every customer, vendor, employee and item inactive, keeping the chart of accounts:
npx easytestdata purge --mode all
The CLI asks for confirmation because this is not limited to tagged records. It still only ever runs against a sandbox: the client refuses any API host other than the sandbox one, and Intuit's Development keys cannot authorize a production company.
C. Reset the sandbox in the developer portal (deletes everything)
For a truly blank company, use Intuit's own reset. Open developer.intuit.com, go to the Dashboard, open the Sandbox section and choose Reset on the sandbox. It deletes all data in the company, including accounts and lists. As of September 2026, per Intuit's sandbox docs, the sample data is not restored once it has been deleted; create a new sandbox if you want the sample company back. Intuit caps how many sandboxes an account can have, so delete unused ones first if the add button is disabled.
Step 2: reconnect if you reset
Options A and B keep your OAuth connection working. After a portal reset (option C), run the authorization again so the CLI holds fresh tokens for the company:
npx easytestdata auth
Your browser opens, you pick the sandbox, and the connection is saved to .easytestdata.json in the current directory. That file contains a refresh token, so keep it out of version control. If you use the web app (EasyTestData Cloud or npx easytestdata ui) instead of the CLI, disconnect and reconnect the sandbox from the web app.
Step 3: refill it with one command
Now load a year of books. Pin the seed and the start date so the same command gives you the same company every time, on any machine:
npx easytestdata load --scenario healthy-small --seed 42 --start-date 2025-09-01
healthy-small is a good default: a small business with steady margins, roughly 750 transactions for 12 months, which loads quickly. The default template is professional services; add --template restaurant, construction, saas or one of the other industries to change what the business sells and spends on. The playground shows the exact counts for any combination before you load it, and the CLI page lists every flag.
Two shortcuts save a step:
--dry-runprints the summary without touching QBO, so you can check the counts first.--clear-firstpurges the previous EasyTestData data (same tag) and loads the new set in one go, which turns steps 1A and 3 into a single command:
npx easytestdata load --scenario healthy-small --seed 42 --start-date 2025-09-01 --clear-first
Loading takes a few minutes for a scenario this size because the CLI stays under QBO's API rate limit; larger scenarios such as rapid-growth take longer. If you leave out --seed, a random one is drawn and printed with the summary, so a run you liked can always be repeated.
Step 4: check and repeat
Log in at app.sandbox.qbo.intuit.com and open the customer list or the Profit and Loss report for September 2025 to August 2026. When you want a different company, purge and load again with another scenario:
npx easytestdata purge --mode generated
npx easytestdata load --template construction --scenario cash-crisis --seed 7 --start-date 2025-09-01
Different tags let two datasets coexist, for example a stable demo company under one tag and disposable test data under another: load with --tag DEMO once, then keep purging and reloading the EZTD set without touching it.
Doing this in CI
The same loop works unattended. A few things make it reliable:
- Pass the connection as secrets. Authorize once on your machine, then give the runner
QBO_CLIENT_ID,QBO_CLIENT_SECRET,QBO_REFRESH_TOKENandQBO_REALM_IDfrom.easytestdata.json. Treat them like passwords. - Pin the CLI version, the seed and the start date so every run loads the same books:
npx --yes easytestdata@0.1.0 load --scenario healthy-small --seed 42 --start-date 2025-09-01 --clear-first. - Purge in a step that always runs, even when tests fail, and pass
-y: the CLI refuses to purge without confirmation in a non-interactive shell. - Expect the refresh token to rotate. Intuit issues a new refresh token when the old one is used; the CLI saves it to
.easytestdata.json, and the GitHub Actions example shows how to write it back to your secret. - Use one sandbox per pipeline. Two jobs loading into the same company at the same time will confuse each other; Intuit lets you have more than one sandbox, so give each pipeline its own.
The CI/CD page has a complete GitHub Actions workflow.
Try the loop without a sandbox
If you want to see the data before you connect anything, open the playground. It generates the same books in your browser and prints the exact load command for your sandbox. Questions about what purge removes or why the P&L differs from the target are answered in the FAQ.