Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

@vakra-dev/reader-js

TypeScript/JavaScript SDK for the Reader API — content extraction for LLMs. Wraps POST /v1/read, parses the standard envelope, throws typed errors, and auto-polls async jobs to completion.

Version: 0.2.0 · Runtime: Node 18+, Deno, Bun, Cloudflare Workers, modern browsers

Install

npm install @vakra-dev/reader-js

Quick start

import { ReaderClient } from "@vakra-dev/reader-js";

const reader = new ReaderClient({ apiKey: process.env.READER_KEY! });

const result = await reader.read({ url: "https://example.com" });
if (result.kind === "scrape") {
  console.log(result.data.markdown);
}

reader.read(...) returns a discriminated union:

  • { kind: "scrape", data: ScrapeResult } — single-URL requests, returned immediately
  • { kind: "job", data: Job } — batch and crawl requests, auto-polled to completion

Features

  • One method for every read operation. reader.read({ url }) for sync scrape, { urls: [...] } for batch, { url, maxPages } for crawl.
  • Typed errors for all 11 Reader error codes. InsufficientCreditsError, RateLimitedError, UrlBlockedError, ScrapeTimeoutError, and more. Each subclass surfaces the relevant fields (e.g. err.required, err.retryAfterSeconds).
  • Automatic retries with exponential backoff for transient codes (rate_limited, upstream_unavailable, scrape_timeout, …). Honors the Retry-After header on 429.
  • Pagination-aware job collection. waitForJob() returns the full job with every page result collected across pagination boundaries.
  • SSE streaming. for await (const event of reader.stream(jobId)) yields real-time progress / page / error / done events.
  • Request ID tracing. Every error carries the x-request-id header value on err.requestId for support tickets.

Browser Sessions

Launch a stealthed Chrome and connect Playwright or Puppeteer:

import { chromium } from "playwright-core";

const session = await reader.sessions.create();
const browser = await chromium.connectOverCDP(session.wsEndpoint);
const page = await (await browser.newContext()).newPage();

await page.goto("https://example.com");
console.log(await page.title());

await browser.close();
await reader.sessions.stop(session.sessionId);

Methods: reader.sessions.create(), .get(id), .stop(id), .list()

Browser usage

The SDK works in modern browsers via native fetch, but do not ship your API key in browser code — anyone can read and reuse it. Proxy requests through your own backend.

Errors

import {
  ReaderApiError,
  InsufficientCreditsError,
  RateLimitedError,
  UrlBlockedError,
} from "@vakra-dev/reader-js";

try {
  await reader.read({ url });
} catch (err) {
  if (err instanceof InsufficientCreditsError) {
    console.error(`Need ${err.required}, have ${err.available}`);
  } else if (err instanceof RateLimitedError) {
    console.error(`Retry after ${err.retryAfterSeconds}s`);
  } else if (err instanceof UrlBlockedError) {
    console.error(`Blocked: ${err.reason}`);
  } else if (err instanceof ReaderApiError) {
    console.error(`[${err.code}] ${err.message} — see ${err.docsUrl}`);
  } else {
    throw err;
  }
}

Full catalog of error codes: https://reader.dev/docs/home/concepts/errors

Links

Development

npm install
npm run typecheck
npm run build    # builds to dist/
npm test         # vitest