Skip to content

HomeDocsDeveloperPython

Developer

Python

Mint Reqio HS256 identity tokens on a Python server using PyJWT. Compatible with Django, Flask, FastAPI, and any Python 3.8+ framework.

The snippet below is exactly what the dashboard generates under Project > Settings > Identity when you choose Python. 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 PyJWT

    Install

    pip install PyJWT
  2. Mint a token

    # pip install PyJWT
    import os, time
    import jwt
     
    now = int(time.time())
    payload = {
        "sub": user.id,
        "email": user.email,
        "traits": {
            # amount in cents; interval is "month" | "year"
            "plan": user.plan,
            "amount": user.plan_amount,
            "interval": user.billing_interval,
            # optional CRM enrichment: 0-100 health, CRM account id, ISO renewal
            "healthScore": account.health_score,
            "accountId": account.crm_id,
            "renewalAt": account.renewal_at,
        },
        "aud": "https://reqio.app/p/YOUR_PROJECT_ID",
        "iat": now,
        "exp": now + 300,
    }
    token = jwt.encode(payload, os.environ["REQIO_SECRET"], algorithm="HS256")

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

    Framework-specific examples:

    # views.py
    import os, time
    import jwt
    from django.contrib.auth.decorators import login_required
    from django.shortcuts import render
     
    @login_required
    def my_view(request):
        now = int(time.time())
        token = jwt.encode(
            {
                "sub": str(request.user.pk),
                "email": request.user.email,
                "traits": {"plan": getattr(request.user, "plan", None)},
                "aud": os.environ["REQIO_AUDIENCE"],
                "iat": now,
                "exp": now + 300,
            },
            os.environ["REQIO_SECRET"],
            algorithm="HS256",
        )
        return render(request, "my_page.html", {"reqio_token": token})
    {# my_page.html #}
    <script
      src="https://reqio.app/widget.js"
      data-project-id="{{ project_id }}"
      data-identity-token="{{ reqio_token }}"
      async
    ></script>

    Store the audience URL (e.g. https://reqio.app/p/proj_abc123) 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 server-side only; never include it in responses sent to the browser.

    Environment variable

    REQIO_SECRET=your-signing-secret
  4. Pass 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="{{ reqio_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

planstr
Plan name on your billing system, e.g. "pro".
amountint
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

healthScoreint (0-100)
CRM account-health score. Reqio clamps out-of-range values.
accountIdstr
Your CRM's external account id. Not displayed, a matching key for a future CRM sync (email first, accountId fallback).
renewalAtstr (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 sent to the browser. The JWT is safe to send to clients because it is short-lived, audience-bound, and contains only the claims you choose to include.