By default the widget tracks users anonymously. Adding identity lets you:
- Know who submitted what: link requests to real users, not anonymous IDs.
- Weight feedback by revenue: requests from high-value customers rise in your backlog automatically.
- Deduplicate across sessions: the same user's upvotes and submissions merge even if they clear cookies.
Set up in the dashboard
Identity is a guided four-step flow at Project > Settings > Identity. The dashboard generates a ready-to-paste snippet for your stack with your real project ID and audience URL already filled in.
1. Choose your stack
The dashboard asks which server language you use: Next.js, Node.js, Python, PHP, Ruby, or Go. Your choice controls which snippet is shown in the next step.
2. Generate a signing secret
Click Generate to create a per-project signing secret. Copy it into your server environment as REQIO_SECRET. It must never be sent to the browser.
3. Mint a token on your server
Paste the snippet from the dashboard into your server code and adapt the user fields to your session model. The snippet uses the standard JWT library for your language. No Reqio package is required or published.
Per-language guides:
- Node.js and Next.js -- uses
jose - Python -- uses
PyJWT - PHP -- uses
firebase/php-jwt - Ruby -- uses the
jwtgem - Go -- uses
golang-jwt/jwt/v5
4. Embed the widget with the token
Pass the token to the widget via the data-identity-token attribute:
<script
src="https://reqio.app/widget.js"
data-project-id="YOUR_PROJECT_ID"
data-identity-token="<token minted by your server>"
async
></script>
Mint a fresh token on every server-rendered request. Tokens expire after 300 seconds (5 minutes).
How it works
Your server mints a short-lived HS256 JWT and passes it to the widget. The widget sends the token with every request; Reqio verifies the signature using the per-project secret. The secret never leaves your server. Tokens are short-lived and audience-bound to one project, so a leaked token cannot be used against a different project.
Token payload
Every token includes:
| Claim | Required | Description |
|---|---|---|
| sub | yes | Your stable, opaque user identifier (e.g. a database row ID). |
| aud | yes | Audience URL for your project: https://reqio.app/p/{projectId}. The dashboard fills this in for you. |
| iat | yes | Issued-at time as a Unix timestamp. |
| exp | yes | Expiry time. Set to iat + 300 (5 minutes). |
| email | optional | Used for deduplication and display. |
| traits | optional | Customer billing details for revenue weighting. |
Revenue traits
Pass customer billing details inside the traits object to enable revenue-weighted ranking in your backlog.
{
"plan": "pro",
"amount": 4900,
"interval": "month"
}
| Field | Type | Description |
|---|---|---|
| plan | string | Plan name on your billing system, e.g. "pro". |
| amount | number | 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" or "year" | Billing cadence for amount. |
AI agent integration
The dashboard provides a copy-ready AI agent prompt next to each snippet. Copy it into Claude Code, Cursor, Windsurf, or any AI coding assistant to have the agent add identity to your server automatically. The prompt includes your project ID, audience URL, the correct library, and the full payload structure.
Identifying users from JavaScript
If you cannot pass the token at render time (for example, in a SPA where the user logs in after the initial page load), call window.Reqio.identify() after the user authenticates:
window.Reqio.identify(token);
The widget queues calls made before it finishes loading and replays them once it initialises.
Security
REQIO_SECRET must never reach the browser. Store it in an environment variable managed by your deployment platform. Tokens are short-lived (300 seconds) and audience-bound to one project URL.