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
Install golang-jwt/jwt/v5
Install
go get github.com/golang-jwt/jwt/v5Mint 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_IDwith 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_AUDIENCEso you do not hardcode it.Set the environment variable
Set
REQIO_SECRETto 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-secretPass 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"pro".amountnumberinterval"month" | "year"amount.CRM enrichment
healthScorenumber (0-100)accountIdstringaccountId fallback).renewalAtstring (ISO 8601 date)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.