Go to developer

Server Validation

Browser success is not login complete. Your backend must call POST /verify/validate — single-use — before creating your application session.

On this page

Trust boundary

BROWSER                 YOUR BACKEND              KEYRA                USER
   │                          │                      │                    │
   │ Start (publishable cp_*) │                      │                    │
   ├────────────────────────────────────────────────►│                    │
   │ authorize_url            │                      │                    │
   │◄────────────────────────────────────────────────┤                    │
   │ Open popup/redirect      │                      │                    │
   │                          │                      │◄─── verify ────────┤
   │ authorization code       │                      │                    │
   │◄────────────────────────────────────────────────┤                    │
   │ Token exchange (PKCE)    │                      │                    │
   ├────────────────────────────────────────────────►│                    │
   │ access_token             │                      │                    │
   │ (= verification_token)   │                      │                    │
   │◄────────────────────────────────────────────────┤                    │
   │ POST token to backend    │                      │                    │
   ├─────────────────────────►│                      │                    │
   │                          │ POST /verify/validate│                    │
   │                          ├─────────────────────►│                    │
   │                          │ valid + user         │                    │
   │                          │◄─────────────────────┤                    │
   │                          │ Create YOUR session  │                    │
   │ Set app session cookie   │                      │                    │
   │◄─────────────────────────┤                      │                    │
Validate sits after token exchange
  • Browser: obtain access_token / verification_token (same value); POST it to your API.
  • Server: call validate; map KEYRA user → your user; create your session cookie/JWT.

REST

POST/verify/validate
SERVERHTTP
POST https://auth.keyra.ie/verify/validate
Content-Type: application/json

{
  "verification_token": "…",
  "client_id": "cp_test_…"
}
FieldRequiredDescription
verification_tokenYesSame value as access_token from token exchange
client_idNoPublishable client id; recommended to scope validation

Server SDK

SERVERTypeScript
import { createKeyraServer } from "@keyra/typescript-sdk";

const keyra = createKeyraServer({
  baseUrl: process.env.KEYRA_BASE_URL ?? "https://auth.keyra.ie",
});

app.post("/api/auth/keyra", async (req, res) => {
  const verification_token = String(req.body.verification_token ?? "");
  if (!verification_token) {
    return res.status(400).json({ error: "verification_token required" });
  }

  const outcome = await keyra.validateVerification({
    verification_token,
    client_id: process.env.KEYRA_PUBLISHABLE_CLIENT_ID,
  });

  if (!outcome.valid) {
    return res.status(401).json({ error: outcome.error ?? "invalid" });
  }

  // Map outcome.user → YOUR user, then create YOUR session (HttpOnly cookie / etc.)
  return res.json({ ok: true });
});

Success response

responsePOST /verify/validate (success)
JSON
{
  "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
  }
}

Access token lifetime defaults to ~3600s when unset (clamped 60–604800 via OAUTH_ACCESS_TOKEN_TTL_SECONDS). Validate still consumes the token once regardless of TTL remaining.

Single-use & errors

ErrorHTTPMeaning
verification_token_already_used409Replay / double validate
invalid_verification_token401Unknown, expired, or malformed token
invalid_client401Client id rejected for this token

Full matrix: Errors.

Create your session

  • Only after valid: true create your application session (secure, HttpOnly cookie or equivalent).
  • Map user.id (and phone/email if present) onto your account model.
  • Do not re-validate the same token on every request — issue your session and use that.

Session design: Sessions.