Testing Tax Statement Notifications in Sandbox
Generate draft W-2s and 1099s in sandbox and simulate publishing them, so you can test your tax statement Notification handling end to end.
When an employer's W-2s or 1099s finish publishing, Check sends one Notification per employer so you know the statements are ready to fetch. In production, this happens when Check publishes statements. In sandbox, you can generate draft statements and simulate publishing them on demand, so you can test your Notification handling and your own employer and worker communications end to end.
Refresh filings and the simulate endpoints on this page are only available in sandbox. In production, they return a 404.
For the topics, when each one fires, and how to fetch the published statements and PDFs, see Tax Statement Notifications. Check sends no email for these topics, so nothing on this page sends a Communication.
The steps on this page produce original statements, so they trigger the employee_original_tax_statements_published and contractor_original_tax_statements_published topics.
The 1099 steps use the Contractor Tax Statements API, which is in limited preview and is not yet generally available. The contractor endpoints on this page return a 404 unless contractor tax statements are enabled for your account.
Prerequisites
Before testing, make sure you have:
- A webhook endpoint subscribed to the
notificationtopic, or to all topics. See Webhook event types. - Tax statement Notifications enabled for your account. If you are not sure, reach out to your Check partner support team.
- A sandbox company with employees, and contractors if you are testing 1099s, that you have fully onboarded with Start implementation. The company's
implementation.statusshowscompletedonce this is done. - At least one approved payroll for that company in the current tax season's year. The company must be in good standing.
The tax season's year is the prior calendar year from January through April, and the current calendar year from May onward. For example, in February 2027 the tax season's year is 2026.
Step 1: Generate draft tax statements
POST to Refresh filings at /companies/:company_id/refresh_filings. Omit payroll_ids and employee_ids to generate data for the entire company, including W-2s and 1099s for the tax season's year.
This starts an asynchronous job that takes a few minutes, depending on how much payroll data the company has. When it finishes, you can list the draft statements:
GET /employee_tax_statements?company=com_123&publication_status=draft
GET /contractor_tax_statements?company=com_123&publication_status=draftIf you change payroll data and want updated statements, call Refresh filings again.
Step 2: Simulate a publish
You can simulate a publish in two ways. The company-level endpoints act on the tax season's year only. The single-statement endpoints act on the statement you name.
Option A: Send only the Notification
Use this to test your Notification handling and your own communications as many times as you need, without changing any statements. Pass notify_only: true to any of the publish endpoints listed in Option B:
{
"notify_only": true
}Check sends the Notification as if the draft statements had just been published. The statements stay in draft, so you can repeat the call.
You will receive a created webhook with the topic notification for each Notification sent.
Option B: Publish the statements
Omit notify_only, or pass false, to move statements from draft to published. Use this to test the full flow, including fetching and displaying published statements and their PDFs. No physical mail is sent.
Publish every draft statement for a company
- W-2s: Simulate publishing a company's employee tax statements at
POST /companies/:company_id/simulate/publish_employee_tax_statements - 1099s: Simulate publishing a company's contractor tax statements at
POST /companies/:company_id/simulate/publish_contractor_tax_statements
Publish a single statement
- W-2: Simulate publishing an employee tax statement at
POST /employee_tax_statements/:statement_id/simulate/publish - 1099: Simulate publishing a contractor tax statement at
POST /contractor_tax_statements/:statement_id/simulate/publish
A simulated publish updates each statement the same way a production publish does. In the Employee Tax Statements and Contractor Tax Statements APIs, publication_status changes to published, published_at is set, and document points to the rendered PDF.
Publishing runs asynchronously. The company-level endpoints return an empty 200 response. The single-statement endpoints return the statement as it was when you made the request, before publishing completes.
Once all of the employer's statements in the run are published, you will receive a created webhook with the topic notification.
Step 3: Handle the Notification
The Notification identifies the employer in company and the kind of statements in topic. For these topics, recipient_type is company and email_communication is null.
Example webhook payload
{
"event": "created",
"data": {
"id": "ntf_MrFrw0F82NSJjyw10Erk",
"topic": "employee_original_tax_statements_published",
"company": "com_zH8Gq33iBkFj5o0GKjTw",
"recipient_type": "company",
"recipient": "com_zH8Gq33iBkFj5o0GKjTw",
"email_communication": null,
"created_at": "2026-11-09T14:22:07Z"
}
}After an Option B publish, fetch the published statements and PDFs as described in Tax Statement Notifications. After an Option A call, the statements are still drafts.
Step 4: Reset and test again
To return published statements to draft so you can publish them again:
- All of a company's W-2s: Simulate unpublishing a company's employee tax statements at
POST /companies/:company_id/simulate/unpublish_employee_tax_statements - All of a company's 1099s: Simulate unpublishing a company's contractor tax statements at
POST /companies/:company_id/simulate/unpublish_contractor_tax_statements - A single W-2: Simulate unpublishing an employee tax statement at
POST /employee_tax_statements/:statement_id/simulate/unpublish - A single 1099: Simulate unpublishing a contractor tax statement at
POST /contractor_tax_statements/:statement_id/simulate/unpublish
Unpublishing does not send a Notification.
Troubleshooting
The publish endpoints return an error, such as tax_statement_not_publishable, when:
- Without
notify_only, the company is not in good standing. - A draft statement has no data yet. Call Refresh filings and wait for it to finish.
- On the company-level endpoints, there are no draft statements left to publish for the tax season's year. Reset with the unpublish endpoints, or call Refresh filings.
- On the single-statement endpoints, the statement is not in
draft. - For 1099s, contractor tax statement publishing is not enabled for your account, or the company's filings are blocked or not yet publishable.
- With
notify_only, there are no draft statements to send a Notification about, or tax statement Notifications are not enabled for your account.
The company-level unpublish endpoints return a tax_statement_not_published error when there are no published statements to reset for the tax season's year.
Updated about 7 hours ago

