Overview

Add "Sign in with Paspo" to a website — with the ready SDK, an AI prompt, or your own OAuth 2.0 client.

Sign in with Paspo lets users sign in to your website with their Paspo ID account. Paspo is a standard OpenID Connect provider: your page gets a one-time authorization code, your server exchanges it for an id_token with the user's verified e-mail, phone or name.

Choose how to integrate

Paste one prompt into Claude Code, Cursor, Codex or Copilot and let the agent wire up the frontend and backend.

npm install @pingocean/paspo-sdk or a single <script> tag. Popup, PKCE, FedCM and fallbacks are handled for you.

Copy-paste examples for React, Next.js, Vue, Nuxt, Angular, Svelte and plain HTML.

No SDK: build the OAuth 2.0 + PKCE flow yourself or plug Paspo into Auth.js, openid-client and other OIDC libraries.

How it works

  1. The user clicks Sign in with Paspo on your page. The SDK generates state, nonce and a PKCE code_verifier.
  2. A Paspo window opens at https://paspo.id/oauth/authorize. The user scans a QR code with the Paspo app or confirms an existing session, and picks which e-mail / phone to share.
  3. The window closes and your page receives a one-time code (valid for 60 seconds).
  4. Your page sends code and code_verifier to your server.
  5. Your server calls POST https://paspo.id/api/w/v1/oauth/token with client_secret, verifies the returned id_token and creates its own session.

In Chromium 141+, when you ask only for phone (no email), the SDK first shows the browser's own sign-in prompt (FedCM) — one tap for users already signed in to Paspo. If the browser blocks the popup, the SDK falls back to a full-page redirect.

Before you start

You need a registered OAuth client. Contact Support with:

Redirect URIsExact URLs (no wildcards), e.g. https://app.example.com/auth/paspo/callback. Must be on the same origin as the page with the button.
ScopesAny of openid, profile, email, phone.
Origins (optional)https://app.example.com — needed for the FedCM prompt.
Name, logo, privacy policy, termsShown on the consent screen.

You receive a public client_id (goes in the browser) and a client_secret (server only).

client_secret never goes to the browser

The code exchange always runs on your server. Never put client_secret in frontend code, environment variables prefixed with NEXT_PUBLIC_ / VITE_ / NUXT_PUBLIC_, or mobile apps.

Endpoints

Issuerhttps://paspo.id
Discoveryhttps://paspo.id/.well-known/openid-configuration
Authorizehttps://paspo.id/oauth/authorize
Tokenhttps://paspo.id/api/w/v1/oauth/token
JWKShttps://paspo.id/api/w/v1/oauth/jwks
UserInfohttps://paspo.id/api/w/v1/oauth/userinfo
SDK (CDN)https://paspo.id/sdk/paspo.min.js

Always prefer the values from the discovery document.

Next steps