Skip to main content

Validate Referrals

Referral Traffic ValidationDirect link to Referral Traffic Validation

Rokt provides a mechanism for advertisers to validate the authenticity of referral traffic delivered through its platform.

The current implementation uses a JSON Web Token (JWT) signed with the ECDSA-256 algorithm. The public keys required for verification can be retrieved from the following endpoints:

Default domain: https://public-api.rokt.com/.well-known/jwks.json

Custom domains: https://[custom-domain]/.well-known/jwks.json

We recommend downloading and caching these public keys for verification. The suggested cache duration is one week. In the event of a key rotation, Rokt will proactively contact you with guidance to ensure a smooth transition.

Update your campaign traffic URL to support signed token passthroughDirect link to Update your campaign traffic URL to support signed token passthrough

To generate the unique signed token please ensure that the destination URL of your creative includes the following as a URL parameter: jwt={rokt.jwt|}.

rokt-jwt-token

In the Destination URL, you will need to add & or ? before jwt={rokt.jwt|}. This is determined by the original traffic link. If the original traffic link contains a ?, add an & before the jwt. rok Example: www.landingpage.com/?hello=world&jwt={rokt.jwt|}

If the original traffic link does not contain a ?, add a ? before the jwt

Example: www.landingpage.com/?jwt={rokt.jwt|}

Using JWT in Campaign Traffic URLsDirect link to Using JWT in Campaign Traffic URLs

When specifying a campaign traffic URL, you can include the rokt.jwt macro. At runtime, Rokt will replace this macro with a digitally signed JWT. By validating this token with the public key, you can extract the following claims:

  • cid – Campaign ID
  • crid – Creative ID
  • rclid – Rokt Click ID. Read more about Rokt Click ID
  • iat – Issued-at timestamp
  • exp – Expiration timestamp (set to 24 hours from issuance)
  • iss – Issuer (set to "Rokt")
  • aud – Audience (set to empty string)

These fields allow advertisers to securely identify and attribute campaign traffic with confidence.

Note: Token expiration validation is optional and can be configured by advertisers based on their security requirements. Some advertisers may choose to validate expiration times strictly, while others may implement more flexible validation policies.

Bind referrals to a landing-page pathDirect link to Bind referrals to a landing-page path

Advertisers that need to prevent a valid referral token from being replayed on a different landing page can opt in to path-bound referral validation. This issues a version 2 token that also signs the resolved landing-page path, so a token minted for one page cannot be reused to authorize a different, higher-value page.

Path-binding is entirely opt-in and additive: the legacy {rokt.jwt|} macro and its claims are unchanged, and the two profiles can coexist across different creatives.

Enable path-bound tokensDirect link to Enable path-bound tokens

Use the rokt.jwt_path_bound macro as the value of the jwt query parameter in your creative's destination URL:

https://www.landingpage.com/offer?jwt={rokt.jwt_path_bound|}

The macro must appear in the URL's query string — it is rejected in the scheme, host, path, or fragment. As with the legacy macro, add ? or & before jwt= depending on whether the destination URL already contains a query string.

Version 2 claimsDirect link to Version 2 claims

Rokt replaces the macro with a version 2 referral JWT that contains all of the legacy referral claims plus:

  • ver – Token contract version. Integer 2.
  • path – The percent-encoded (escaped) path of the resolved landing page. Always begins with /, and excludes the query string and fragment.

A decoded version 2 payload looks like:

{
"iss": "Rokt",
"aud": "",
"iat": 1755666601,
"exp": 1755670201,
"cid": "1234567890123456789",
"crid": "2345678901234567890",
"rclid": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef",
"ver": 2,
"path": "/offer"
}

How Rokt derives the path claimDirect link to how-rokt-derives-the-path-claim

