Paste Script
Lowest-friction browser path: load keyra-oauth.js, render a KEYRA button, send the verification token to your backend.
On this page
Load the script
<script src="https://auth.keyra.ie/sdk/keyra-oauth.js"></script>Hosted URL: https://auth.keyra.ie/sdk/keyra-oauth.js. Auth origin defaults to https://auth.keyra.ie.
Required configuration
Every call to attach, renderButton, or completeRedirectCallback needs:
| Option | Required | Description |
|---|---|---|
authOrigin | Yes | KEYRA auth host, e.g. https://auth.keyra.ie |
clientId | Yes | Publishable client id (cp_test_* / cp_prod_*) |
redirectUri | Yes | Exact match of project callbackUrl or an entry in hosted redirect URIs |
Render a button
<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) {
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,
}),
});
},
onError: function (err) {
console.error(err);
},
});
</script>What happens here? The script generates PKCE + state, calls POST /verify/start (default scope verify), opens popup or redirect, exchanges the authorization code at POST /oauth/token, then invokes onSuccess.
Success → your backend
responseonSuccess result (shape)
{
"access_token": "…",
"verification_token": "…", // same value as access_token
"token_type": "Bearer",
"expires_in": 3600,
"user": { /* from token response */ },
"raw": { /* token endpoint body */ },
"userinfo": { /* optional if fetchUserinfo */ },
"userinfoError": null
}Full validate contract: Server validation.
Methods
| Method | Purpose |
|---|---|
KeyraOAuth.attach(opts) | Wire options to a selector / existing button without forcing appearance. |
KeyraOAuth.renderButton(container, opts) | Render a styled KEYRA button into a container (selector or element). |
KeyraOAuth.completeRedirectCallback(opts) | Resume after full-page redirect; completes PKCE exchange using stored verifier. |
Options reference
| Option | Default | Description |
|---|---|---|
mode | auto | auto | popup | redirect |
scope | verify | Passed to POST /verify/start |
timeoutMs | 120000 | Overall flow timeout (ms) |
fetchUserinfo | true | After token exchange, optionally GET /oauth/userinfo |
popupWidth / popupHeight | 520 / 720 | Popup window size |
autoCompleteRedirect | true | Auto-run redirect callback completion when query params present |
button / selector | — | Used with attach to bind an existing control |
onSuccess / onError | — | Result / error callbacks |
appearance | styled defaults | Object for button styling, or false to skip rendering chrome |
Events & storage
- Popup completion uses
postMessagetypesKEYRA_AUTH_SUCCESS/KEYRA_AUTH_ERRORwith an origin check againstauthOrigin. - Redirect PKCE state is stored under session key
keyra:oauth:flow:v2(notlocalStorageas your app session).
Appearance
Pass an appearance object, or appearance: false to skip KEYRA button chrome (e.g. when using attach on your own button).
| Property | Values |
|---|---|
theme | black | white | outline | icon |
size | small | medium | large |
shape | rectangular | pill |
text | Presets login_with | continue_with | verify_with | signup_with, or a custom string |
loadingText | String shown while the flow is in progress |
showLogo | Boolean |
width | CSS width for the control |
logoAlignment | Logo placement relative to label |
logoUrl | Optional custom logo URL |
ariaLabel | Accessible name override |
variables | Object of CSS variable overrides |
