npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

rulebook-typescript

v0.1.1

Published

TypeScript SDK for the Rulebook Company API — exchange fee schedule and rebate data

Readme

Rulebook SDK for TypeScript / JavaScript

The official TypeScript client for the Rulebook Company API — access exchange fee schedule and rebate data across US trading venues.

Node.js 18+ License: MIT

Installation

npm install rulebook-typescript

Usage

import { Rulebook } from "rulebook-typescript";

const client = new Rulebook({ apiKey: "your-api-key" });

// List all exchanges
const exchanges = await client.exchanges.list();
for (const exchange of exchanges) {
  console.log(`${exchange.name}: ${exchange.display_name} (${exchange.record_count} records)`);
}

// Get details for a specific exchange
const detail = await client.exchanges.retrieve("NYSE");
console.log(`Date range: ${detail.date_range.earliest} to ${detail.date_range.latest}`);
console.log(`Fee types: ${detail.fee_types}`);
console.log(`Actions: ${detail.actions}`);

// List fee schedule results (with filtering)
const results = await client.feeScheduleResults.list({
  exchange_name: ["fee_cboe_us_options"],
  fee_type: ["Option"],
  latest_only: true,
  page_size: 10,
});
for (const item of results.data) {
  console.log(`${item.exchange_name} | ${item.fee_type} | ${item.fee_amount}`);
}

// Get a single fee schedule result
const result = await client.feeScheduleResults.retrieve("some-uuid");

// Get available filter values
const filters = await client.feeScheduleResults.getFilters();
console.log(`Exchanges: ${filters.exchange_names}`);
console.log(`Fee types: ${filters.fee_types}`);

// Get results by extraction version
const versionResults = await client.feeScheduleResults.getResultsByVersion("version-uuid");

Authentication

Pass your API key directly or set the RULEBOOK_API_KEY environment variable:

// Option 1: Pass directly
const client = new Rulebook({ apiKey: "..." });

// Option 2: Environment variable
// export RULEBOOK_API_KEY=...
const client = new Rulebook();

Async by Default

All methods return a Promise and are designed for async/await usage. Unlike the Python SDK which provides separate Rulebook and AsyncRulebook clients, the TypeScript SDK is async-native — there is no separate sync client.

import { Rulebook } from "rulebook-typescript";

async function main() {
  const client = new Rulebook({ apiKey: "your-api-key" });
  const exchanges = await client.exchanges.list();
  const detail = await client.exchanges.retrieve("NYSE");
}

main();

Error Handling

The SDK throws typed errors for all API errors:

import { Rulebook, NotFoundError, AuthenticationError, RateLimitError } from "rulebook-typescript";

const client = new Rulebook();

try {
  const detail = await client.exchanges.retrieve("UNKNOWN");
} catch (err) {
  if (err instanceof NotFoundError) {
    console.log("Exchange not found");
  } else if (err instanceof AuthenticationError) {
    console.log("Invalid API key");
  } else if (err instanceof RateLimitError) {
    console.log(`Rate limited — retry after: ${err.headers.get("retry-after")}`);
  }
}

Error hierarchy:

| Error | Status Code | Description | |---|---|---| | BadRequestError | 400 | Invalid request parameters | | AuthenticationError | 401 | Missing or invalid API key | | PermissionDeniedError | 403 | Insufficient access for this resource | | NotFoundError | 404 | Resource does not exist | | UnprocessableEntityError | 422 | Request validation failed | | RateLimitError | 429 | Too many requests | | InternalServerError | 5xx | Server-side error | | APIConnectionError | — | Network failure | | APITimeoutError | — | Request timed out |

Raw Response Access

Access HTTP status codes, headers, and the raw response via withRawResponse:

const raw = await client.exchanges.withRawResponse.retrieve("NYSE");
console.log(raw.statusCode);                     // 200
console.log(raw.headers.get("content-type"));    // application/json

const detail = raw.parse();                      // ExchangeDetail

Client Configuration

const client = new Rulebook({
  apiKey: "...",
  baseUrl: "https://api.rulebookcompany.com/api/v1",  // default
  timeout: 30000,         // milliseconds (default: 30000)
  maxRetries: 2,          // retry transient failures (default: 2)
  defaultHeaders: {},     // headers sent on every request
  defaultQuery: {},       // query parameters sent on every request
});

Per-request overrides

Override timeout or add headers for a single request without modifying the client:

const exchanges = await client.exchanges.list({
  extra_headers: { "X-Request-Id": "abc-123" },
  timeout: 60000,
});

Immutable client copies

Create a new client with different settings using withOptions():

const slowClient = client.withOptions({ timeout: 120000 });

Retries

The SDK automatically retries transient errors (408, 409, 429, 500, 502, 503, 504) with exponential backoff and jitter. Configure with maxRetries:

const client = new Rulebook({ maxRetries: 5 }); // default is 2

Response Types

All responses are strongly typed with TypeScript interfaces:

import type {
  Exchange,
  ExchangeDetail,
  DateRange,
  FeeScheduleResult,
  FeeScheduleResultFilters,
  PaginatedResponse,
} from "rulebook-typescript/types";

Exchange — returned by list()

| Field | Type | Description | |---|---|---| | name | string | Exchange identifier (e.g., "NYSE") | | display_name | string | Full name (e.g., "New York Stock Exchange") | | fee_types | string[] | Available fee types (e.g., ["Equity", "Option"]) | | record_count | number | Total fee schedule records |

ExchangeDetail — returned by retrieve()

| Field | Type | Description | |---|---|---| | name | string | Exchange identifier | | display_name | string | Full name | | date_range | DateRange | Earliest and latest dates of available data | | fee_types | string[] | Available fee types | | fee_categories | string[] | Fee categories (e.g., ["Fee And Rebates"]) | | actions | string[] | Trade actions (e.g., ["Make", "Take", "Open"]) | | participants | string[] | Participant types (e.g., ["Market Maker", "Customer"]) | | symbol_classifications | string[] | Symbol classifications (e.g., ["ETF", "Equity"]) | | symbol_types | string[] | Symbol types (e.g., ["Penny", "Non Penny"]) | | trade_types | string[] | Trade types (e.g., ["Simple Order"]) |

PaginatedResponse<T> — returned by list(), getResultsByVersion()

| Field | Type | Description | |---|---|---| | data | T[] | Results for the current page | | total_records | number | Total number of records matching the query | | page_size | number | Number of records per page | | total_pages | number | Total number of pages | | current_page | number | Current page number (zero-based) | | query_time_ms | number \| null | Server-side query execution time in milliseconds |

Maintainers

Requirements

  • Node.js 18+ (uses native fetch)
  • TypeScript 5.4+ (optional, for type checking)

License

MIT — see LICENSE for details.