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