KLIQ|Developers

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