Skip to main content

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" }
warning

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');
Credits Lost on Deletion

Deleting an API key permanently destroys all remaining credits!

Before deleting a key:

  1. Check remaining balance: await client.getKey('key_abc123')
  2. Consider transferring credits (contact support if needed)
  3. 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.

CreditsPricePer 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โ€‹

ScenarioRecommendation
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:

  1. Create new key
  2. Deploy new key to production
  3. Monitor for errors
  4. 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']
});
Feature Status

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โ€‹

CodeMeaningAction
401Invalid API keyCheck key format
402Credits exhaustedPurchase more credits
429Rate limit hitImplement backoff
500Server errorRetry 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?โ€‹

  1. Check format: Keys start with atv_live_ or atv_test_
  2. Verify header: Must be X-API-Key (case-sensitive)
  3. Check credits: Key may be out of credits
  4. Test endpoint: Try /api/health first

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/batch endpoints
  • Use webhooks instead of polling (when available)