Rascador

TypeScript SDK

@torvion/rascador is the official, open-source TypeScript client for the Rascador API. It has no dependencies and runs on Node 18+, Bun, Deno, edge runtimes and in the browser.

Install

npm
npm install @torvion/rascador
bun
bun add @torvion/rascador
pnpm
pnpm add @torvion/rascador
deno
deno add jsr:@torvion/rascador

Quick start

Create a key from API Keys and keep it in an environment variable. A rsc_test_ key is enough to start — see Environments for what it can and can't do.

TypeScript
import { Rascador } from "@torvion/rascador"

const rascador = new Rascador({ apiKey: process.env.RASCADOR_API_KEY })

const { data: me } = await rascador.me()
console.log(me.scopes)

Every method returns the gateway's envelope unchanged as { data, meta }, with field names exactly as they appear in the API Reference.

Methods

MethodEndpointNotes
me()GET /v1/meScopes, limits and remaining quota. Free.
sources.list()GET /v1/sourcesWhich sources exist and what each supports. Free.
categories.list({ q })GET /v1/categoriesServed from cache.
products.list({ … })GET /v1/productsFilter stored products; iterate with for await.
products.get(id, { refresh })GET /v1/products/:idInstant when stored; live-fetches otherwise.
search({ q, pages, refresh })GET /v1/searchLive search. Takes 20–40s.
TypeScript
// Browse stored products by category
const { data: categories } = await rascador.categories.list({ q: "dress" })
const { data: products, meta } = await rascador.products.list({
  category_id: categories[0].id,
  on_sale: true,
  limit: 20,
})

// Or walk every page
for await (const product of rascador.products.list({ brand: "SHEIN" })) {
  console.log(product.title, product.price.current)
}

// Live search, then full details for a hit
const { data: hits } = await rascador.search({ q: "summer dress" })
const { data: product } = await rascador.products.get(String(hits[0].product_id))

products.list accepts category_id, sku, q, brand, min_price, max_price, color, size, on_sale, limit and offset. Iterating it with for await follows meta.pagination.has_more for you.

Sources

Set a default source on the client and override it per call. sources.list() tells you which filters and live features each source supports.

TypeScript
const rascador = new Rascador({ apiKey, source: "shein" })

await rascador.search({ q: "usb-c hub", source: "amazon" })

Errors

Any non-2xx response throws a RascadorErrorcarrying the gateway's error envelope. Branch on code, not on the message — the full list is on Errors & Limits.

TypeScript
import { RascadorError } from "@torvion/rascador"

try {
  await rascador.search({ q: "linen shirt" })
} catch (err) {
  if (!(err instanceof RascadorError)) throw err

  switch (err.code) {
    case "quota_exceeded":
      console.log("Quota resets at", err.details?.resets_at)
      break
    case "insufficient_scope":
      console.log("This key can't do that:", err.details)
      break
    default:
      console.log(err.status, err.code, err.requestId)
  }
}

Each error has code, status, retryable, retryAfterSeconds, requestId and details. Include the requestId when you contact support.

Timeouts and retries

search drives a real browser, so it gets a 130-second timeout by default; every other call gets 30 seconds. Errors the gateway marks retryable — rate limits and upstream outages — are retried up to twice, waiting at least as long as Retry-After asks. Quota spent on a failed call is refunded, so retries never double-charge.

TypeScript
const rascador = new Rascador({
  apiKey,
  timeoutMs: 60_000, // non-search calls
  maxRetries: 0,     // turn retries off
  fetch: customFetch, // e.g. for proxies or tests
})

// Cancel a single call
const controller = new AbortController()
await rascador.search({ q: "desk lamp" }, { signal: controller.signal })

Source code

The SDK is MIT-licensed and developed in the open on GitHub, published to npm and JSR. Issues and pull requests are welcome.