Grade a Pokémon Card (CollectorScan)
This recipe grades a Pokémon Base Set Charizard using the PSA 10-point scale — from catalog lookup to final PSA-style report.
What you will build
A collector grading workflow that identifies the card in the registry, submits front and back photos, triggers AI grading across the four PSA attributes, and delivers a final human-reviewed grade.
1. Set up the client
import { KliqClient } from '@kliq-ai/sdk';
const kliq = new KliqClient({ apiKey: process.env.KLIQ_API_KEY! });
const tenant = kliq.forTenant('t_abc123');
2. Find the card in the catalog
// Search by name or look up directly by slug
const card = await kliq.catalog.items.get('pkmn-base-charizard-holo-4');
console.log(card.name);
// "Charizard Holo #4"
console.log(card.attributes);
// { setNumber: '4/102', rarity: 'Holo Rare', type: 'Fire' }
console.log(card.type.gradingSchemaSlug);
// "psa-10-point"
3. Create the inspection
const inspection = await tenant.inspections.create({
catalogItemSlug: card.slug,
gradingSchemaSlug: card.type.gradingSchemaSlug,
notes: '1st Edition shadowless. Owner: Jane Smith.',
metadata: { owner: 'jane.smith', lotRef: 'LOT-2026-001' },
});
console.log(inspection.id); // "insp_bbb222"
4. Upload photos
PSA requires at minimum a front and back scan. Additional angle photos (corners, edges) improve AI accuracy.
const photoAngles = [
{ file: frontImageFile, angle: 'front' },
{ file: backImageFile, angle: 'back' },
{ file: cornerImageFile, angle: 'corners' },
];
const observations = await Promise.all(
photoAngles.map(async ({ file, angle }) => {
// Get a signed upload URL
const { uploadUrl, imageUrl } = await tenant.observations.getUploadUrl({
filename: `charizard-${angle}.jpg`,
contentType: 'image/jpeg',
});
// Push the image bytes to cloud storage
await fetch(uploadUrl, {
method: 'PUT',
body: file,
headers: { 'Content-Type': 'image/jpeg' },
});
// Register the observation
return tenant.observations.create({
locationId: 'loc_vault_1',
imageUrl,
metadata: { inspectionId: inspection.id, angle },
});
})
);
console.log(`Uploaded ${observations.length} photos`);
5. Trigger AI grading
await tenant.inspections.grade(inspection.id);
The platform loads the PSA grading guides for pokemon-base-set (centering descriptions, prompt hints) and passes them alongside the photos to the vision model.
6. Poll for results
let result = await tenant.inspections.get(inspection.id);
while (result.status === 'grading') {
await new Promise(r => setTimeout(r, 3000));
result = await tenant.inspections.get(inspection.id);
}
console.log('AI grades:', result.aiGrades);
// {
// centering: 9,
// corners: 8,
// edges: 9,
// surface: 8,
// overall: 8.5
// }
7. Human review and override
// A grader inspects the physical card and confirms or adjusts the AI grades
const finalized = await tenant.inspections.submitHumanGrades(inspection.id, {
grades: {
centering: 9, // confirmed
corners: 8, // confirmed
edges: 9, // confirmed
surface: 9, // upgraded — AI missed clean surface under correct lighting
},
notes: 'Surface scratch AI detected is actually a photographic reflection. Surface is PSA 9.',
});
console.log('Final grade:', finalized.finalGrades.overall); // 8.75 → rounds to PSA 9
console.log('Status:', finalized.status); // "completed"
8. Read the final report
const report = await tenant.inspections.get(inspection.id);
console.log(`Card: ${report.catalogItem.name}`);
console.log(`Schema: ${report.gradingSchema.name}`);
console.log(`Overall: ${report.finalGrades.overall} (PSA ${Math.round(report.finalGrades.overall)})`);
console.log(`Human reviewed: ${report.humanReviewed}`);
console.log(`Completed: ${report.completedAt}`);
// Card: Charizard Holo #4
// Schema: PSA 10-Point Grading Scale
// Overall: 8.75 (PSA 9)
// Human reviewed: true
// Completed: 2026-04-28T15:00:00Z
Next steps
- Grading Schemas — Explore other schemas (BGS, GIA, Sheldon)
- Catalog Registry — Browse all collector catalog types
- Build your own WineScan — Create a private vertical with custom schemas