Sandbox SANDBOX
A deterministic test environment for the TradesAPI verify, batch, and search endpoints. Wire up CI in minutes — zero credit cost, no rate-limit pressure on production scrapers, and safe to share with security review.
/verify, /batch, /search) with the same authentication header. The license number you send routes to a deterministic fixture response — the request never reaches a state portal. Sandbox keys cannot reach production data: the routing decision happens at auth time based on the key's scope.
Get a sandbox key
Sign in to your dashboard and click Create sandbox key. You'll get one chance to copy the raw key — treat it like any other credential. You can rotate it anytime.
Open dashboard →Sentinel license numbers
Sandbox responses are keyed by the license-number prefix. The state and trade you send are echoed back verbatim — they don't change the response shape. This is what makes sandbox responses safe to assert against in CI.
| Prefix | Response shape |
|---|---|
SANDBOX-VALID-{any} | Active license, expiration ~1 year out, no disciplinary actions. |
SANDBOX-EXPIRED-{any} | valid: false, status: "Expired", expiration in the past. |
SANDBOX-SUSPENDED-{any} | valid: false, status: "Suspended". |
SANDBOX-DISCIPLINARY-{any} | valid: true with two sample disciplinary entries on the result. |
SANDBOX-NOTFOUND-{any} | valid: false, mimics "license not in this state's database". |
| Anything else | valid: false with status: "Sandbox license number not recognized" — the educational error. |
Every sandbox response includes "sandbox": true at the top level so your code can distinguish it from a production response. The X-Sandbox: true response header carries the same signal.
Examples
Verify an active license
curl 'https://www.tradesapi.com/verify?state=TX&license=SANDBOX-VALID-12345&trade=hvac' \
-H 'X-API-Key: <your-sandbox-key>'
Verify an expired license
curl 'https://www.tradesapi.com/verify?state=CA&license=SANDBOX-EXPIRED-99999' \
-H 'X-API-Key: <your-sandbox-key>'
Verify a license with disciplinary history
curl 'https://www.tradesapi.com/verify?state=FL&license=SANDBOX-DISCIPLINARY-77777' \
-H 'X-API-Key: <your-sandbox-key>'
Batch verify (mix-and-match)
curl -X POST 'https://www.tradesapi.com/batch' \
-H 'X-API-Key: <your-sandbox-key>' \
-H 'Content-Type: application/json' \
-d '{
"licenses": [
{ "state": "TX", "license": "SANDBOX-VALID-1", "trade": "hvac" },
{ "state": "CA", "license": "SANDBOX-EXPIRED-2", "trade": "general" },
{ "state": "FL", "license": "SANDBOX-NOTFOUND-3", "trade": "plumbing" }
]
}'
Search by name
curl 'https://www.tradesapi.com/search?state=TX&name=Sample' \
-H 'X-API-Key: <your-sandbox-key>'
Returns three deterministic rows whose license_number values are valid sandbox sentinels — you can chain a search-then-verify workflow end-to-end without leaving the sandbox.
What sandbox keys cannot do
- Reach production scrapers or cached production data — the routing decision is enforced at the API layer based on the key's scope.
- Charge credits — sandbox keys start at zero balance and never deduct.
- Mutate any account state beyond their own usage history.
Sandbox traffic is logged to your verification history alongside production traffic, so you can see your CI activity in the same audit-log export. Each sandbox row is tagged so downstream filters can split sandbox from production if you need it.
Rate limits
Sandbox keys share the same per-key rate-limit config as production keys (default 100 req/min). The standard X-RateLimit-Limit, X-RateLimit-Remaining, and X-RateLimit-Reset headers behave identically — useful for tuning your CI's request-pacing logic before pointing it at production.
Production cutover
When you're ready to go live, swap the X-API-Key header for your production key. The endpoint URLs, request shapes, and response schemas are byte-identical — the only difference is that production responses don't carry the "sandbox": true flag and credits are charged per successful verification.