Pokemon API Integration Guide
Complete guide to integrating Pokemon card API into your applications. Learn authentication, error handling, rate limiting, and best practices with ready-to-use Pokemon API integration examples.
Integration Steps
1Authentication & API Key Setup
First, obtain your API key and set up authentication in your application:
// Store your API key securely
const API_KEY = process.env.POKEMON_API_KEY;
const BASE_URL = 'https://www.pokemonpricetracker.com/api';
// Create reusable headers
const headers = {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
'User-Agent': 'YourApp/1.0'
};
// Example API call
const response = await fetch(`${BASE_URL}/cards?name=charizard`, {
headers: headers
});
if (!response.ok) {
throw new Error(`HTTP error! status: ${response.status}`);
}
const data = await response.json();2Error Handling & Rate Limiting
Implement robust error handling and respect rate limits:
// JavaScript example with comprehensive error handling
class PokemonAPI {
constructor(apiKey) {
this.apiKey = apiKey;
this.baseUrl = 'https://www.pokemonpricetracker.com/api';
this.rateLimitRemaining = null;
this.rateLimitReset = null;
}
async makeRequest(endpoint, options = {}) {
const url = `${this.baseUrl}${endpoint}`;
try {
const response = await fetch(url, {
...options,
headers: {
'Authorization': `Bearer ${this.apiKey}`,
'Content-Type': 'application/json',
...options.headers
}
});
// Update rate limit info
this.rateLimitRemaining = response.headers.get('X-RateLimit-Remaining');
this.rateLimitReset = response.headers.get('X-RateLimit-Reset');
// Handle different HTTP status codes
switch (response.status) {
case 200:
return await response.json();
case 401:
throw new Error('Invalid API key. Please check your credentials.');
case 429:
const resetTime = new Date(this.rateLimitReset * 1000);
throw new Error(`Rate limit exceeded. Try again at ${resetTime}`);
case 404:
throw new Error('Resource not found. Check your request parameters.');
case 500:
throw new Error('Server error. Please try again later.');
default:
throw new Error(`Unexpected error: ${response.status} ${response.statusText}`);
}
} catch (error) {
if (error.name === 'TypeError') {
throw new Error('Network error. Please check your internet connection.');
}
throw error;
}
}
// Check rate limit before making requests
canMakeRequest() {
if (this.rateLimitRemaining === null) return true;
return parseInt(this.rateLimitRemaining) > 0;
}
// Get time until rate limit resets
timeUntilReset() {
if (!this.rateLimitReset) return 0;
return Math.max(0, (this.rateLimitReset * 1000) - Date.now());
}
}Rate Limits: Free tier: 100 requests/day, Standard: 20,000/day, Business: 200,000/day
3Data Parsing & Processing
Parse and process API responses effectively:
// Example response structure and parsing
const parseCardData = (apiResponse) => {
const { cards, pagination } = apiResponse;
return cards.map(card => ({
id: card.id,
name: card.name,
set: {
name: card.set?.name,
id: card.set?.id,
releaseDate: card.set?.releaseDate
},
prices: {
market: card.prices?.tcgplayer?.market || null,
low: card.prices?.tcgplayer?.low || null,
high: card.prices?.tcgplayer?.high || null,
average: card.prices?.average || null,
trend: calculateTrend(card.priceHistory)
},
gradedPrices: {
psa10: card.gradedPrices?.psa10 || null,
psa9: card.gradedPrices?.psa9 || null,
bgs10: card.gradedPrices?.bgs10 || null
},
rarity: card.rarity,
image: card.images?.large || card.images?.small,
lastUpdated: new Date(card.lastUpdated)
}));
};
// Helper function to calculate price trend
const calculateTrend = (priceHistory) => {
if (!priceHistory || priceHistory.length < 2) return 'stable';
const recent = priceHistory.slice(-7); // Last 7 data points
const older = priceHistory.slice(-14, -7); // Previous 7 data points
const recentAvg = recent.reduce((sum, p) => sum + p.price, 0) / recent.length;
const olderAvg = older.reduce((sum, p) => sum + p.price, 0) / older.length;
const change = (recentAvg - olderAvg) / olderAvg;
if (change > 0.05) return 'increasing';
if (change < -0.05) return 'decreasing';
return 'stable';
};Common Integration Patterns
Data Caching Strategy
Implement caching to reduce API calls and improve performance:
// Redis caching example
const redis = require('redis');
const client = redis.createClient();
class CachedPokemonAPI {
constructor(apiKey) {
this.api = new PokemonAPI(apiKey);
this.cacheExpiry = 3600; // 1 hour
}
async getCard(cardId) {
const cacheKey = `card:${cardId}`;
// Try cache first
let cached = await client.get(cacheKey);
if (cached) {
return JSON.parse(cached);
}
// Fetch from API
const card = await this.api.getCard(cardId);
// Cache result
await client.setex(
cacheKey,
this.cacheExpiry,
JSON.stringify(card)
);
return card;
}
}- • Cache frequently accessed data
- • Set appropriate TTL values
- • Handle cache misses gracefully
Security Best Practices
Keep your API integration secure:
// Environment variable usage
const config = {
apiKey: process.env.POKEMON_API_KEY,
apiUrl: process.env.POKEMON_API_URL,
timeout: parseInt(process.env.API_TIMEOUT) || 30000
};
// Validate API key format
const validateApiKey = (key) => {
if (!key || typeof key !== 'string') {
throw new Error('Invalid API key format');
}
if (key.length !== 32) {
throw new Error('API key must be 32 characters');
}
return key;
};
// Secure headers
const secureHeaders = {
'Authorization': `Bearer ${validateApiKey(config.apiKey)}`,
'User-Agent': 'YourApp/1.0',
'Accept': 'application/json'
};- • Store API keys in environment variables
- • Never commit keys to version control
- • Validate input parameters
- • Use HTTPS for all requests
Framework-Specific Examples
React Hook for Pokemon API
import { useState, useEffect } from 'react';
const usePokemonCard = (cardId) => {
const [card, setCard] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
useEffect(() => {
if (!cardId) return;
const fetchCard = async () => {
try {
setLoading(true);
const response = await fetch(
`https://www.pokemonpricetracker.com/api/cards/${cardId}`,
{
headers: {
'Authorization': `Bearer ${process.env.REACT_APP_POKEMON_API_KEY}`
}
}
);
if (!response.ok) throw new Error('Failed to fetch card');
const data = await response.json();
setCard(data);
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
};
fetchCard();
}, [cardId]);
return { card, loading, error };
};
// Usage in component
const CardDisplay = ({ cardId }) => {
const { card, loading, error } = usePokemonCard(cardId);
if (loading) return <div>Loading...</div>;
if (error) return <div>Error: {error}</div>;
if (!card) return <div>No card found</div>;
return (
<div className="card">
<img src={card.images.large} alt={card.name} />
<h3>{card.name}</h3>
<p>Price: ${card.prices.market}</p>
</div>
);
};Integration Best Practices
✅ Do
- Implement proper error handling for all HTTP status codes
- Cache API responses to reduce unnecessary requests
- Use environment variables for API keys and sensitive data
- Implement retry logic with exponential backoff
- Monitor your API usage and rate limits
- Validate and sanitize all input parameters
❌ Don't
- Hard-code API keys in your source code
- Make API requests without proper error handling
- Exceed rate limits - implement proper throttling
- Cache data for too long - respect data freshness
- Ignore API response headers and metadata
- Make synchronous requests that block your application