Developer
PHP
Mint Reqio HS256 identity tokens on a PHP server using firebase/php-jwt. Compatible with Laravel, Symfony, and plain PHP.
The snippet below is exactly what the dashboard generates under Project > Settings > Identity when you choose PHP. 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 firebase/php-jwt
Install
composer require firebase/php-jwtMint a token
<?php // composer require firebase/php-jwt use Firebase\JWT\JWT; $now = time(); $payload = [ "sub" => $user->id, "email" => $user->email, "traits" => [ // 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, ], "aud" => "https://reqio.app/p/YOUR_PROJECT_ID", "iat" => $now, "exp" => $now + 300, ]; $token = JWT::encode($payload, $_ENV["REQIO_SECRET"], "HS256");Replace
YOUR_PROJECT_IDwith your project ID, or copy the full snippet from the dashboard where the audience URL is pre-filled.Framework-specific examples:
<?php namespace App\Http\Controllers; use Firebase\JWT\JWT; use Illuminate\Http\Request; class PageController extends Controller { public function index(Request $request) { $user = $request->user(); $now = time(); $token = JWT::encode( [ "sub" => (string) $user->id, "email" => $user->email, "traits" => [ "plan" => $user->plan, "amount" => $user->plan_amount, "interval" => $user->billing_interval, ], "aud" => config("services.reqio.audience"), "iat" => $now, "exp" => $now + 300, ], config("services.reqio.secret"), "HS256" ); return view("page", compact("token")); } }{{-- resources/views/page.blade.php --}} <script src="https://reqio.app/widget.js" data-project-id="{{ config('services.reqio.project_id') }}" data-identity-token="{{ $token }}" async ></script>Store the audience URL in
services.reqio.audienceinconfig/services.phpso you do not hardcode it.<?php require 'vendor/autoload.php'; use Firebase\JWT\JWT; $now = time(); $token = JWT::encode( [ "sub" => (string) $_SESSION["user_id"], "email" => $_SESSION["user_email"] ?? null, "aud" => getenv("REQIO_AUDIENCE"), "iat" => $now, "exp" => $now + 300, ], getenv("REQIO_SECRET"), "HS256" ); ?> <script src="https://reqio.app/widget.js" data-project-id="<?= htmlspecialchars(getenv("REQIO_PROJECT_ID")) ?>" data-identity-token="<?= htmlspecialchars($token) ?>" async ></script>Always escape output with
htmlspecialcharswhen interpolating into HTML attributes.Set the environment variable
Set
REQIO_SECRETto the signing secret from Project > Settings > Identity > Reveal secret. Store it in your environment (.envfile, server config, or secrets manager) and never echo it into responses.Environment variable
REQIO_SECRET=your-signing-secretPass the token to the widget
For server-rendered templates, pass the token via
data-identity-token:<script src="https://reqio.app/widget.js" data-project-id="YOUR_PROJECT_ID" data-identity-token="<?= htmlspecialchars($token) ?>" 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".amountintinterval"month" | "year"amount.CRM enrichment
healthScoreint (0-100)accountIdstringaccountId fallback).renewalAtstring (ISO 8601 date)Security
Store REQIO_SECRET in your environment and never echo it into responses. The JWT is short-lived and audience-bound to one project, limiting the blast radius of a leaked token. The signing secret must never leave your server.