Rokt signs the escaped (percent-encoded) path component of the fully rendered destination URL, with the query string and fragment removed. To keep the signed path unambiguous, Rokt does not issue a path-bound token — it falls back to the authored URL with no ver/path token — when the resolved path:

  • does not begin with /;
  • contains a query (?) or fragment (#);
  • contains a backslash (\) or an empty segment (//);
  • contains a . or .. (dot) segment;
  • contains an encoded separator (%2F or %5C); or
  • contains a double-encoded character (%25).

Because these forms are rejected at signing time, the path you receive is always a single-decode, canonical, escaped path.

Validate a path-bound referralDirect link to Validate a path-bound referral

Validate path-bound referrals in trusted server-side routing or reward logic:

  1. Verify the ES256 signature using Rokt's public key (see the JWKS endpoints above).
  2. Validate the existing referral claims, including cid, crid, rclid, iat, and exp.
  3. Require ver to equal 2 on any route protected by path-bound validation.
  4. Compare the path claim to the escaped path of the incoming request — the percent-encoded path exactly as received, with the query string and fragment removed. Match it as an exact, case-sensitive string, and do not decode either side first: Rokt signs the escaped form and rejects encoded or double-encoded separators, so a raw comparison is both correct and safe. Most server frameworks expose a raw/undecoded request path for this purpose (for example r.URL.EscapedPath() in Go, URI.getRawPath() in Java, new URL(url).pathname in Node.js).
  5. Reject the token if ver or path is missing or does not match.

For example, a token carrying "path": "/offer" is valid for a request to https://www.landingpage.com/offer?utm=x (path /offer, query ignored) and must be rejected for a request to https://www.landingpage.com/instant.

Same-path entitlements. Do not rely on browser-only validation. If query parameters or server-side state can increase the reward or entitlement while the path stays the same, path binding alone is insufficient — contact your Rokt representative to define an additional signed entitlement claim.

Roll out enforcement graduallyDirect link to Roll out enforcement gradually

During adoption, accept both legacy and version 2 tokens. Enforce the ver/path checks only on the routes you have protected, and begin rejecting missing v2 claims on those routes only after you have confirmed all protected traffic is issuing them. Keep vulnerable paths paused until enforcement is verified.

The existing {rokt.jwt|} macro remains unchanged and does not include ver or path. Path-bound claims add approximately 35 characters to the rendered token for a short path such as /offer; confirm that the destination and any intermediaries support the resulting rendered URL length.

The language examples below show how to enforce the ver and path claims in each supported stack.

Clock Skew ToleranceDirect link to Clock Skew Tolerance

When implementing JWT validation, we recommend setting a 1-minute clock skew tolerance to account for potential time differences between servers. Perfect time synchronization between servers is not always possible in distributed systems, and this grace period helps ensure reliable token validation in production environments.

The examples below demonstrate how to implement this clock skew tolerance across different programming languages and JWT libraries.

Test TokenDirect link to Test Token

For testing the examples below, you can use this sample JWT token:

eyJhbGciOiJFUzI1NiIsImtpZCI6InJva3Qtc2lnbmluZy1rZXkiLCJ0eXAiOiJKV1QifQ.eyJjaWQiOiIzNDM2MDg1MzY4NjkyNDA4MzI0IiwiY3JpZCI6IjM0Mzc3MzI3NTQ5MzU5MDYzMDgiLCJyY2xpZCI6IjdkYjk1OGRiZDIzMjI0N2E0YTgyODVhMzRkMjJmZTBmNGU5YWZmYTQ2M2JmNWVlNTRlMjY3MjFhYjBkZjBlMjMiLCJuYmYiOjE3NTU2NjY2MDEsImV4cCI6MTc1NTY3MDIwMSwiaWF0IjoxNzU1NjY2NjAxfQ.D2_5RnmIgWucUx-7JG5b-Av9PM0V59w6Pmumqv0_zHgkD1136dPhKSMv2i-fP4Z0maANJcAwY6jSTXzp6Gc7gA

Note: This token is for testing purposes only and has an expiration time. Copy this token to use with the examples below.

ExamplesDirect link to Examples

Please see the list of example code below:

  • Java Example - JWT validation using Java with JJWT library
  • Python Example - JWT validation using Python with PyJWT and cryptography
  • Node.js Example - JWT validation using Node.js with jose library
  • Go Example - JWT validation using Go with golang-jwt
  • C# Example - JWT validation using C# with Microsoft.IdentityModel
Was this article helpful?