Skip to content

HomeDocsDeveloperGo

Developer

Go

Mint Reqio HS256 identity tokens on a Go server using golang-jwt/jwt/v5.

The snippet below is exactly what the dashboard generates under Project > Settings > Identity when you choose Go. Copy it from the dashboard to get your real project ID and audience URL pre-filled.

Before you start

  • A Reqio project
  • A signing secret generated at Project > Settings > Identity
  1. Install golang-jwt/jwt/v5

    Install

    go get github.com/golang-jwt/jwt/v5
  2. Mint a token

    // go get github.com/golang-jwt/jwt/v5
    import (
        "os"
        "time"
        jwt "github.com/golang-jwt/jwt/v5"
    )
     
    type reqioClaims struct {
        Email  string         `json:"email"`
        Traits map[string]any `json:"traits"`
        jwt.RegisteredClaims
    }
     
    now := time.Now()
    claims := reqioClaims{
        Email: user.Email,
        Traits: map[string]any{
            // amount in cents; interval is "month" | "year"
            "plan":     user.Plan,
            "amount":   user.PlanAmount,
            "interval": user.BillingInterval,
            // optional CRM enrichment: 0-100 health, CRM account id, ISO renewal
            "healthScore": account.HealthScore,
            "accountId":   account.CRMID,
            "renewalAt":   account.RenewalAt,
        },
        RegisteredClaims: jwt.RegisteredClaims{
            Subject:   user.ID,
            Audience:  jwt.ClaimStrings{"https://reqio.app/p/YOUR_PROJECT_ID"},
            IssuedAt:  jwt.NewNumericDate(now),
            ExpiresAt: jwt.NewNumericDate(now.Add(5 * time.Minute)),
        },
    }
    token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).
        SignedString([]byte(os.Getenv("REQIO_SECRET")))

    Replace YOUR_PROJECT_ID with your project ID, or copy the full snippet from the dashboard where the audience URL is pre-filled.

    HTTP handler example:

    package main
     
    import (
        "net/http"
        "os"
        "text/template"
        "time"
     
        jwt "github.com/golang-jwt/jwt/v5"
    )
     
    type reqioClaims struct {
        Email  string         `json:"email"`
        Traits map[string]any `json:"traits"`
        jwt.RegisteredClaims
    }
     
    var tmpl = template.Must(template.ParseFiles("templates/page.html"))
     
    func pageHandler(w http.ResponseWriter, r *http.Request) {
        user := userFromSession(r) // your own session resolution
        if user == nil {
            http.Error(w, "unauthorized", http.StatusUnauthorized)
            return
        }
     
        now := time.Now()
        claims := reqioClaims{
            Email:  user.Email,
            Traits: map[string]any{
                "plan":     user.Plan,
                "amount":   user.PlanAmountCents,
                "interval": user.BillingInterval,
            },
            RegisteredClaims: jwt.RegisteredClaims{
                Subject:   user.ID,
                Audience:  jwt.ClaimStrings{os.Getenv("REQIO_AUDIENCE")},
                IssuedAt:  jwt.NewNumericDate(now),
                ExpiresAt: jwt.NewNumericDate(now.Add(5 * time.Minute)),
            },
        }
     
        token, err := jwt.NewWithClaims(jwt.SigningMethodHS256, claims).
            SignedString([]byte(os.Getenv("REQIO_SECRET")))
        if err != nil {
            http.Error(w, "identity error", http.StatusInternalServerError)
            return
        }
     
        data := map[string]string{
            "ProjectID":  os.Getenv("REQIO_PROJECT_ID"),
            "ReqioToken": token,
        }
        tmpl.Execute(w, data)
    }
    <!-- templates/page.html -->
    <script
      src="https://reqio.app/widget.js"
      data-project-id="{{ .ProjectID }}"
      data-identity-token="{{ .ReqioToken }}"
      async
    ></script>

    Store the audience URL in REQIO_AUDIENCE so you do not hardcode it.

  3. Set the environment variable

    Set REQIO_SECRET to the signing secret from Project > Settings > Identity > Reveal secret. Store it in an environment variable managed by your deployment platform; never include it in responses.

    Environment variable

    REQIO_SECRET=your-signing-secret
  4. Pass the token to the widget

    For server-rendered HTML, pass the token via data-identity-token:

    <script
      src="https://reqio.app/widget.js"
      data-project-id="YOUR_PROJECT_ID"
      data-identity-token="{{ .ReqioToken }}"
      async
    ></script>

    For SPAs where the user authenticates after the initial page load, call window.Reqio.identify() from JavaScript after login:

    window.Reqio.identify(token);

Traits reference

planstring
Plan name on your billing system, e.g. "pro".
amountnumber
Recurring charge as billed, in cents. For annual plans send the full annual total; Reqio divides by 12 to derive the monthly value.
interval"month" | "year"
Billing cadence for amount.

CRM enrichment

healthScorenumber (0-100)
CRM account-health score. Reqio clamps out-of-range values.
accountIdstring
Your CRM's external account id. Not displayed, a matching key for a future CRM sync (email first, accountId fallback).
renewalAtstring (ISO 8601 date)
Next renewal date. Unparseable values are dropped by Reqio.

Security

Store REQIO_SECRET in an environment variable and never include it in responses. The JWT is short-lived (5 minutes), signed with HS256, and audience-bound to one Reqio project URL, limiting the damage from a leaked token. The signing secret must remain server-side.