Reference

Web SDK functions, options, errors, scopes, id_token claims and endpoints.

Functions

Function
signIn(options)Starts sign-in. Call from a click handler. Returns nothing; results arrive in callbacks
takeVerifier(state)PKCE code_verifier for this attempt. Returns it once, then ""
takeNonce(state)The nonce sent to Paspo. Returns it once, then ""
configure({ origin })npm build only: set a non-default Paspo origin before the first signIn
versionSDK version string

With the CDN build these live on window.Paspo (no configure — the origin comes from the script URL).

signIn options

OptionType
clientIdstringRequired. Your client ID
redirectUristringRequired. A registered redirect URI on the same origin as the page
scopestringRequired. Space-separated scopes, e.g. "openid email"
fedcmbooleanfalse disables the browser's FedCM prompt. Default: used when possible
onSuccess(result) => voidGot a code. See result
onError(error) => voidSign-in failed. See errors
onClose() => voidThe user closed the Paspo window or dismissed the prompt

Calling signIn again while a window is open closes the old one and starts a new attempt.

Result

interface PaspoSignInResult {
  code: string;    // one-time, valid 60 s
  state: string;   // pass to takeVerifier / takeNonce
  via?: "fedcm";   // set when the browser prompt issued the code
}

When via is "fedcm", exchange the code without redirect_uri.

If the browser blocks the popup, onSuccess is not called: the tab goes to Paspo and returns to redirectUri?code=…&state=…. takeVerifier(state) works there too — the values are kept in this tab's sessionStorage.

Errors

interface PaspoSignInError {
  error: string;
  error_description: string;
  state?: string;
}
errorWhenWhat to do
invalid_requestMissing clientId / redirectUri / scope, an invalid URL, an insecure context (no crypto.subtle) or blocked sessionStorageFix the options; serve over HTTPS
access_deniedThe user declined on the consent screenLet them try again
otherStandard OAuth error codes passed through from Paspo, e.g. server_errorShow error_description, let the user retry

An unknown client_id or an unregistered redirect_uri is never redirected back to your site: Paspo shows the error in its own window. Check both in your client settings.

Errors from the token endpoint (on your server):

error
invalid_grantThe code expired (60 s), was already used, or code_verifier / redirect_uri don't match. Start a new sign-in
invalid_clientWrong client_id / client_secret
invalid_requestA required parameter is missing
unsupported_grant_typegrant_type isn't authorization_code

Scopes

ScopeClaims in id_tokenNotes
openidsub, iss, aud, exp, iat, nonceAlways include it
profilename
emailemail, email_verifiedThe user picks which address to share
phonephone_number, phone_number_verifiedThe user picks which number to share. phone without email enables the FedCM prompt in Chromium 141+

Request at least one of profile, email, phone.

ID token claims

ClaimType
issstringhttps://paspo.id
substringStable Paspo user ID. Use it as the account key
audstringYour client_id
exp, iatnumberUnix seconds
noncestringThe value from takeNonce(state)
namestringWith profile
emailstringWith email — the address the user chose on the consent screen, not necessarily their primary
email_verifiedbooleanWith email
phone_numberstringWith phone, E.164, e.g. +77001234567
phone_number_verifiedbooleanWith phone

Endpoints

DiscoveryGET https://paspo.id/.well-known/openid-configuration
AuthorizeGET https://paspo.id/oauth/authorize
TokenPOST https://paspo.id/api/w/v1/oauth/token
JWKSGET https://paspo.id/api/w/v1/oauth/jwks
UserInfoGET https://paspo.id/api/w/v1/oauth/userinfo with Authorization: Bearer <access_token>
FedCM confighttps://paspo.id/api/w/v1/fedcm/config.json

Browser storage

The SDK keeps two sessionStorage entries per attempt and removes them when read or when the attempt ends:

  • paspo.oauth.verifier.<state>
  • paspo.oauth.nonce.<state>

No cookies, no localStorage, no tracking.

Testing

  1. In development, log the result instead of posting it:
    Paspo.signIn({
      clientId: "YOUR_CLIENT_ID",
      redirectUri: location.origin + "/auth/paspo/callback",
      scope: "openid email",
      onSuccess: ({ code, state }) => console.log({ code, verifier: Paspo.takeVerifier(state) }),
    });
    
  2. Within 60 seconds run the cURL request with these values.
  3. Before release, check: a successful sign-in, cancelling the window, a blocked popup (redirect fallback), and a reused code (invalid_grant).

Versioning

The npm package follows semver. The CDN file at https://paspo.id/sdk/paspo.min.js always serves the latest compatible 1.x and is cached for one hour.