Sandbox (test mode)
On this page
A test API key runs every endpoint against the sandbox. You get the same request and response shapes as live, but the result is decided by the address you send, nothing is checked for real, and no credits are used. Test keys work with a balance of zero.
Use the sandbox to build and test your whole integration: every result category, processing and polling, rate-limit and server errors, bulk jobs with progress, downloads and webhooks.
Test keys
When you create an API key, choose Live or Test. The mode is fixed for the life of the key, and the full key starts with it:
| Mode | Key starts with | What it does |
|---|---|---|
| Live | sc_live_ | Real verification. Uses credits. |
| Test | sc_test_ | Sandbox results. No credits, ever. |
The dashboard shows the prefix in the key hint (sc_test_…a1b2) and a Test chip next to test keys. Keys created before modes existed have no prefix; they are live keys and keep working unchanged.
Use a test key exactly like a live one:
curl -G "https://simplecold.com/api/v1/api-validation/single" \
--data-urlencode "[email protected]" \
-H "Authorization: Bearer sc_test_YOUR_TEST_KEY"How addresses are matched
Sandbox addresses
| Address | status | category | failType | Timing |
|---|---|---|---|---|
deliverable@… (or any unlisted address) | mailbox_found | deliverable | none | Instant |
undeliverable@…, invalid@…, nosuchuser@… | mailbox_not_found | undeliverable | permanent | Instant |
disabled@… | mailbox_disabled | undeliverable | permanent | Instant |
nomx@… | no_mail_server | undeliverable | permanent | Instant |
catchall@…, acceptall@… | accept_all | risky | none | Instant |
role@…, info@…, sales@…, support@… | role_address | risky | none | Instant |
disposable@… | disposable | risky | none | Instant |
antispam@… | blocked_by_server | risky | temporary | Instant |
unverifiable@… | no_response | risky | temporary | Instant |
…@gmial.com, …@yaho.com, …@hotmial.com | possible_typo + suggestion | undeliverable | permanent | Instant |
slow@… | processing, then mailbox_found | pending, then deliverable | none | Final result about 20 s later |
slow-undeliverable@… | processing, then mailbox_not_found | pending, then undeliverable | permanent | Final result about 20 s later |
slow-risky@… | processing, then accept_all | pending, then risky | none | Final result about 20 s later |
error-429@… | – | – | – | Standard 429 RATE_LIMITED response |
error-500@… | – | – | – | Standard 500 response |
error-timeout@… | processing, then mailbox_found | pending, then deliverable | none | Answers after about 15 s; final result about 20 s later |
statusMessage is the same plain sentence a live result with that status has. Statuses and categories explains each one.
Every sandbox response has "sandbox": true in each result (and in bulk job and status responses). Live responses never have the field, so you can assert on it in tests.
Example responses
{
"code": "SUCCESS",
"message": "Successfully performed operation.",
"payload": {
"email": "[email protected]",
"domain": "example.com",
"status": "accept_all",
"statusMessage": "The domain accepts mail for any address, so this mailbox can't be confirmed.",
"category": "risky",
"failType": "none",
"mxLocation": "IE",
"siteLocation": "US",
"siteLanguage": "EN",
"suggestion": null,
"sandbox": true
},
"requestId": "5f3a..."
}[
{
"email": "[email protected]",
"domain": "example.com",
"status": "mailbox_not_found",
"statusMessage": "This mailbox does not exist.",
"category": "undeliverable",
"failType": "permanent",
"mxLocation": "IE",
"siteLocation": "US",
"siteLanguage": "EN",
"suggestion": null,
"sandbox": true
},
{
"email": "[email protected]",
"domain": "gmial.com",
"status": "possible_typo",
"statusMessage": "Possible typo. Did you mean [email protected]?",
"category": "undeliverable",
"failType": "permanent",
"mxLocation": null,
"siteLocation": null,
"siteLanguage": null,
"suggestion": "[email protected]",
"sandbox": true
},
{
"email": "[email protected]",
"domain": "example.com",
"status": "processing",
"statusMessage": "Still checking this mailbox. Ask again in about a minute; you will not be charged again.",
"category": "pending",
"failType": "none",
"mxLocation": null,
"siteLocation": null,
"siteLanguage": null,
"suggestion": null,
"sandbox": true
}
]Polling with slow@
slow@, slow-undeliverable@, slow-risky@ and error-timeout@ answer processing first, the way a slow mail server does. Collect the final result from /single/result, exactly as you would in live mode:
curl -G "https://simplecold.com/api/v1/api-validation/single/result" \
--data-urlencode "[email protected]" \
-H "Authorization: Bearer sc_test_YOUR_TEST_KEY"Simulated errors
These let you test error handling without hitting a real limit or waiting for an outage. They apply to single and batch requests; in a batch, one such address makes the whole request answer with the error, as a real one would.
Bulk in the sandbox
Upload a CSV with a test key and you get a real job:
{
"id": "c3d0e8a2-7f41-4f0b-9a55-1d2f7e4c9b10",
"name": "sandbox-leads",
"totalEmails": 120,
"totalValidEmails": 0,
"totalCreditsUsed": 0,
"status": "IN PROGRESS",
"sandbox": true
}{
"status": "IN PROGRESS",
"sandbox": true,
"totalProcessed": 70,
"progressPercent": 58.3,
"etaSeconds": 14,
"lastUpdatedAt": "2026-10-27T10:00:20.000Z",
"nextUpdateAt": "2026-10-27T10:00:25.000Z",
"queuedChunks": 1
}Webhooks
Sandbox activity sends the same events to your organisation's webhook endpoints: result.ready for slow… and error-timeout addresses, bulk.progress while a sandbox job runs, and bulk.finished when it ends (with creditsUsed: 0). The only difference is the envelope's livemode field:
{
"id": "evt_9b1f0c2d3e4a5b6c7d8e9f00",
"type": "bulk.finished",
"created": 1793001234,
"orgId": "6a1c4f0e-2a4b-4b6e-9c1d-0e5f4a3b2c1d",
"livemode": false,
"data": { "jobId": "c3d0e8a2-7f41-4f0b-9a55-1d2f7e4c9b10", "status": "completed", "creditsUsed": 0 }
}Live events have "livemode": true. Check it in your handler so test traffic never touches production data. In the dashboard's delivery log, test deliveries carry a test chip.
Limits
The sandbox has its own budgets, separate from your live ones: sandbox traffic never uses up live limits, and live traffic never uses up the sandbox's.
| Endpoint (test key) | Per test key | Per organisation |
|---|---|---|
single and single/result (shared) | 100 per minute | 300 per minute |
batch | 10 per minute | 30 per minute |
bulk upload | 5 per hour | 15 per hour |
bulk/:id/status | 120 per minute | 360 per minute |
bulk/:id/download-result | 30 per minute | 90 per minute |
The batch size limit (50 addresses) and the CSV format rules are the same as live. You can have up to 5 test keys, in addition to 5 live keys.