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.

How it works. Sandbox keys hit the same endpoints as production keys (/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.

PrefixResponse 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 elsevalid: 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

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.

Get your sandbox key →