Skip to main content

JavaScript Examples

Authentication

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
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);
}