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 from the test-helper 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 POST /v1/test-helpers/taps with the chip’s chip_id to get a fresh, single-use e value. Test helpers take a secret key only, and the endpoint is only available on test chips - calling it for 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 tap counter behaves.Each call produces a new e value. Use it immediately in the next step - it is single-use and cannot be reused.chip_id is the only required field. Optionally pass { "count": <integer> } alongside it 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 chip_id and e value to POST /v1/taps exactly as you would for a real tap. The 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/test-helpers/taps again to get a new e value for your next verification. Each e is single-use - generate a fresh one for each call to POST /v1/taps.
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 tap

Pass "dry_run": true in a verify request to validate an e value without recording a tap or issuing a session token. This is useful for confirming your integration handles the request/response shape correctly before committing real tap records. The e value is consumed either way - generate a new one from POST /v1/test-helpers/taps 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.