JavaScript Examples
Authentication
Using Personal Access Token (Recommended for Development)
const TradingCardAPI = require('trading-card-api');
// Initialize with Personal Access Token
const client = new TradingCardAPI({
personalAccessToken: process.env.TRADING_CARD_API_PAT,
baseUrl: 'https://api.tradingcardapi.com'
});
// No additional authentication steps required!
// The token is automatically included in all requests
Using OAuth 2.0 Client Credentials (Recommended for Production)
const TradingCardAPI = require('trading-card-api');
// Initialize with OAuth credentials
const client = new TradingCardAPI({
clientId: process.env.TRADING_CARD_API_CLIENT_ID,
clientSecret: process.env.TRADING_CARD_API_CLIENT_SECRET,
baseUrl: 'https://api.tradingcardapi.com'
});
// Client handles OAuth token flow automatically
Basic Usage
const TradingCardAPI = require('trading-card-api');
const client = new TradingCardAPI({
clientId: 'your_client_id',
clientSecret: 'your_client_secret',
baseUrl: 'https://api.tradingcardapi.com'
});
// Get cards
const cards = await client.cards.list({
'page[limit]': 25,
'filter[year]': 2023
});
cards.data.forEach(card => {
console.log(card.attributes.name);
});
Advanced Filtering
// Search with multiple filters
const results = await client.cards.list({
'filter[year]': 1989,
'filter[name]': '*Griffey*',
'include': 'set,oncard',
'sort': 'name',
'page[limit]': 50
});
Cards
Fetch Card with Image Reference
// Get a card and check for image_uuid
const cardId = '550e8400-e29b-41d4-a716-446655440000';
try {
const response = await client.cards.get(cardId);
const card = response.data;
console.log(`Card: ${card.attributes.name}`);
console.log(`Number: ${card.attributes.number}`);
// Check if card has an image reference (v0.6.0+)
if (card.attributes.image_uuid) {
console.log(`Image UUID: ${card.attributes.image_uuid}`);
} else {
console.log('No image uploaded yet');
}
} catch (error) {
console.error('Error:', error.message);
}
Include Card Images in Response
// Fetch card with related images included (v0.7.0+)
const cardId = '550e8400-e29b-41d4-a716-446655440000';
try {
const response = await client.cards.get(cardId, {
'include': 'images'
});
const card = response.data;
console.log(`Card: ${card.attributes.name}`);
// Access included images
if (response.included) {
response.included.forEach(included => {
if (included.type === 'card_images') {
console.log(`Image: ${included.attributes.side}`);
console.log(`URL: ${included.attributes.image_url}`);
}
});
}
} catch (error) {
console.error('Error:', error.message);
}
List Cards with Images
// List cards and include their images
const results = await client.cards.list({
'filter[set_id]': '550e8400-e29b-41d4-a716-446655440000',
'include': 'images,set',
'page[limit]': 25
});
results.data.forEach(card => {
const hasImage = card.attributes.image_uuid ? ' [Has Image]' : '';
console.log(`${card.attributes.number} - ${card.attributes.name}${hasImage}`);
});
// Process included images
if (results.included) {
const images = results.included.filter(item => item.type === 'card_images');
console.log(`\nTotal images included: ${images.length}`);
}
File Uploads
Upload Card Image
const fs = require('fs');
const FormData = require('form-data');
// Upload a card image with basic validation
const imagePath = '/path/to/card-front.jpg';
// Validate file exists
if (!fs.existsSync(imagePath)) {
throw new Error(`Image file not found: ${imagePath}`);
}
// Check file size
const stats = fs.statSync(imagePath);
const maxSize = 10 * 1024 * 1024; // 10MB
if (stats.size > maxSize) {
throw new Error('Image too large. Maximum size: 10MB');
}
try {
const form = new FormData();
form.append('file', fs.createReadStream(imagePath));
form.append('data', JSON.stringify({
type: 'card_images',
attributes: {
card_id: '550e8400-e29b-41d4-a716-446655440000',
image_type: 'front'
}
}));
const response = await client.cardImages.create(form);
console.log('Image uploaded successfully!');
console.log('Image ID:', response.data.id);
console.log('Small URL:', response.data.attributes.variants.small.url);
console.log('Medium URL:', response.data.attributes.variants.medium.url);
console.log('Large URL:', response.data.attributes.variants.large.url);
const imageId = response.data.id;
} catch (error) {
console.error('Upload failed:', error.message);
throw error;
}
Upload with Progress Tracking
const fs = require('fs');
const axios = require('axios');
const FormData = require('form-data');
async function uploadWithProgress(imagePath, cardId) {
const form = new FormData();
form.append('file', fs.createReadStream(imagePath));
form.append('data', JSON.stringify({
type: 'card_images',
attributes: {
card_id: cardId,
image_type: 'front'
}
}));
const response = await axios.post(
'https://api.tradingcardapi.com/v1/card-images',
form,
{
headers: {
...form.getHeaders(),
'Authorization': `Bearer ${client.accessToken}`
},
onUploadProgress: (progressEvent) => {
const percentCompleted = Math.round(
(progressEvent.loaded * 100) / progressEvent.total
);
console.log(`Upload progress: ${percentCompleted}%`);
}
}
);
return response.data;
}
// Usage
const result = await uploadWithProgress('/path/to/card.jpg', '550e8400-e29b-41d4-a716-446655440000');
console.log('Upload complete:', result.data.id);
List Card Images
// List all images for a specific card
const cardId = '550e8400-e29b-41d4-a716-446655440000';
const images = await client.cardImages.list({
'filter[card_id]': cardId
});
images.data.forEach(image => {
console.log('Image ID:', image.id);
console.log('Type:', image.attributes.image_type);
console.log('Small URL:', image.attributes.variants.small.url);
console.log('---');
});
Download Card Image
// Download specific size variant
const imageId = '01234567-89ab-cdef-0123-456789abcdef';
const imageUrl = `https://api.tradingcardapi.com/v1/card-images/${imageId}/download?size=medium`;
try {
const imageResponse = await fetch(imageUrl, {
headers: {
'Authorization': `Bearer ${client.accessToken}`
},
redirect: 'follow' // Follow CDN redirects
});
if (imageResponse.ok) {
const imageBuffer = await imageResponse.arrayBuffer();
fs.writeFileSync('card-image.jpg', Buffer.from(imageBuffer));
console.log('Image downloaded successfully');
} else {
console.error(`Download failed with status: ${imageResponse.status}`);
}
} catch (error) {
console.error('Download error:', error.message);
}
Update Image Metadata
// Update image metadata (e.g., change from front to back)
const imageId = '01234567-89ab-cdef-0123-456789abcdef';
try {
const response = await client.cardImages.update(imageId, {
type: 'card_images',
id: imageId,
attributes: {
image_type: 'back'
}
});
console.log('Image metadata updated successfully');
console.log('New type:', response.data.attributes.image_type);
} catch (error) {
console.error('Update failed:', error.message);
}
Delete Card Image
// Delete a card image
const imageId = '01234567-89ab-cdef-0123-456789abcdef';
try {
await client.cardImages.delete(imageId);
console.log('Image deleted successfully');
} catch (error) {
console.error('Deletion failed:', error.message);
}
Responsive Images with Versioned CDN URLs
// Fetch image with versioned CDN URLs
const imageResponse = await client.cardImages.get(imageId);
const attrs = imageResponse.data.attributes;
// All URLs include version parameter (?v=timestamp) for automatic cache invalidation
const smallUrl = attrs.variants.small.url;
const mediumUrl = attrs.variants.medium.url;
const largeUrl = attrs.variants.large.url;
// Generate responsive image HTML
const imgHtml = `
<img
src="${smallUrl}"
srcset="
${smallUrl} 150w,
${mediumUrl} 300w,
${largeUrl} 600w
"
sizes="(max-width: 640px) 150px, 300px"
alt="Card image"
loading="lazy"
/>
`;
// Or in React
function CardImage({ imageId }) {
const [image, setImage] = React.useState(null);
React.useEffect(() => {
client.cardImages.get(imageId).then(response => {
setImage(response.data.attributes);
});
}, [imageId]);
if (!image) return <div>Loading...</div>;
return (
<img
src={image.variants.small.url}
srcSet={`
${image.variants.small.url} 150w,
${image.variants.medium.url} 300w,
${image.variants.large.url} 600w
`}
sizes="(max-width: 640px) 150px, 300px"
alt="Card image"
loading="lazy"
/>
);
}
Set Sources
Create Set Source
// Add a checklist source to a set
const setId = '550e8400-e29b-41d4-a716-446655440000';
try {
const response = await client.setSources.create({
type: 'set_sources',
attributes: {
set_id: setId,
source_type: 'checklist',
source_name: 'Beckett Online Price Guide',
source_url: 'https://www.beckett.com/price-guides'
}
});
console.log('Source created successfully!');
console.log('Source ID:', response.data.id);
console.log('Type:', response.data.attributes.source_type);
console.log('Name:', response.data.attributes.source_name);
} catch (error) {
console.error('Failed to create source:', error.message);
}
List Sources for a Set
// Get all sources for a specific set
const setId = '550e8400-e29b-41d4-a716-446655440000';
const sources = await client.setSources.list({
'filter[set_id]': setId
});
console.log(`Found ${sources.data.length} sources\n`);
sources.data.forEach(source => {
console.log('Source Type:', source.attributes.source_type);
console.log('Name:', source.attributes.source_name);
console.log('URL:', source.attributes.source_url);
if (source.attributes.verified_at) {
console.log('Verified:', source.attributes.verified_at);
}
console.log('---');
});
Get Set with Sources Included
// Fetch a set with all its sources using include parameter
const setId = '550e8400-e29b-41d4-a716-446655440000';
const response = await client.sets.get(setId, {
include: 'sources'
});
const set = response.data;
console.log('Set:', set.attributes.name);
console.log('Year:', set.attributes.year);
console.log('');
// Sources are in the included array
if (response.included) {
console.log('Data Sources:');
response.included
.filter(item => item.type === 'set_sources')
.forEach(source => {
console.log(`- ${source.attributes.source_type}: ${source.attributes.source_name}`);
});
}
Update Source Verification
// Update a source to mark it as verified
const sourceId = '01234567-89ab-cdef-0123-456789abcdef';
try {
const response = await client.setSources.update(sourceId, {
type: 'set_sources',
id: sourceId,
attributes: {
verified_at: new Date().toISOString()
}
});
console.log('Source verified at:', response.data.attributes.verified_at);
} catch (error) {
console.error('Verification failed:', error.message);
}
Delete Set Source
// Remove a source from a set
const sourceId = '01234567-89ab-cdef-0123-456789abcdef';
try {
await client.setSources.delete(sourceId);
console.log('Source deleted successfully');
} catch (error) {
console.error('Deletion failed:', error.message);
}
Track Multiple Source Types
// Add multiple sources for different data types
const setId = '550e8400-e29b-41d4-a716-446655440000';
const sourceTypes = [
{
type: 'checklist',
name: 'COMC Database',
url: 'https://www.comc.com'
},
{
type: 'metadata',
name: 'CardboardConnection',
url: 'https://www.cardboardconnection.com'
},
{
type: 'images',
name: 'Trading Card Database',
url: 'https://www.tradingcarddb.com'
}
];
for (const sourceInfo of sourceTypes) {
try {
const response = await client.setSources.create({
type: 'set_sources',
attributes: {
set_id: setId,
source_type: sourceInfo.type,
source_name: sourceInfo.name,
source_url: sourceInfo.url
}
});
console.log(`Added ${sourceInfo.type} source: ${sourceInfo.name}`);
} catch (error) {
console.error(`Failed to add ${sourceInfo.type} source:`, error.message);
}
}
v2 Endpoints
Get Set Checklist (v2)
// v2 endpoint returns cards as primary data (correct JSON:API semantics)
const setId = '550e8400-e29b-41d4-a716-446655440000';
try {
const response = await client.get(`/v2/sets/${setId}/checklist`);
const cards = response.data;
const set = response.included?.[0];
cards.forEach(card => {
console.log(`Card #${card.attributes.number}: ${card.attributes.name}`);
});
} catch (error) {
console.error('Error:', error.message);
}
Compact Format for Large Sets
// Use compact format to reduce response size by ~75%
const setId = '550e8400-e29b-41d4-a716-446655440000';
try {
const response = await client.get(`/v2/sets/${setId}/checklist`, {
format: 'compact'
});
response.data.forEach(card => {
const { number, name } = card.attributes;
console.log(`#${number.padEnd(4)} ${name}`);
});
} catch (error) {
console.error('Error:', error.message);
}