Skip to main content
A tap proves someone is holding a specific physical item. verify() records that tap and hands back a session scoped to it: every call the session makes carries the session credential, so the session token never has to be threaded through your own code.

Verify a tap

verify() takes the chip_id and e from the tap and returns the session:
It never takes a URL. To get a tap out of one, parse it first with tryParseTapUrl, which returns null rather than throwing:
That handles both shapes a tap arrives in: an Endstate tap URL (/verify/{chip_id}?e= or /u/{chip_id}?e=), and a tap redirect destination on your own domain, where the values arrive as endstate_chip_id and endstate_e query parameters instead.
Keeping the parse separate is deliberate. “Is there a tap on this page?” is an offline question whose answer is often no - a direct visit, or a reload after the query was stripped - so it belongs in a branch rather than a try around a network call. See Host your own verify page for the full flow.
The e value is single-use. Never cache one and never replay one yourself. verify() derives its idempotency key from the tap, so a page refresh replays the original response instead of spending the credential and reporting a false “already scanned”.

Act on the session

The session exposes exactly what a tap authorizes:

Sessions cannot be refreshed

A new session needs a new tap. There is no refresh, by design - the session’s authority comes from someone having physically held the item.
isExpired() is a local clock check, for interface copy only. The SDK never gates a request on it: a device clock is not authoritative. The definitive answer is a 401 session_token.invalid_or_expired from the API.

Adopting a session you already hold

If your server issued the session, or you kept the token across a page reload, adopt it rather than re-verifying:

Where the tap comes from

In a browser, core can capture the tap for you through a registered tap source, or take the output of @endstate-sdk/reader directly - see Browser. On a server, you already have chip_id and e from whatever forwarded them to you.