Add KEYRA login to a web application
Default: paste script + backend /verify/validate. Web SDK and server-driven starts are available as alternatives.
On this page
Prerequisites
- KEYRA developer account and project
- Publishable client id (
cp_test_*/cp_prod_*) — see Credentials - Exact callback URL registered on the project (primary callback and/or hosted redirect URIs list)
- A backend route that can call
/verify/validate
Register your callback URL
Start APIs reject redirects that are not an exact string match of the project's primary callbackUrl or an entry in hosted redirect URIs. Configure these in the Developer Portal project settings.
Development
http://localhost:3000/auth/keyra/callback
Production
https://example.com/auth/keyra/callbackStep 1 — Browser: paste script
<div id="keyra-login"></div>
<script src="https://auth.keyra.ie/sdk/keyra-oauth.js"></script>
<script>
KeyraOAuth.renderButton("#keyra-login", {
authOrigin: "https://auth.keyra.ie",
clientId: "cp_test_YOUR_PUBLISHABLE_ID",
redirectUri: "http://localhost:3000/auth/keyra/callback",
mode: "auto",
scope: "verify",
onSuccess: async function (result) {
// result.access_token === result.verification_token
const res = await fetch("/api/auth/keyra", {
method: "POST",
headers: { "Content-Type": "application/json" },
credentials: "include",
body: JSON.stringify({
verification_token: result.verification_token || result.access_token,
}),
});
if (!res.ok) throw new Error("Server validation failed");
window.location.href = "/app";
},
onError: function (err) {
console.error(err);
},
});
</script>What happens here? The script calls POST /verify/start, opens the hosted UI, exchanges the authorization code at /oauth/token, then invokes onSuccess with access_token / verification_token (same value). Your handler posts that token to your backend.
Step 2 — Server: validate then create session
import { createKeyraServer } from "@keyra/typescript-sdk";
import express from "express";
const keyra = createKeyraServer({
baseUrl: process.env.KEYRA_BASE_URL ?? "https://auth.keyra.ie",
});
const app = express();
app.use(express.json());
app.post("/api/auth/keyra", async (req, res) => {
const verification_token = String(req.body.verification_token ?? "");
const client_id = process.env.KEYRA_PUBLISHABLE_CLIENT_ID!;
if (!verification_token) {
return res.status(400).json({ error: "verification_token required" });
}
try {
const outcome = await keyra.validateVerification({
verification_token,
client_id,
});
if (!outcome.valid) {
return res.status(401).json({ error: outcome.error ?? "invalid" });
}
// Map KEYRA user → YOUR user record, then create YOUR session.
// Example only — replace with your session strategy (HttpOnly cookie / JWT / etc).
req.session = req.session ?? {};
(req.session as { keyraUserId?: number }).keyraUserId = outcome.user?.id as number | undefined;
return res.json({ ok: true, user: outcome.user });
} catch (err) {
console.error(err);
return res.status(401).json({ error: "validation_failed" });
}
});responsePOST /verify/validate (success)
{
"valid": true,
"verification_id": "…",
"client_id": "cp_test_…",
"expires_at": "2026-08-05T12:00:00.000Z",
"user": {
"id": 123,
"phone": "+353…",
"fullName": null,
"email": null,
"role": "developer",
"isAdmin": false,
"accessRole": null
}
}Alternative frontends
Default above. Full option reference: Paste Script guide.
Test the integration
- Load your page and click the KEYRA button.
- Complete hosted verification.
- Confirm your
/api/auth/keyrareceives the token and returns 200. - Confirm a second validate with the same token fails with
verification_token_already_used. - Confirm your app session cookie/JWT is set only after validate succeeds.
