How to Combine a Card Scanner With the CardGrade API for Automated Bulk Grading
Technology
How to Combine a Card Scanner With the CardGrade API for Automated Bulk Grading
Pair a high-speed card scanner with the CardGrade API to build an automated grading pipeline. Scan cards, submit images programmatically, and get AI grade predictions at scale.
CardGrade.io Editorial·Published Feb 21, 2026·6 min read
The Automated Grading Pipeline
If you process more than a handful of cards at a time — whether you run a card shop, prep service, or just have a serious collection — manually uploading photos through a website gets old fast. The real power move is pairing a dedicated card scanner with the CardGrade API to build an automated pipeline: scan a card, submit the image, get an AI grade prediction, all without touching a browser.
Here's how to set it up.
Step 1: Choose Your Card Scanner
Not all scanners are created equal for trading cards. You need something that produces clean, well-lit, high-resolution images — because the quality of the scan directly affects the accuracy of the grade prediction.
What to look for
Resolution: 600 DPI minimum, 1200 DPI preferred. Higher resolution means the AI can spot surface imperfections, print defects, and centering issues more accurately.
Flatbed or dedicated card scanner: Flatbed scanners work but are slow for volume. Dedicated card scanners are purpose-built for the form factor.
Consistent lighting: Even illumination across the card surface prevents shadows and hot spots that can fool the grading algorithm.
Front and back scanning: Some scanners do both sides in a single pass — a big time saver for bulk work.
Scanner options by use case
For low to mid volume (under 50 cards/day):
A quality flatbed scanner like the Epson Perfection V39 or Canon CanoScan LiDE 400 works well. Place the card face-down, scan at 600+ DPI, flip, repeat. It's manual but produces excellent image quality.
For mid to high volume (50–500 cards/day):
The Fujitsu ScanSnap series (like the iX1600) can scan both sides in a single pass using the document feeder. Use a card-sized carrier sheet to protect the cards during feeding. This is the sweet spot for most card shops.
For high volume operations (500+ cards/day):
Purpose-built card scanners exist for this market. Some have hoppers that feed sleeved or raw cards automatically. These typically cost more but dramatically reduce per-card scanning time.
Step 2: Set Up Your Scan Workflow
Once you have a scanner, you need a folder-watching workflow:
The basic flow
Card placed on scanner
↓
Scan produces image file (e.g., scan_001_front.jpg, scan_001_back.jpg)
↓
Images land in a watch folder
↓
Script detects new images
↓
Script submits to CardGrade API
↓
Results saved to CSV/database
Organize your scan output
Create a simple folder structure:
scans/
pending/ ← New scans land here
submitted/ ← Moved here after API submission
completed/ ← Moved here after results retrieved
Most scanner software lets you configure the output directory and file naming pattern. Set it to drop files into scans/pending/.
Step 3: Write the Automation Script
Here's a Python script that watches the pending folder and submits cards to the CardGrade API:
import os
import time
import requests
import shutil
import json
API_TOKEN = "your_api_token_here"
API_BASE = "https://cardgrade.io/api/v1"
HEADERS = {"Authorization": f"Bearer {API_TOKEN}"}
PENDING_DIR = "scans/pending"
SUBMITTED_DIR = "scans/submitted"
COMPLETED_DIR = "scans/completed"
def submit_card(front_path, back_path=None):
"""Submit a card to the CardGrade API."""
files = {"frontImage": open(front_path, "rb")}
if back_path and os.path.exists(back_path):
files["backImage"] = open(back_path, "rb")
data = {
"gradingCompany": "PSA",
"cardType": "Pokemon Card",
}
resp = requests.post(
f"{API_BASE}/grade",
headers=HEADERS,
files=files,
data=data,
)
return resp.json()
def check_result(grading_id):
"""Poll for grading results."""
resp = requests.get(
f"{API_BASE}/grade/{grading_id}",
headers=HEADERS,
)
return resp.json()
def process_pending():
"""Find and submit pending scans."""
files = sorted(os.listdir(PENDING_DIR))
front_files = [f for f in files if "_front" in f.lower()]
for front_file in front_files:
base = front_file.replace("_front", "").rsplit(".", 1)[0]
back_file = front_file.replace("_front", "_back")
front_path = os.path.join(PENDING_DIR, front_file)
back_path = os.path.join(PENDING_DIR, back_file)
print(f"Submitting: {front_file}")
result = submit_card(front_path, back_path)
if "id" in result:
# Move to submitted folder
shutil.move(front_path,
os.path.join(SUBMITTED_DIR, front_file))
if os.path.exists(back_path):
shutil.move(back_path,
os.path.join(SUBMITTED_DIR, back_file))
# Save grading ID for polling
with open(
os.path.join(SUBMITTED_DIR, f"{base}.json"), "w"
) as f:
json.dump(result, f)
print(f" → Grading ID: {result['id']}")
else:
print(f" → Error: {result}")
# Run the watcher
print("Watching for new scans...")
while True:
process_pending()
time.sleep(5)
This script watches the pending/ folder every 5 seconds, submits new card scans to the API, and moves processed files to submitted/. You'd add a similar polling loop to check for completed gradings and move results to completed/.
Step 4: Handle Results at Scale
Once gradings complete, you probably want the results in a spreadsheet or database. Add a results collector:
import csv
def collect_results():
"""Check submitted gradings and save results."""
json_files = [
f for f in os.listdir(SUBMITTED_DIR)
if f.endswith(".json")
]
for json_file in json_files:
path = os.path.join(SUBMITTED_DIR, json_file)
with open(path) as f:
data = json.load(f)
result = check_result(data["id"])
if result.get("status") == "completed":
# Append to CSV
with open("grading_results.csv", "a",
newline="") as csvfile:
writer = csv.writer(csvfile)
writer.writerow([
json_file.replace(".json", ""),
result.get("overallGrade"),
result.get("results", {}).get(
"psaPrediction"),
result.get("results", {}).get(
"bgsPrediction"),
result.get("results", {}).get(
"cgcPrediction"),
result.get("results", {}).get("centering"),
result.get("results", {}).get("corners"),
result.get("results", {}).get("edges"),
result.get("results", {}).get("surface"),
])
# Move to completed
shutil.move(path,
os.path.join(COMPLETED_DIR, json_file))
print(f"Completed: {json_file} → "
f"Grade {result.get('overallGrade')}")
Now you have a CSV with all your grades, sub-grades, and predictions — ready to import into your inventory system or use for submission decisions.
Tips for Best Results
Image quality matters most. A $200 scanner at 1200 DPI will give better grading results than a $2,000 scanner at 300 DPI. Resolution is king.
Clean your scanner glass. Dust, fingerprints, and smudges on the scanner bed show up in the scan and can affect the grade prediction. Wipe it down regularly.
Use consistent settings. Don't change scanner brightness, contrast, or color settings between cards. The AI works best with consistent input.
Respect rate limits. Pro plans allow 10 grades per minute, Business allows 30. Space your submissions accordingly — the script above naturally rate-limits by processing sequentially.
Start with a test batch. Run 10–20 cards through the pipeline first and compare the AI predictions with your own assessment before processing your full inventory.
The ROI Math
Here's why this setup pays for itself quickly:
A Business plan gives you 300 credits per month at $60 — that's $0.20 per card for an AI grade prediction. Compare that to:
PSA submission: $20–$150 per card depending on service level
BGS submission: $25–$250 per card
Manual inspection time: Even at minimum wage, manually evaluating a card takes 2–3 minutes
Pre-screening with AI means you only submit cards that are likely to get the grade you need. If AI grading saves you from one bad PSA submission per month, the Business plan has already paid for itself.
Getting Started
Get your scanner set up — Any 600+ DPI flatbed or document scanner works
The combination of a card scanner and the CardGrade API turns what used to be a tedious manual process into an automated pipeline. Scan, submit, decide — at scale.
Share
Ready to grade your cards with AI?
Pre-screen your cards before submitting to PSA, BGS, or CGC. Start with 3 free credits.
The CardGrade.io editorial team writes about card grading, AI technology, and collecting strategy. Our guides are researched against official PSA, BGS, and CGC standards.