TypeScript SDK
@raritydb/sdk is the official TypeScript client: typed results, auto-paging lists and photo helpers, with no dependencies. It runs anywhere fetch does: Node 18+, Bun, Deno, browsers and edge runtimes. (Calling it from a browser exposes your key, so keep it server-side.)
It isn't on npm yet; it will be published with the public API domain. Until then, install it from the repository's sdk/ folder.
import { RarityDB } from "@raritydb/sdk";
const raritydb = new RarityDB({ apiKey: process.env.RARITYDB_API_KEY!, baseUrl: "https://raritydb.com" });
const card = await raritydb.card("sv03.5-006");
console.log(card?.name, card?.printings[0]?.price?.trend); // "Charizard ex" 7.42
Catalog
await raritydb.search("charzard", { limit: 5 }); // species, sets and cards, best first
await raritydb.set("sv03.5"); // with pull rates
await raritydb.resolveId("pokemontcg.io", "base1-4"); // or "tcgplayer", "cardmarket", "tcgdex"
for await (const card of raritydb.cards({ setCode: "sv03.5" })) {
console.log(card.number, card.name); // pages are fetched as you go
}
for await (const set of raritydb.sets({ region: "ASIA" })) console.log(set.code, set.name);
cards() takes the same filter as the API's cards query: name, setCode, nationalDex, supertype, type, rarity, illustrator, regulationMark, region, standardLegal, digital.
Photos
identify, identifyCards, assessCondition and checkAuthenticity take a photo as bytes (Uint8Array, Buffer, ArrayBuffer, Blob) or an https URL. JPEG, PNG and WebP are detected from the bytes.
import { readFileSync } from "node:fs";
const id = await raritydb.identify(readFileSync("card.jpg"));
if (id.status === "MATCH") console.log(id.card!.name, id.printing);
const page = await raritydb.identifyCards(readFileSync("binder-page.jpg"), { grid: "3x3" });
for (const { row, column, identification, error } of page.cards) console.log(row, column, identification?.card?.name ?? error);
const grade = await raritydb.assessCondition(readFileSync("front.jpg"), { back: readFileSync("back.jpg") });
console.log(grade.gradeRange); // { low: 8, high: 9, scale: "1–10" }
const check = await raritydb.checkAuthenticity(readFileSync("front.jpg"));
console.log(check.verdict, check.redFlags);
These count against your daily photo quota (see Authentication and limits).
A slab photo's identify result includes slab (where to verify the cert); raritydb.slabVerification("PSA", "12345678") does the same without a photo.
Anything else
The typed methods cover common queries. For any other field, run your own query:
const { species } = await raritydb.graphql(`{ species(slug: "pikachu") { name evolutionLine { name } } }`);
The schema ships in the package as schema.graphql for codegen tools.
Prices from your own provider key
new RarityDB({ apiKey, baseUrl, providerKeys: { justtcg: process.env.JUSTTCG_KEY } });
The key is sent with each request and never stored. See Prices.
Price alerts and webhooks
const { secret, webhookEndpoint } = await raritydb.createWebhookEndpoint("https://example.com/hooks/raritydb");
await raritydb.createPriceAlert({ cardCode: "sv03.5-006", condition: "TREND_ABOVE", threshold: 50, webhookEndpointId: webhookEndpoint.id });
// In your webhook handler, with the raw request body:
import { verifyWebhook, type PriceAlertEvent } from "@raritydb/sdk";
if (await verifyWebhook(rawBody, signatureHeader, secret)) {
const event = JSON.parse(rawBody) as PriceAlertEvent;
}
See Price alerts and webhooks.
Pullbook (seller ledger)
const purchase = await raritydb.createPurchase({ kind: "SEALED", sealedProductId, quantity: 2, purchasedOn: "2026-10-01", price: 50, shipping: 4 });
const box = purchase.items[0];
await raritydb.addPulls(purchase.id, { fromItemId: box.id, pulls: [{ cardCode: "sv03.5-006", printingKey: "holo" }], bulk: 40 });
const inventory = await raritydb.pullbookInventory(); // costBasis in your ledger currency
const holdings = await raritydb.pullbookHoldings({ kind: "sealed" }); // market value, paid, gain
const sale = await raritydb.createSale({ channel: "WHATNOT", soldOn: "2026-10-10", lines: [{ cardCode: "sv03.5-006", price: 40 }], shippingCharged: 4 });
const imported = await raritydb.importSales(csvText, "WHATNOT", { filename: "orders.csv" }); // or finishImport(id, mapping) when needs_mapping
const { rows, total } = await raritydb.pullbookReport("PURCHASE", 2026); // what each box made
const { lots, inReview } = await raritydb.pullbookTaxLots(2026); // not tax advice; inReview = sales left out until matched
for (const line of await raritydb.pullbookReviewQueue()) await raritydb.resolveSaleLine(line.id, { costBasis: 0 });
See Pullbook.
Errors
Failed calls throw RarityDBError with status, code (e.g. RATE_LIMITED, QUOTA_EXCEEDED, UNAUTHENTICATED) and, for rate limits, retryAfter in seconds. When a query partly succeeds, the data is returned and the errors go to onWarning (default console.warn).
This page as Markdown: /docs/typescript-sdk.md