API Keys
API keys provide traditional authentication with prepaid credits.
Benefitsโ
- 250 calls/day limit
- 30 requests/minute rate
- No crypto wallet needed
- Prepaid credits
Creating a Keyโ
Requires SIWE authentication first:
await client.signIn();
const key = await client.createKey({ name: 'My App' });
// { id: "key_abc123", key: "atv_live_...", name: "My App" }
Save the key immediately โ it's only shown once!
Using a Keyโ
curl -H "X-API-Key: atv_live_..." \
https://api.web3identity.com/api/ens/resolve/vitalik.eth
Managing Keysโ
// List keys
const keys = await client.listKeys();
// Delete key
await client.deleteKey('key_abc123');
Deleting an API key permanently destroys all remaining credits!
Before deleting a key:
- Check remaining balance:
await client.getKey('key_abc123') - Consider transferring credits (contact support if needed)
- Understand this action cannot be undone
If the key has significant credits remaining, consider keeping it inactive rather than deleting.
Creditsโ
Keys require prepaid credits.
| Credits | Price | Per Call |
|---|---|---|
| 100 | $0.90 | $0.009 |
| 250 | $2.00 | $0.008 |
| 1,000 | $7.00 | $0.007 |
| 5,000 | $30.00 | $0.006 |
Purchasing Creditsโ
const purchase = await client.purchaseCredits('key_abc123', 1000);
// Returns payment instructions
Checking Balanceโ
const key = await client.getKey('key_abc123');
console.log(key.credits); // 847
When to Use API Keysโ
| Scenario | Recommendation |
|---|---|
| Backend services | โ API Key |
| Mobile apps | โ API Key |
| High volume | โ API Key |
| Browser apps | โ ๏ธ Use SIWE instead |
| Testing | โ Use free tier |
Security Best Practicesโ
Storageโ
โ Never expose keys in client-side code:
// BAD: Key visible in browser
const API_KEY = 'atv_live_abc123...';
โ Store in environment variables:
// GOOD: Server-side only
const apiKey = process.env.WEB3_IDENTITY_API_KEY;
โ Use secret management:
- AWS Secrets Manager
- HashiCorp Vault
- Environment variables on secure servers
Rate Limitingโ
API keys have dual rate limits:
- 30 requests/minute (per-key)
- 250 calls/day (free tier with key)
Handle 429 errors:
try {
const response = await fetch(url, {
headers: { 'X-API-Key': apiKey }
});
if (response.status === 429) {
const retryAfter = response.headers.get('Retry-After');
console.log(`Rate limited. Retry after ${retryAfter}s`);
// Implement exponential backoff
}
} catch (error) {
console.error('API request failed:', error);
}
Key Rotationโ
Rotate keys periodically for security:
- Create new key
- Deploy new key to production
- Monitor for errors
- Delete old key after 24h
Recommended rotation schedule:
- Production keys: Every 90 days
- Development keys: Every 30 days
- Compromised keys: Immediately
IP Restrictionsโ
Lock keys to known IP ranges when possible:
// Coming Soon: IP allowlists
const key = await client.createKey({
name: 'Production Server',
allowedIPs: ['203.0.113.0/24']
});
IP restrictions are planned for Q2 2026. Currently all keys work from any IP.
Monitoring Usageโ
Check Credits Programmaticallyโ
Set up monitoring to alert before running out:
async function checkCredits(apiKey) {
const key = await client.getKey(apiKey);
if (key.credits < 100) {
console.warn(`โ ๏ธ Low credits: ${key.credits} remaining`);
// Send alert to monitoring system
}
return key.credits;
}
// Check every hour
setInterval(() => checkCredits('key_abc123'), 3600000);
Usage Analyticsโ
Track your API usage in the dashboard:
curl -H "X-API-Key: atv_live_..." \
https://api.web3identity.com/api/usage
Response:
{
"today": 147,
"thisMonth": 3842,
"creditsRemaining": 1158,
"lastRequest": "2026-02-09T16:30:00Z"
}
Error Handlingโ
Common Error Codesโ
| Code | Meaning | Action |
|---|---|---|
401 | Invalid API key | Check key format |
402 | Credits exhausted | Purchase more credits |
429 | Rate limit hit | Implement backoff |
500 | Server error | Retry with backoff |
Retry Logicโ
Implement exponential backoff for transient errors:
async function apiCallWithRetry(url, apiKey, maxRetries = 3) {
let attempt = 0;
while (attempt < maxRetries) {
try {
const response = await fetch(url, {
headers: { 'X-API-Key': apiKey }
});
if (response.ok) return await response.json();
if (response.status === 500 || response.status === 503) {
// Retry server errors
const backoff = Math.pow(2, attempt) * 1000;
console.log(`Retry ${attempt + 1} after ${backoff}ms`);
await new Promise(resolve => setTimeout(resolve, backoff));
attempt++;
continue;
}
// Don't retry client errors
throw new Error(`API error: ${response.status}`);
} catch (error) {
if (attempt === maxRetries - 1) throw error;
attempt++;
}
}
}
Troubleshootingโ
Key Not Working?โ
- Check format: Keys start with
atv_live_oratv_test_ - Verify header: Must be
X-API-Key(case-sensitive) - Check credits: Key may be out of credits
- Test endpoint: Try
/api/healthfirst
Credits Not Deducting?โ
Free endpoints don't consume credits:
/api/health/api/usage/api/keys/*- Authentication endpoints
High Credit Usage?โ
Optimize your requests:
- Cache responses when data doesn't change frequently
- Batch requests using
/api/price/batchendpoints - Use webhooks instead of polling (when available)