Skip to main content

Authentication

amser uses three distinct authentication mechanisms depending on context: SIWE for the dashboard, API keys for server-side requests, and a combination of wallet auth plus the amser API for gating access in your own application.

Part 1 — Dashboard authentication (SIWE)

SIWE (Sign-In With Ethereum) replaces traditional username-and-password authentication with a wallet signature. Instead of transmitting a secret, the user signs a structured message with their wallet, proving ownership of an Ethereum address without exposing the private key. This is the only authentication method for the amser dashboard.

How the flow works

  1. Connect wallet — the user connects via MetaMask, WalletConnect, Coinbase Wallet, or any injected provider.
  2. Request nonce — amser calls GET /v0/auth/nonce to obtain a one-time challenge.
  3. Construct message — amser builds a SIWE message (ERC-4361) using that nonce.
  4. Sign — the user signs the message in their wallet. No transaction is submitted and no gas is spent.
  5. Verify — amser sends the signature to POST /v0/auth/verify, which validates it and sets an HttpOnly session cookie (sid).
  6. Session established — the session is bound to the wallet address. Switching wallets requires re-authentication.

SIWE message format

The message the user sees in their wallet follows the ERC-4361 structure:

amser wants you to sign in with your Ethereum account:
0xYourAddressHere

Sign in to amser

URI: https://app.amser.io
Version: 1
Chain ID: 8453
Nonce: <random>
Issued At: 2026-01-01T00:00:00.000Z

Session properties

  • Expires after 15 minutes of inactivity (automatically refreshed on activity)
  • Invalidated on explicit logout (POST /v0/auth/logout)
  • Scoped to the authenticated wallet address — the dashboard only shows data for that merchant

Part 2 — API authentication (API keys)

The dashboard uses SIWE because it runs in a browser where the user can sign messages interactively. Server-side integrations cannot prompt a wallet, so they use API keys instead.

API keys are read-only — they work for GET requests only. Write operations (creating webhooks, revoking keys) require a SIWE session through the dashboard.

To authenticate a server-side request, include the key in the Authorization header:

Authorization: Bearer amsr_live_xxxxxxxxxxxxx

Generate and manage API keys from the dashboard under Settings → API Keys. See the API Keys page for the full reference.

Part 3 — On-chain gating (SIWE + subscription check)

If you are building a subscription-gated application, the recommended pattern combines wallet-based authentication with the amser API to check subscription status at login time.

The pattern

  1. The user authenticates to your app using any wallet-based auth mechanism (SIWE, RainbowKit, ConnectKit, etc.).
  2. Your server calls GET /v0/auth/check with the user's wallet address and plan ID.
  3. If authorized: true, you issue a session that includes subscription claims.
  4. Subsequent requests are authorized via your own session — you do not re-check the amser API on every request.
async function loginUser(walletAddress: string): Promise<Session> {
// 1. Verify the user's wallet signature (your existing auth layer)

// 2. Check subscription status via amser API — no on-chain call needed
const params = new URLSearchParams({
module_address: MODULE_ADDRESS,
wallet: walletAddress,
plan_ids: PLAN_ID,
});

const res = await fetch(
`https://api.amser.io/v0/auth/check?${params}`,
{ headers: { 'Authorization': `Bearer ${process.env.AMSER_API_KEY}` } }
);

const { authorized } = await res.json();

// 3. Issue session with subscription claim
return createSession({
address: walletAddress,
subscribed: authorized,
// Keep session shorter than your grace period so lapsed subscriptions
// can't maintain access indefinitely via a stale session
expiresAt: Date.now() + 60 * 60 * 1000, // 1 hour
});
}

Session expiry considerations

If a subscription lapses mid-session, the user retains access until their session expires. Set the session duration to match your acceptable lag — shorter sessions are more accurate but require more frequent re-checks. As a rule of thumb, keep session lifetime well below your plan's grace period so that a lapsed subscriber cannot ride a stale session through the entire grace window.

Next steps