Understanding Responses
Learn about the SDK's response structure and data transformation features.
Response Structure
All successful method calls from the client return a consistent JustTCGApiResponse object. This provides a predictable structure for handling API responses.
interface JustTCGApiResponse<T> {
/** The main data payload from the API */
data: T;
/** Pagination metadata (only on paginated endpoints) */
pagination?: {
total: number;
limit: number;
offset: number;
hasMore: boolean;
};
/** API usage metadata (included in every response) */
usage: {
apiRequestLimit: number;
apiDailyLimit: number;
apiRateLimit: number;
apiRequestsUsed: number;
apiDailyRequestsUsed: number;
apiRequestsRemaining: number;
apiDailyRequestsRemaining: number;
apiPlan: string;
};
/** Error message (if API returns an error) */
error?: string;
code?: string;
}
Type Safety: The
T generic parameter ensures that response.datais fully typed based on the method you're calling.Card Object Structure
The SDK provides clean, typed interfaces for all data structures. Here's the Card object structure:
interface Card {
/** The unique identifier for the card */
id: string;
/** The name of the card */
name: string;
/** The game this card belongs to */
game: string;
/** The set ID this card belongs to */
set: string;
/** The set name this card belongs to */
set_name: string;
/** The card number within the set */
number: string | null;
/** The rarity of the card */
rarity: string | null;
/** The TCGPlayer ID for the card */
tcgplayerId: string | null;
/** The MTGJSON ID for the card */
mtgjsonId: string | null;
/** The Scryfall ID for the card */
scryfallId: string | null;
/** Additional details about the card */
details?: string | null;
/** The different variants of the card */
variants: Variant[];
}
Variant Object Structure
Each card contains an array of variants with detailed pricing information:
interface Variant {
/** The unique identifier for this variant. */
id: string;
/** The condition of the card variant (e.g., Near Mint). */
condition: string;
/** The printing type of the card variant (e.g., Foil, 1st Edition). */
printing: string;
/** The language of the card variant, if applicable. */
language: string | null;
/** The TCGPlayer SKU ID for the card variant. */
tcgplayerSkuId: string | null;
/** The current price of the card variant in dollars. */
price: number;
/** The last time the price was updated, as an epoch timestamp in seconds. */
lastUpdated: number; // Epoch seconds
/** The percentage change in price over the last 24 hours. */
priceChange24hr?: number | null; // Percentage
// --- 7d stats ---
/** The percentage change in price over the last 7 days. */
priceChange7d?: number | null; // Percentage
/** The average price over the last 7 days. */
avgPrice?: number | null; // Dollars
/** The price history entries over the last 7 days. */
priceHistory?: PriceHistoryEntry[] | null;
minPrice7d?: number | null; // Dollars
maxPrice7d?: number | null; // Dollars
stddevPopPrice7d?: number | null;
covPrice7d?: number | null;
iqrPrice7d?: number | null;
trendSlope7d?: number | null;
priceChangesCount7d?: number | null;
// --- 30d stats ---
priceChange30d?: number | null; // Percentage
avgPrice30d?: number | null; // Dollars
minPrice30d?: number | null; // Dollars
maxPrice30d?: number | null; // Dollars
priceHistory30d?: PriceHistoryEntry[] | null;
stddevPopPrice30d?: number | null;
covPrice30d?: number | null;
iqrPrice30d?: number | null;
trendSlope30d?: number | null;
priceChangesCount30d?: number | null;
priceRelativeTo30dRange?: number | null;
// --- 90d stats ---
priceChange90d?: number | null; // Percentage
avgPrice90d?: number | null; // Dollars
minPrice90d?: number | null; // Dollars
maxPrice90d?: number | null; // Dollars
stddevPopPrice90d?: number | null;
covPrice90d?: number | null;
iqrPrice90d?: number | null;
trendSlope90d?: number | null;
priceChangesCount90d?: number | null;
priceRelativeTo90dRange?: number | null;
// --- 1y stats ---
minPrice1y?: number | null;
maxPrice1y?: number | null;
// --- All-time stats ---
minPriceAllTime?: number | null;
minPriceAllTimeDate?: string | null;
maxPriceAllTime?: number | null;
maxPriceAllTimeDate?: string | null;
}
Price History Structure
Price history is provided as an array of timestamped price points:
interface PriceHistoryEntry {
/** Epoch timestamp in seconds */
t: number;
/** Price in dollars */
p: number;
}
Example Usage
const response = await client.v1.cards.get({ cardId: 'some-card-id' });
const card = response.data[0];
const variant = card.variants[0];
if (variant.priceHistory) {
// Convert timestamps to dates and plot price history
const pricePoints = variant.priceHistory.map(entry => ({
date: new Date(entry.t * 1000),
price: entry.p
}));
console.log('Price history:', pricePoints);
}
Pagination
Paginated endpoints include pagination metadata in the response:
interface PaginationInfo {
/** Total number of results available */
total: number;
/** Number of results per page */
limit: number;
/** Number of results skipped */
offset: number;
/** Whether there are more results available */
hasMore: boolean;
}
Example Pagination Usage
const response = await client.v1.cards.get({
game: 'Pokemon',
limit: 20,
offset: 0
});
console.log('Results:', response.data.length);
console.log('Total available:', response.pagination?.total);
console.log('Has more:', response.pagination?.hasMore);
// Load next page
if (response.pagination?.hasMore) {
const nextPage = await client.v1.cards.get({
game: 'Pokemon',
limit: 20,
offset: 20
});
}
Usage Metadata
Every response includes usage metadata to help you monitor your API consumption:
interface UsageInfo {
/** Your total request limit */
apiRequestLimit: number;
/** Your daily request limit */
apiDailyLimit: number;
/** Your rate limit (requests per minute) */
apiRateLimit: number;
/** Requests used in this call */
apiRequestsUsed: number;
/** Daily requests used */
apiDailyRequestsUsed: number;
/** Requests remaining in this call */
apiRequestsRemaining: number;
/** Daily requests remaining */
apiDailyRequestsRemaining: number;
/** Your current plan */
apiPlan: string;
}
Example Usage Monitoring
const response = await client.v1.games.list();
console.log('API Plan:', response.usage.apiPlan);
console.log('Daily requests used:', response.usage.apiDailyRequestsUsed);
console.log('Daily requests remaining:', response.usage.apiDailyRequestsRemaining);
// Check if approaching limits
const usagePercentage = (response.usage.apiDailyRequestsUsed / response.usage.apiDailyLimit) * 100;
if (usagePercentage > 80) {
console.warn('Approaching daily limit!');
}
Next Steps
Now that you understand response structure, you can: