Five-minute integration

Browser widget in. One-time token out.

The browser receives only a public site key. Your server keeps the secret key and redeems each signed token exactly once.

1. Add the widget

Use your public site key and a stable action name. Identify the controller and provide working privacy and alternative-verification links.

<glint-proof
  site-key="gp_site_YOUR_KEY"
  action="signup"
  controller-name="Your company"
  privacy-url="https://example.com/privacy"
  alternative-url="https://example.com/verify-another-way"
></glint-proof>
<script async src="https://glintproof.com/widget.js"></script>

2. Receive the token

Listen for the verified event and send the token with your form. If you do not use an alternative URL, handle the alternative event and open an equivalent route yourself.

const widget = document.querySelector('glint-proof');

widget
  .addEventListener('glintproof:verified', ({ detail }) => {
    form.elements.glintproofToken.value = detail.token;
  });

widget.addEventListener('glintproof:alternative', () => {
  showEmailOrPasskeyVerification();
});

3. Verify on your server

Call siteverify with your secret key. Never call this endpoint from browser code.

const check = await fetch('https://glintproof.com/api/siteverify', {
  method: 'POST',
  headers: {
    'Authorization': `Bearer ${process.env.GLINTPROOF_SECRET_KEY}`,
    'Content-Type': 'application/json'
  },
  body: JSON.stringify({ token: req.body.glintproofToken, action: 'signup' })
});

const result = await check.json();
if (!result.success) throw new Error('Human check failed');

Successful response

{ "success": true, "action": "signup", "score": 91, "verifiedAt": "2026-07-15T12:00:00.000Z" }

Production checklist