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?
| Feature | Anonymous | SIWE Authenticated |
|---|---|---|
| Rate Limit | 100 calls/day | 200 calls/day |
| Session | IP-based (public) | Wallet-based (private) |
| API Keys | ❌ Not available | ✅ Generate keys |
| Personalization | ❌ None | ✅ Usage history, favorites |
| Trust Level | Anonymous | Verified 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:
| Tier | Authentication | Daily Limit | Cost |
|---|---|---|---|
| Anonymous | None | 100 | Free |
| SIWE | Wallet signature | 200 | Free |
| API Key | SIWE + generate key | 250 | Free |
| x402 | Wallet signature per request | ∞ | $0.01/call |
See Rate Limits Guide for details.
Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/auth/nonce | Get nonce for SIWE |
POST | /api/auth/verify | Verify SIWE signature |
GET | /api/auth/session | Get current session |
POST | /api/auth/logout | Logout 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
chainIdmatches 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/sessionto check status - Re-authenticate if session is invalid
"Nonce already used"
- Each nonce is single-use
- Request a new nonce for each authentication attempt
Related
- ERC-4361: Sign-In with Ethereum
- SIWE Official Docs
- API Keys Guide — Generate keys after SIWE authentication
- Rate Limits Guide — Understand tier benefits