Skip to main content
Foil is designed around backend verification. The browser sends your backend a fresh { sessionId, sealedToken } handoff, and your backend decides whether to allow, challenge, throttle, or block the action.
1

Start Foil early

Initialize the browser client on page load so collection begins before the user reaches the protected action.
2

Request a fresh session handoff

Right before signup, checkout, login, or another sensitive action, call foil.getSession().
3

Submit the handoff with the business action

Send { sessionId, sealedToken } to your backend alongside your normal payload.
4

Verify on the server

Use the SDK to verify the sealed token locally with your secret key.
5

Apply policy

Allow, challenge, rate-limit, or block based on the verdict.

Browser handoff

Verify the sealed token

The primary verification path. Local, fast, no network call to Foil. The iOS and Android SDKs return the same { sessionId, sealedToken } handoff, and you verify a native token the same way as a browser token.
The method is named safeVerifyFoilToken (and snake/Pascal variants) in every SDK except PHP, where it is SealedToken::safeVerify.

What verification doesn’t check

Verification confirms that the token is authentic and that your secret key can open it. The server SDKs decrypt the token and return its contents. They don’t check how old the token is, and they don’t remember which tokens they have seen. Two things follow from that:
  • A token has no expiry. Every getSession() call produces a new token, and the token’s decision.evaluated_at records when Foil produced it. A token that someone captured from a real browser still verifies later, so reject tokens whose evaluated_at is more than a few minutes old.
  • A token can be submitted more than once. Verification is stateless. To reject repeats, record the decision.event_id of each token you accept, which is unique to each token, or the session_id if you allow one action per session.
Also use the session_id from the verified token, not the sessionId that the browser sent. Nothing in the request ties the browser’s sessionId field to the token, so a caller can send a valid token next to a different session ID. The following example treats a token that fails verification or is more than five minutes old as missing:
Decide in your policy what a missing token means. See Verify the token on your server in the checkout guide for a complete example in every server SDK language.

Alternative: session readback

If you prefer to fetch the full session from the API (useful for async or audit workflows):
Key fields in the session readback response:

Attach your user ID

If the Foil session starts before the user exists in your database, attach your user ID after signup succeeds from your backend. Pass the session_id from the verified token.

Policy patterns

Start in report-only mode. Once you understand your traffic’s verdict distribution, gradually enable enforcement.

What’s next