Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.kayle.id/llms.txt

Use this file to discover all available pages before exploring further.

Reading the cryptographic chip in a passport requires NFC, which is a phone-only capability. When a user lands on verify.kayle.id, the verify app coordinates a handoff to a mobile client — either Kayle’s iOS or Android app on the same device or a desktop-to-phone QR pairing. You don’t implement any of this. The mobile apps and the verify app handle it. This page exists so you understand what your user is seeing and why.

The handoff token

The verify app calls POST /v1/verify/session/:id/handoff to mint a one-time mobile_write_token:
{
  "v": 1,
  "session_id": "vs_...",
  "attempt_id": "va_...",
  "mobile_write_token": "...",
  "expires_at": "2026-05-05T11:05:00Z"
}
The token is valid for 5 minutes. The mobile app receives it via a deep link (same-device handoff) or a QR code (desktop-to-phone), then opens a WebSocket to the API and uses the token in its first message to authenticate.

Same-device idempotency

Within a 60-second window, repeated handoff requests for the same session reuse the same token. After that window, a new token is issued and a new attempt may be started. The token is consumed on the first successful mobile hello — replays fail. The first device that authenticates becomes the only device that can finish the attempt: its hashed device ID is recorded against the attempt and subsequent claims from a different device are rejected. This is the basis for the same-device-only flag exposed in the public session status — once any attempt has been claimed, the verify app stops offering desktop-to-phone pairing.

What you should do

For most integrations, nothing. Send the user to verification_url and wait for the webhook. If you want to render your own status indicator while the user is mid-flow, poll GET /v1/verify/session/:id/status (a public endpoint scoped to the session ID) — it returns the session’s current status and a same_device_only flag without exposing any document data.