Official Swift SDK for CardSight AI REST API
The most comprehensive baseball card identification and collection management platform. 2M+ Cards β’ AI-Powered Recognition β’ Free Tier Available
Quick Links: Getting Started β’ Installation β’ Examples β’ Documentation β’ Support
- Full Swift Concurrency Support - Built with async/await for modern Swift development
- Type-Safe API - Auto-generated types from OpenAPI specification
- Automatic HEIC Conversion - Seamlessly handles iPhone's default photo format
- Smart Image Processing - Automatic resizing and compression for optimal uploads
- Platform Support - Native support for iOS, macOS, tvOS, and watchOS
- Comprehensive Error Handling - Detailed error types with retry capabilities
- 100% API Coverage - All CardSight AI endpoints are fully implemented
| Feature | Description |
|---|---|
| Card Identification | Identify cards from images using AI with automatic HEIC to JPEG conversion |
| Catalog Search | Search 2M+ baseball cards database |
| Collections | Manage owned card collections with analytics |
| Collectors | Manage collector profiles |
| Lists | Track wanted cards (wishlists) |
| Grading | PSA, BGS, SGC grade information |
| AI Search | Natural language queries |
| Autocomplete | Search suggestions |
- Swift 5.9+
- iOS 15.0+ / macOS 12.0+ / tvOS 15.0+ / watchOS 8.0+
- API Key from cardsight.ai (free tier available)
Add the following to your Package.swift file:
dependencies: [
.package(url: "https://github.com/cardsightai/cardsightai-sdk-swift.git", from: "2.0.0")
]Or in Xcode:
- File β Add Package Dependencies
- Enter:
https://github.com/cardsightai/cardsightai-sdk-swift.git - Click Add Package
Get started in minutes with a free API key from cardsight.ai - no credit card required!
import CardSightAI
// 1. Initialize the client
let client = try CardSightAI(apiKey: "your_api_key_here")
// 2. Identify a card from an image
let image: UIImage = // ... from camera or photo library
let result = try await client.identify.card(image)
// 3. Access the identification results
switch result {
case .ok(let response):
switch response.body {
case .json(let identification):
// The API can detect multiple cards in a single image
if let detection = identification.detections?.first {
print("Card: \(detection.card?.name ?? "Unknown")")
print("Confidence: \(detection.confidence)") // "High", "Medium", or "Low"
print("Total cards detected: \(identification.detections?.count ?? 0)")
} else {
print("No cards detected")
}
}
default:
print("Identification failed")
}That's it! The SDK handles HEIC conversion, image optimization, and API communication automatically.
The SDK automatically handles HEIC images from iPhone cameras:
import UIKit
import CardSightAI
let client = try CardSightAI(apiKey: "your_api_key")
// From camera or photo library (HEIC automatically converted to JPEG)
let image: UIImage = // ... from UIImagePickerController
let result = try await client.identify.card(image)
// The SDK automatically:
// 1. Detects if the image is HEIC format
// 2. Converts HEIC to JPEG
// 3. Resizes if needed (max 2048x2048 by default)
// 4. Optimizes file size (max 5MB)
// 5. Sends to API
// Access the identification results
switch result {
case .ok(let response):
switch response.body {
case .json(let identification):
// Check if any cards were detected
guard let detections = identification.detections, !detections.isEmpty else {
print("No cards detected in image")
return
}
// Process all detected cards (the API can detect multiple cards in a single image)
print("Detected \(detections.count) card(s)")
for (index, detection) in detections.enumerated() {
print("\nCard \(index + 1):")
print("Confidence: \(detection.confidence)") // .High, .Medium, or .Low
if let card = detection.card {
print(" Name: \(card.name)")
print(" Year: \(card.year)")
print(" Manufacturer: \(card.manufacturer)")
print(" Release: \(card.releaseName)")
if let setName = card.setName {
print(" Set: \(setName)")
}
if let number = card.number {
print(" Number: \(number)")
}
}
}
}
default:
print("Identification failed")
}The identify endpoint returns detailed metadata and supports multiple card detection:
let result = try await client.identify.card(image)
switch result {
case .ok(let response):
switch response.body {
case .json(let identification):
// Access request metadata
print("Request ID: \(identification.requestId)")
if let processingTime = identification.processingTime {
print("Processing time: \(processingTime)ms")
}
// Handle single or multiple card detection
if let detections = identification.detections {
switch detections.count {
case 0:
print("No cards detected")
case 1:
print("Single card detected")
default:
print("Multiple cards detected: \(detections.count)")
}
// Each detection represents a physical card in the image
for detection in detections {
if let card = detection.card {
print("[\(detection.confidence)] \(card.name) - \(card.year)")
}
}
}
}
default:
break
}// Configure custom image processing
let config = try CardSightAIConfig(
apiKey: "your_api_key",
imageProcessing: ImageProcessingOptions(
maxDimension: 1024, // Smaller size for faster uploads
jpegQuality: 0.7, // Lower quality for smaller files
maxFileSizeMB: 3.0, // Max 3MB
correctOrientation: true // Fix orientation issues
)
)
let client = try CardSightAI(config: config)// From Data (auto-detects format)
let imageData: Data = // ... image data
let result = try await client.identify.card(imageData)
// From file URL
let fileURL = URL(fileURLWithPath: "/path/to/image.heic")
let result = try await client.identify.card(fileURL)
// From NSImage (macOS)
#if canImport(AppKit)
let nsImage: NSImage = // ... your image
let result = try await client.identify.card(nsImage)
#endif// Search for cards with query parameters
var query = Operations.getCards.Input.Query()
query.name = "Aaron Judge"
query.year = 2023
query.take = 10
let result = try await client.raw.getCards(query: query)
if case .ok(let response) = result {
print("Found \(response.body.json.items.count) cards")
}
// Get specific card
let card = try await client.raw.getCard(.init(path: .init(id: "card_uuid")))
// Search sets
var setsQuery = Operations.getSets.Input.Query()
setsQuery.year = 2023
setsQuery.take = 20
let sets = try await client.raw.getSets(query: setsQuery)
// Get specific set with details
let set = try await client.raw.getSet(.init(path: .init(id: "set_uuid")))
// Get cards in a set
let setCards = try await client.raw.getSetCards(.init(path: .init(id: "set_uuid")))
// Search releases
var releasesQuery = Operations.getReleases.Input.Query()
releasesQuery.name = "Chrome"
releasesQuery.yearFrom = 2020
releasesQuery.yearTo = 2024
let releases = try await client.raw.getReleases(query: releasesQuery)
// Get manufacturers
let manufacturers = try await client.raw.getManufacturers()
// Get segments (Baseball, Pokemon, etc.)
let segments = try await client.raw.getSegments()
// Get parallels
let parallels = try await client.raw.getParallels()
// Get catalog statistics
let stats = try await client.raw.getCatalogStatistics()// Create a collection
let createInput = Operations.createCollection.Input(
body: .json(.init(
name: "My Vintage Cards",
description: "Pre-1980 baseball cards",
collectorId: "collector_uuid"
))
)
let collection = try await client.raw.createCollection(createInput)
// Add card to collection
let addCardInput = Operations.addCardsToCollection.Input(
path: .init(collectionId: "collection_uuid"),
body: .json(.init(
cards: [.init(
cardId: "card_uuid",
quantity: 1,
buyPrice: "50.00",
buyDate: "2024-01-15"
)]
))
)
try await client.raw.addCardsToCollection(addCardInput)
// Get collection analytics
let analytics = try await client.raw.getCollectionAnalytics(
.init(path: .init(collectionId: "collection_uuid"))
)Retrieve card images using the generated client:
// Get card image data
let imageResult = try await client.raw.getCardImage(
.init(path: .init(id: "card_uuid"))
)
if case .ok(let response) = imageResult {
if case .image_sol_jpeg(let imageBody) = response.body {
let imageData = try await Data(collecting: imageBody, upTo: 10 * 1024 * 1024) // 10MB limit
#if canImport(UIKit)
let image = UIImage(data: imageData)
imageView.image = image
#endif
#if canImport(AppKit)
let image = NSImage(data: imageData)
imageView.image = image
#endif
}
}do {
let result = try await client.raw.getCard(.init(path: .init(id: "invalid_id")))
} catch let error as CardSightAIError {
switch error {
case .authenticationError(let message):
print("Auth failed: \(message)")
case .apiError(let statusCode, let message, _):
print("API error \(statusCode): \(message)")
case .imageProcessingError(let message):
print("Image processing failed: \(message)")
case .networkError(let error):
print("Network error: \(error)")
case .timeout:
print("Request timed out")
default:
print("Error: \(error.localizedDescription)")
}
// Check if retryable
if error.isRetryable {
// Retry logic
}
}The SDK includes powerful image processing capabilities specifically designed for trading card images:
// iPhone camera photos (HEIC) are automatically converted
let photo = // ... from camera
let result = try await client.identify.card(photo) // Handles HEIC β JPEG// Process image manually if needed
let processor = ImageProcessor()
let processedData = try await processor.processForUpload(image)
// Or with custom options
let customOptions = ImageProcessingOptions(
maxDimension: 1024,
jpegQuality: 0.6
)
let processedData = try await processor.processForUpload(image, customOptions: customOptions)// If you want to handle image processing yourself
let config = try CardSightAIConfig(
apiKey: "your_api_key",
autoProcessImages: false // Disable automatic processing
)let config = try CardSightAIConfig(
apiKey: "your_api_key", // Required
baseURL: "https://api.cardsight.ai", // Optional custom endpoint
timeout: 30, // Request timeout in seconds
customHeaders: ["X-Custom": "value"], // Additional headers
imageProcessing: ImageProcessingOptions( // Image processing settings
maxDimension: 2048,
jpegQuality: 0.8,
maxFileSizeMB: 5.0,
correctOrientation: true
),
autoProcessImages: true // Auto-convert HEIC
)
let client = try CardSightAI(config: config)β 100% Coverage Verified
The SDK provides complete coverage of all 79 CardSight AI REST API endpoints (including 3 new random catalog endpoints):
| Category | Endpoints | Coverage | SDK Access |
|---|---|---|---|
| Health | 2 | 100% | client.getHealth(), client.getHealthAuthenticated() |
| Card Identification | 1 | 100% | client.identify.card() |
| Catalog | 17 | 100% | client.raw.getCards(), client.raw.getSets(), etc. |
| Collections | 23 | 100% | client.raw.getCollections(), client.raw.createCollection(), etc. |
| Collectors | 5 | 100% | client.raw.getCollectors(), etc. |
| Lists | 8 | 100% | client.raw.getLists(), etc. |
| Grades | 3 | 100% | client.raw.getGradingCompanies(), etc. |
| Autocomplete | 6 | 100% | client.raw.autocompleteCards(), etc. |
| AI | 1 | 100% | client.raw.queryAI() |
| Images | 1 | 100% | client.raw.getCardImage() |
| Feedback | 8 | 100% | client.raw.submitGeneralFeedback(), etc. |
| Subscription | 1 | 100% | client.raw.getSubscription() |
| TOTAL | 79 | 100% | - |
The SDK includes a convenience wrapper for card identification that handles image processing automatically:
- π―
client.identify.card()- Automatic HEIC conversion, resizing, optimization, and multipart upload - All other endpoints use the auto-generated client directly via
client.raw.{operationName}()
# Clone the repository
git clone https://github.com/cardsightai/cardsightai-sdk-swift.git
cd cardsightai-sdk-swift
# Update OpenAPI specification
make update-spec
# Build the package
make build
# Run tests (requires Xcode, not just Command Line Tools)
make testThe SDK includes comprehensive unit tests and integration tests:
Unit tests validate SDK configuration, error handling, and image processing without requiring API connectivity:
swift test --filter CardSightAITestsThe SDK includes integration tests that validate real API connectivity:
Requirements:
- Xcode (full installation, not just Command Line Tools)
- API Key: Set
CARDSIGHTAI_API_KEYenvironment variable
Available Tests:
- Unauthenticated Health Check (
GET /health) - Tests basic API connectivity (no API key needed) - Authenticated Health Check (
GET /health/auth) - Tests API connectivity and validates your API key
Running Integration Tests:
In Xcode (Recommended):
- Open
Package.swiftin Xcode - Set
CARDSIGHTAI_API_KEYin your scheme's environment variables (for authenticated test) - Run tests via Product β Test (βU)
Via Command Line:
# Run all integration tests (requires Xcode installation)
export CARDSIGHTAI_API_KEY=your_api_key_here
swift test --filter CardSightAIIntegrationTests
# Run individual tests
swift test --filter testHealthCheckUnauthenticated # No API key needed
swift test --filter testHealthCheckAuthenticated # Requires API keyNote:
- Integration tests require Xcode (not just Command Line Tools) due to XCTest framework dependencies
- Tests automatically skip when running in CI environments
- The unauthenticated health test works without an API key
Problem: Tests fail with "no such module 'XCTest'" error Cause: XCTest framework requires full Xcode installation, not just Command Line Tools Solution: Install Xcode from the App Store and run tests from Xcode or ensure Xcode is selected as the active developer directory:
sudo xcode-select --switch /Applications/Xcode.app/Contents/DeveloperProblem: Client initialization fails with authentication error
Cause: No API key provided and CARDSIGHTAI_API_KEY environment variable not set
Solutions:
// Option 1: Pass API key directly
let client = try CardSightAI(apiKey: "your_api_key")
// Option 2: Set environment variable
// In Xcode: Edit Scheme β Run β Arguments β Environment Variables
// Add: CARDSIGHTAI_API_KEY = your_api_key
// In Terminal:
export CARDSIGHTAI_API_KEY=your_api_keyProblem: HEIC images from iPhone camera fail to process Cause: Image processor configuration or unsupported format Solutions:
// Ensure auto-processing is enabled (default)
let client = try CardSightAI(
apiKey: "your_api_key",
autoProcessImages: true // This is the default
)
// Or manually convert before uploading
if let jpegData = image.jpegData(compressionQuality: 0.8) {
let result = try await client.identify.card(jpegData)
}Problem: Client initialization fails with invalid URL error Cause: Malformed base URL string Solution: Use the default URL or ensure custom URL is properly formatted:
// Use default (recommended)
let client = try CardSightAI(apiKey: "your_api_key")
// Or provide valid custom URL
let client = try CardSightAI(
apiKey: "your_api_key",
baseURL: "https://custom.api.url"
)Problem: Requests fail with timeout errors Cause: Network issues or slow connection Solutions:
// Increase timeout for slow connections
let client = try CardSightAI(
apiKey: "your_api_key",
timeout: 60 // 60 seconds instead of default 30
)
// Check if error is retryable
do {
let result = try await client.identify.card(image)
} catch let error as CardSightAIError {
if error.isRetryable {
// Retry the request
print("Request failed but is retryable")
}
}Problem: Image uploads fail or take too long Cause: Image file size exceeds limits or is too large Solutions:
// Reduce image size and quality
let config = try CardSightAIConfig(
apiKey: "your_api_key",
imageProcessing: ImageProcessingOptions(
maxDimension: 1024, // Smaller than default 2048
jpegQuality: 0.6, // Lower than default 0.8
maxFileSizeMB: 2.0 // Smaller than default 5.0
)
)
let client = try CardSightAI(config: config)Problem: Working with types like Operations.get_sol_v1_sol_catalog_sol_cards is cumbersome
Explanation: These are auto-generated from the OpenAPI specification and reflect the API's internal structure
Recommendation: Use the convenience properties on the client which provide cleaner interfaces:
// Instead of using Operations types directly:
// var query = Operations.get_sol_v1_sol_catalog_sol_cards.Input.Query()
// Use the client's methods which hide the complexity:
let cards = try await client.catalog.cards.list(query: query)If you encounter issues not covered here:
- Check the API Documentation: api.cardsight.ai/documentation
- Review Error Messages: CardSightAI errors include detailed descriptions
catch let error as CardSightAIError { print("Error: \(error.errorDescription ?? "Unknown")") print("Reason: \(error.failureReason ?? "Unknown")") }
- Enable Debug Logging: Check network requests and responses
- Submit an Issue: GitHub Issues
- Contact Support: support@cardsight.ai
Contributions are welcome! Please see CONTRIBUTING.md for guidelines.
MIT
- Email: support@cardsight.ai
- Website: cardsight.ai
- API Documentation: api.cardsight.ai/documentation
- Issues: GitHub Issues
This SDK uses:
- Swift OpenAPI Generator for auto-generating API types
- Swift OpenAPI Runtime for API client functionality
Made with β€οΈ by CardSight AI, Inc.