Forwarded Sessions
Signed, expiring, server-backed context objects that carry your payload from web click to app claim.
Session creation
A Forwarded Session is created when a user visits a Forwarded Link in a supported browser. The session holds a copy of the link's current payload, a signed token (32-byte random value, HMAC-SHA256 signed), a nonce, and an expiry timestamp.
The token is embedded in the iOS app-argument (passed through the Smart App Banner) or the Android referrer string (passed by Google Play to the app on first post-install open). The raw token is never stored server-side after creation — only its HMAC hash is kept.
Sessions in state CREATED become OPENED when the user taps the Smart App Banner or the Play Store delivers the referrer string. If the user closes the browser without continuing to install, the session remains CREATED until it expires.
Session lifecycle
CREATED: The initial state. The payload is stored, the token is issued, the landing page is displayed. The session may receive OPENED from multiple platform paths (e.g. Smart App Banner and Universal Link) — only the first counts.
OPENED → RESOLVED: When the app launches and the SDK finds a pending token, it calls the Forwarded resolve API. The API verifies the HMAC signature, checks the nonce, validates expiry, and marks the session RESOLVED. The payload is returned to the SDK.
CLAIMED: After your code knows the user identity, call claim() with their external_user_id. The session is permanently associated with that user. A claimed session cannot be claimed by a different user. Retries with the same idempotency key are safe and return the same result.
Session expiry
Sessions have a configurable expiry (default 24 hours, maximum 7 days). An expired session cannot be resolved even if the token is valid. The SDK returns null for expired sessions, logging the expiry reason.
Expired sessions are retained in the dashboard for 90 days for inspection and debugging before being pruned. They are not delivered via webhook after expiry.
Idempotency and retries
The claim endpoint accepts an idempotency_key parameter. Two claim requests with the same key return the same result — even if the session was already claimed. Use 'claim-{userId}' as the idempotency key.
If a different external_user_id is presented for an already-claimed session, the API returns 409 Conflict. This prevents a session from being bound to multiple users.