Skip to main content

Auth API

Authenticate with your Ethereum wallet using Sign-In with Ethereum (SIWE) to unlock higher rate limits and personalized features.

Overview

The Auth API implements ERC-4361 (Sign-In with Ethereum), allowing you to prove wallet ownership without sharing private keys or creating accounts.

Why use SIWE authentication?

FeatureAnonymousSIWE Authenticated
Rate Limit100 calls/day200 calls/day
SessionIP-based (public)Wallet-based (private)
API Keys❌ Not available✅ Generate keys
Personalization❌ None✅ Usage history, favorites
Trust LevelAnonymousVerified wallet owner

How SIWE Works

1. Client requests nonce       → GET /api/auth/nonce
2. Client signs SIWE message → EIP-191 signature with wallet
3. Client sends signature → POST /api/auth/verify
4. Server verifies & creates session → Returns session cookie
5. Subsequent requests include session → Higher rate limits applied

Security: Your private key never leaves your wallet. The signature proves ownership without revealing secrets.

Authentication Flow

Step 1: Get a Nonce

curl -X POST "https://api.web3identity.com/api/auth/nonce" \
-H "Content-Type: application/json" \
-d '{"address": "0x701B4937e6c943789ffA74CC8601813b2D87B454"}'

Response:

{
"nonce": "abc123...",
"message": "api.web3identity.com wants you to sign in with your Ethereum account:\n0x701B4937e6c943789ffA74CC8601813b2D87B454\n\nSign in to access the Web3 Identity API\n\nURI: https://api.web3identity.com\nVersion: 1\nChain ID: 1\nNonce: abc123...\nIssued At: 2024-02-10T14:00:00.000Z",
"expiresIn": 300,
"domain": "api.web3identity.com",
"uri": "https://api.web3identity.com",
"statement": "Sign in to access the Web3 Identity API",
"chainId": 1,
"version": "1",
"issuedAt": "2024-02-10T14:00:00.000Z",
"timestamp": "2024-02-10T14:00:00.000Z"
}

Step 2: Sign the Message

Use your wallet to sign an EIP-191 message:

import { SiweMessage } from 'siwe';

const message = new SiweMessage({
domain: 'api.web3identity.com',
address: '0xYourAddress',
statement: 'Sign in to Web3 Identity API',
uri: 'https://api.web3identity.com',
version: '1',
chainId: 1,
nonce: 'abc123...', // from Step 1
});

const signature = await wallet.signMessage(message.prepareMessage());

Step 3: Verify the Signature

curl -X POST "https://api.web3identity.com/api/auth/verify" \
-H "Content-Type: application/json" \
-d '{
"message": "api.web3identity.com wants you to sign in...",
"signature": "0x..."
}'

Response:

{
"success": true,
"address": "0xYourAddress",
"sessionId": "session_...",
"expiresAt": "2026-02-17T14:00:00Z"
}

Step 4: Use Your Session

The server sets a session cookie. Subsequent requests automatically include higher rate limits:

curl "https://api.web3identity.com/api/prices/ethereum" \
--cookie "session=..." # Auto-included by browser

Check your session status:

curl "https://api.web3identity.com/api/auth/session"

Step 5: Logout

curl -X POST "https://api.web3identity.com/api/auth/logout"

Rate Limit Tiers

Authentication unlocks progressively higher rate limits:

TierAuthenticationDaily LimitCost
AnonymousNone100Free
SIWEWallet signature200Free
API KeySIWE + generate key250Free
x402Wallet signature per request$0.01/call

See Rate Limits Guide for details.

Endpoints

MethodPathDescription
POST/api/auth/nonceGet nonce for SIWE
POST/api/auth/verifyVerify SIWE signature
GET/api/auth/sessionGet current session
POST/api/auth/logoutLogout and invalidate session

Client Libraries

JavaScript/TypeScript

npm install siwe ethers
import { SiweMessage } from 'siwe';
import { ethers } from 'ethers';

// 1. Get nonce
const nonceRes = await fetch('https://api.web3identity.com/api/auth/nonce', {
method: 'POST'
});
const { nonce } = await nonceRes.json();

// 2. Create SIWE message
const message = new SiweMessage({
domain: 'api.web3identity.com',
address: await signer.getAddress(),
statement: 'Sign in to Web3 Identity API',
uri: 'https://api.web3identity.com',
version: '1',
chainId: 1,
nonce,
});

// 3. Sign message
const signature = await signer.signMessage(message.prepareMessage());

// 4. Verify with server
const verifyRes = await fetch('https://api.web3identity.com/api/auth/verify', {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
message: message.prepareMessage(),
signature,
}),
credentials: 'include', // Important: include cookies
});

const { success, address } = await verifyRes.json();
console.log(`Authenticated as $\{address\}`);

Security Notes

  • Nonces expire in 5 minutes — Request a new nonce if verification fails
  • Sessions last 7 days — Automatically refreshed with each request
  • One session per address — New login invalidates previous session
  • Signatures are single-use — Each signature tied to a unique nonce
  • No private keys transmitted — EIP-191 signatures prove ownership without revealing keys

Common Issues

"Invalid signature"

  • Ensure the message format exactly matches SIWE spec
  • Check that chainId matches the wallet's active network
  • Verify the nonce hasn't expired (5min limit)

"Session expired"

  • Sessions last 7 days with automatic refresh
  • Call /api/auth/session to check status
  • Re-authenticate if session is invalid

"Nonce already used"

  • Each nonce is single-use
  • Request a new nonce for each authentication attempt