Documentation

Integration Guide

Step-by-step integration with complete code examples for the canonical Bookmer LoginSign OAuth host https://id.bookmer.com.

1. Redirect to Bookmer LoginSign

Send the user to the OAuth authorize URL (see OAuth Flow for the exact URL and parameters). Example link:

<a href="https://id.bookmer.com/oauth/authorize?client_id=YOUR_CLIENT_ID&redirect_uri=https://yourapp.com/callback&response_type=code&scope=openid%20email%20profile&state=random_state">
  Sign in with Bookmer LoginSign
</a>

Keep the Bookmer LoginSign host exactly as shown. Only your registered redirect_uri points to your application.

Marketplace buyers should start at /activate/:appId?code= (or AppSumo Activate) instead of this link. After /activate succeeds, do not add license_code to authorize — the key is already bound. Your own landing page can pass optional license_code on /oauth/authorize. See Marketplace licenses and OAuth Flow.

Important: Start with /oauth/authorize only. Do not start with /login or provider-specific auth routes.

2. Callback: receive the code

After the user signs in and consents, Bookmer LoginSign redirects to your redirect_uri with ?code=...&state=.... Your callback page (or server route) must:

  • Read the code and state from the query string
  • Verify state matches what you sent (CSRF protection)
  • Exchange the code for an access token via POST /oauth/token (see API Reference)

3. Exchange code for token (backend)

// Node.js / Express example: exchange code for access_token
const response = await fetch('https://id.bookmer.com/oauth/token', {
  method: 'POST',
  headers: { 'Content-Type': 'application/x-www-form-urlencoded' },
  body: new URLSearchParams({
    grant_type: 'authorization_code',
    code: codeFromCallback,
    client_id: process.env.LOGINSIGN_CLIENT_ID,
    client_secret: process.env.LOGINSIGN_CLIENT_SECRET,
    redirect_uri: 'https://yourapp.com/callback',
  }),
});
const raw = await response.json();
if (!response.ok) {
  // Log this in production diagnostics. Do not hide behind generic "Sign-in failed".
  console.error('Bookmer LoginSign token exchange failed', response.status, raw);
  throw new Error(raw.error_description || raw.error || 'Token exchange failed');
}
const { access_token } = raw;

Common Failure Patterns

  • User returns to callback with code but login fails: token exchange request differs from authorize request (most often redirect_uri mismatch).
  • invalid_client: wrong client secret or wrong environment credentials.
  • invalid_grant: expired/used code, or redirect URI mismatch between authorize and token request.

4. Get user profile

Use the access token to call the userinfo endpoint:

const userRes = await fetch('https://id.bookmer.com/api/user', {
  headers: { Authorization: `Bearer ${access_token}` },
});
const user = await userRes.json();
// user: { id, globalId, name, email (the address the user chose to share), image }

Important Notes

  • Email is the address the user selected at consent — not a LoginSign alias
  • Register redirect URIs in Console → Settings
  • Use HTTPS in production
  • Verify state on callback and reject mismatches