Authentication

All API requests are scoped to a specific database via an API key. The SDK also provides end-user authentication — sign-up, sign-in, OAuth, and magic links — for apps that need user accounts.

New to the dashboard? Start with the Dashboard setup guide — it explains each UI step and how dashboard login differs from SDK end-user auth.

Keep your API keys secret. Never expose them in client-side code or public repositories. Use a public key (read-only) for browser-side operations.

Key formats

New keys use a predictable prefix so you can tell type and product at a glance (like Stripe):

  • pdb_sk_… — secret key (read/write; server-side only)
  • pdb_pk_… — public key (read-only; safe for browser clients)

Only the key hash is stored. The full string is shown once at creation.

Getting your API key

Create and manage API keys from Dashboard → Databases → API Keys.

  1. Sign up at /signup and open /dashboard
  2. Click New database — copy the API key from the success modal (shown once)
  3. Later: open the database → sidebar API Keys → create, reveal, copy, or revoke keys

Every SDK request includes this key. It scopes all operations — including documents and end-user accounts — to your database.

Initializing the client

import { createClient } from "paperdb-js";

const db = createClient({
  apiKey: process.env.PAPERDB_API_KEY,
  baseUrl: "https://api.paperdb.app", // or your self-hosted URL
});

Email / Password

Create and sign in users with email and password. No extra dashboard configuration required.

// Sign up
const { user, session } = await db.auth.signUp({
  email: "user@example.com",
  password: "securepassword",
  name: "Alice"
});

// Sign in
const { user, session } = await db.auth.signIn({
  email: "user@example.com",
  password: "securepassword"
});

// Sign out
await db.auth.signOut();

// Get current user
const user = await db.auth.getUser();

OAuth (Google, GitHub)

OAuth redirects the browser to the provider. After the callback, the session token is appended to your redirectUrl.

Your app redirects the user to the provider. After sign-in, the user is sent back to your redirectUrl with a session token in the query string. Call setSessionToken(token) to persist the session.

// Redirects to Google — call from a button click
await db.auth.signInWithProvider({
  provider: "google",
  redirectUrl: "https://paperdb.app/auth/callback"
});

// On the callback page, extract the token from the URL
const token = new URLSearchParams(window.location.search).get("token");
if (token) db.auth.setSessionToken(token);

Magic Links

Send a one-time sign-in link to a user's email. The link expires in 15 minutes and can only be used once.

Your callback page extracts email and token from the link URL and calls verifyMagicLink to complete sign-in.

// Send the magic link
await db.auth.sendMagicLink({
  email: "user@example.com",
  redirectUrl: "https://yourapp.com/auth/callback"
});

// On the verify page (token comes from the link URL)
const { user, session } = await db.auth.verifyMagicLink(email, token);

Password Reset

Send a reset link to the user's email. The link is valid for one hour. Use confirmResetPassword with the token from the link to set a new password.

// Request a reset email (link valid for 1 hour)
await db.auth.resetPassword("user@example.com");

// Confirm the reset (token + email come from the reset link URL)
await db.auth.confirmResetPassword(email, token, "newpassword123");

Session Management

// Refresh session (extends expiry)
await db.auth.refreshSession();

// Change password (requires current password)
await db.auth.changePassword("currentpass", "newpass");

// Update profile
await db.auth.updateProfile({ name: "Bob", avatar: "https://..." });

// Listen to auth state changes
const unsubscribe = db.auth.onAuthStateChange((state) => {
  console.log(state.isAuthenticated, state.user);
});

Available API Routes

  • POST /auth/sign-up
  • POST /auth/sign-in
  • POST /auth/sign-out
  • GET /auth/me
  • PATCH /auth/me
  • POST /auth/refresh
  • POST /auth/change-password
  • POST /auth/forgot-password
  • POST /auth/reset-password
  • POST /auth/magic-link
  • POST /auth/magic-link/verify
  • GET /auth/oauth/:provider
  • GET /auth/oauth/:provider/callback

Rate Limits

The API enforces two rate limits, returned as response headers:

  • Per API key: 1,000 requests / minute — X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset
  • Per IP: 200 requests / minute (unauthenticated traffic)

Exceeding either limit returns 429 Too Many Requests with a retryAfter field in the response body.