Skip to main content
Test chips let you build and verify your integration end-to-end before you have encoded hardware in hand. They behave identically to real chips in every API call — the only difference is how you obtain an e value: you generate one on demand via the /tap endpoint instead of reading it from a physical tag. Use this guide to run the complete loop — create a test chip, generate a tap credential, and verify it — entirely with curl.

Full walkthrough

1

Create a test chip

Pair a test chip to an existing unit by setting is_test: true. You do not supply a chip_id or an initial e value — Endstate assigns the chip_id for you.
Note the chip_id returned in the response — you use it in every subsequent call. Pairing the chip also triggers issuance: the unit’s token.status transitions from "pending" to "active" and a serial number is assigned.
2

Generate a tap value

Call the /tap endpoint to get a fresh, single-use e value. This endpoint is only available on test chips — calling it on a real encoded chip returns chip.not_a_test_chip.
count is the emulated chip counter used to generate this e value — it increments with each simulated tap, mirroring how a physical chip’s scan counter behaves.Each call produces a new e value. Use it immediately in the next step — it is single-use and cannot be reused.
/tap takes no required fields, and an empty body is accepted — with or without a Content-Type: application/json header, the API treats it as {}. Only a non-empty body that isn’t valid JSON is rejected (validation.failed).
Optionally pass { "count": <integer> } in the body to pin the emulated counter for the generated e value — it must be greater than the chip’s current counter. When omitted, the next counter value is used automatically; most integrations never need to set it.
3

Verify the tap

Submit the e value exactly as you would for a real tap. The verify endpoint makes no distinction between test chips and encoded chips at this point — the flow is identical.
A successful response confirms verification worked. The session_token is short-lived proof that the chip was tapped; pass it to a client to authorize unit-scoped actions without exposing your API key.
4

Repeat as needed

Call POST /v1/chips/{chip_id}/tap again to get a new e value for your next verification. Each e is single-use — generate a fresh one for each call to the verify endpoint.
You can run this loop as many times as you need during development. scan_count increments with each successful verification.

How test chips compare to encoded chips

Test chips are otherwise indistinguishable from encoded chips through the API. Your verification handler does not need to branch on is_test. To list only your test chips, pass is_test=true to the chips list endpoint:

Validate without recording a scan

Pass "dry_run": true in a verify request to validate an e value without recording a scan or issuing a session token. This is useful for confirming your integration handles the request/response shape correctly before committing real scan records. The e value is consumed either way — generate a new one from /tap for your next call.
When dry_run is true, the response has dry_run: true, session_token and id are null, and scan_count does not increment.

Development and production

Test chips are for development only. Production verification requires encoded NFC hardware chips — physical tags that generate e values on each tap. Before going live, replace test chips with encoded chips and confirm your integration handles real tap URLs correctly. See Environments for the API base URL and testing model.

Next steps

Verify a unit

The full production verification guide, including how real tap URLs deliver the chip_id and e value.

Chips & verification

How chips work, what the e value is, and the full verification model.