Installation

npm install rulebook-sdk
Requires Node.js 18+ (uses native fetch). TypeScript 5.4+ recommended for type checking.

Initialize the Client

import { Rulebook } from "rulebook-sdk";

const client = new Rulebook({ apiKey: "your-api-key" });
Or set the RULEBOOK_API_KEY environment variable and omit the parameter:
export RULEBOOK_API_KEY="your-api-key"
import { Rulebook } from "rulebook-sdk";

const client = new Rulebook(); // reads from RULEBOOK_API_KEY
You can also override the base URL via the RULEBOOK_BASE_URL environment variable:
export RULEBOOK_BASE_URL="https://your-custom-endpoint/api/v1"

List Exchanges

const response = await client.exchanges.list();

for (const ex of response.data) {
  console.log(`${ex.name} (${ex.display_name})`);
  console.log(`  Fee types: ${ex.fee_types}`);
  console.log(`  Records: ${ex.record_count}`);
}

console.log(`Total exchanges: ${response.meta.record_count}`);
Response type: ExchangeListResponse
FieldTypeDescription
dataExchange[]Array of exchange objects
metaMetaResponse metadata

Get Exchange Details

const response = await client.exchanges.retrieve("nasdaq");

const detail = response.data;
console.log(`Date range: ${detail.date_range.earliest} to ${detail.date_range.latest}`);
console.log(`Actions: ${detail.actions}`);
console.log(`Participants: ${detail.participants}`);
console.log(`Fee categories: ${detail.fee_categories}`);
console.log(`Query time: ${response.meta.query_time_ms}ms`);
Response type: ExchangeDetailResponse
FieldTypeDescription
dataExchangeDetailExchange detail object
metaMetaResponse metadata

List Fee Schedule Results

const page = await client.feeScheduleResults.list({
  exchange_name: ["nasdaq"],
  fee_type: ["option"],
  fee_participant: ["market_maker"],
  latest_only: true,
  page_size: 10,
});

console.log(`Total results: ${page.meta.record_count}`);
for (const result of page.data) {
  console.log(`  ${result.fee_action}: ${result.fee_amount} (${result.fee_symbol_type})`);
}
Response type: PaginatedResponse<FeeScheduleResult>
FieldTypeDescription
dataFeeScheduleResult[]Array of result objects
metaMetaPagination metadata
Filter parameters:
ParameterTypeDescription
exchange_namestring[]Filter by exchange name(s)
fee_typestring[]Filter by fee type(s)
fee_categorystring[]Filter by fee category(s)
fee_actionstring[]Filter by trading action(s)
fee_participantstring[]Filter by participant type(s)
fee_symbol_classificationstring[]Filter by symbol classification(s)
fee_symbol_typestring[]Filter by symbol type(s)
fee_trade_typestring[]Filter by trade type(s)
start_datestringFilter by scraped date (YYYY-MM-DD)
end_datestringFilter by scraped date (YYYY-MM-DD)
latest_onlybooleanOnly latest version per exchange
order_bystringSort field (default: created_on)
order_dirstringSort direction: asc or desc
page_sizenumberRecords per page (1–100)
page_numbernumberPage number (0-indexed)
include_footnotesbooleanInclude related footnotes
include_definitionsbooleanInclude related definitions
include_sourcebooleanInclude source document info

Get a Single Fee Schedule Result

const response = await client.feeScheduleResults.retrieve(
  "a3d76e96-0cad-4ece-9db1-7ad3c743bdf8",
  { include_footnotes: true, include_definitions: true, include_source: true }
);

const result = response.data;
console.log(`${result.exchange_name}${result.fee_type}${result.fee_category}`);
console.log(`  Action: ${result.fee_action}`);
console.log(`  Amount: ${result.fee_amount}`);
console.log(`  Participant: ${result.fee_participant}`);
console.log(`Query time: ${response.meta.query_time_ms}ms`);
Response type: FeeScheduleResultResponse
FieldTypeDescription
dataFeeScheduleResultFee schedule result object
metaMetaResponse metadata

Get Available Filters

Discover valid filter values before querying results:
const response = await client.feeScheduleResults.getFilters();

const filters = response.data;
console.log(`Exchanges: ${filters.exchange_names}`);
console.log(`Fee types: ${filters.fee_types}`);
console.log(`Categories: ${filters.fee_categories}`);
console.log(`Actions: ${filters.fee_actions}`);
console.log(`Participants: ${filters.fee_participants}`);
console.log(`Total records: ${response.meta.record_count}`);

// Narrow filters to specific exchanges
const nasdaqFilters = await client.feeScheduleResults.getFilters({
  exchange_name: ["nasdaq", "nasdaq_phlx"],
});
Response type: FeeScheduleResultFiltersResponse
FieldTypeDescription
dataFeeScheduleResultFiltersFilter values object
metaMetaResponse metadata

Get Results by Version

Retrieve all fee schedule results from a specific extraction version:
const page = await client.feeScheduleResults.getResultsByVersion(
  "b962c0b1-5d99-4ef6-b3f6-36cb18c08933",
  { include_source: true, include_footnotes: true, page_size: 50 },
);

console.log(`Version has ${page.meta.record_count} results (${page.meta.total_pages} pages)`);
for (const result of page.data) {
  console.log(`  ${result.fee_action}: ${result.fee_amount}`);
  if (result.source_document) {
    console.log(`    Source: ${result.source_document} (p.${result.page_number})`);
  }
}
Response type: PaginatedResponse<FeeScheduleResult>
FieldTypeDescription
dataFeeScheduleResult[]Array of result objects
metaMetaPagination metadata

Pagination

Fee schedule results are paginated. Use page_number and page_size to iterate:
let page_number = 0;
let totalFetched = 0;

while (true) {
  const page = await client.feeScheduleResults.list({
    latest_only: true,
    page_size: 50,
    page_number,
  });
  totalFetched += page.data.length;
  console.log(`Page ${page_number + 1}/${page.meta.total_pages}: ${page.data.length} results`);

  if (page_number >= page.meta.total_pages - 1) break;
  page_number++;
}

console.log(`Fetched ${totalFetched} of ${page.meta.record_count} total results`);

Async by Default

The TypeScript SDK is async-native — all methods return a Promise and are designed for async/await usage. Unlike the Python SDK which provides separate Rulebook and AsyncRulebook clients, there is no separate sync client.
import { Rulebook } from "rulebook-sdk";

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

main();

Next Steps

Error Handling

Handle API errors with typed exceptions

Advanced Usage

Timeouts, retries, raw responses, and per-request overrides