Skip to content

mjesuele/fred-client

Repository files navigation

@mjesuele/fred-client

A modern, type-safe TypeScript client for the Federal Reserve Economic Data (FRED) API.

CI npm version License: MIT

Quick Navigation

Getting Started:

Documentation:

Examples:

Contributing:

Features

  • Zero runtime dependencies - Uses native Node.js Fetch API
  • TypeScript-first - Built with TypeScript 5.9.x strict mode
  • Dual module format - ESM and CJS support via tsup
  • 1:1 FRED API mapping - Direct correspondence to FRED endpoints
  • Automatic retry - Exponential backoff with jitter (opt-in)
  • Rate limiting - Token bucket algorithm (opt-in)
  • In-memory caching - TTL-based caching (opt-in)
  • Type-safe - Runtime validation with detailed error messages
  • Auto-pagination - Async iterators for paginated results
  • Security-first - Automatic API key redaction in errors

Installation

npm install @mjesuele/fred-client

Requirements:

Quick Start

import { FREDClient } from "@mjesuele/fred-client";

// Create a client
const client = new FREDClient({
  apiKey: "your-api-key-here",
});

// Get series metadata
const gdp = await client.series.get({ seriesId: "GDP" });
console.log(gdp.title); // "Gross Domestic Product"
console.log(gdp.units); // "Billions of Dollars"
console.log(gdp.frequency); // "Quarterly"

// Get observations (data points)
const observations = await client.series.getObservations({
  seriesId: "GDP",
  observationStart: "2020-01-01",
  observationEnd: "2023-12-31",
});

// observations is an array of { date, value } objects
for (const obs of observations) {
  console.log(`${obs.date}: ${obs.value}`);
}

// Search for series
const searchResults = await client.series.search({
  searchText: "unemployment rate",
  limit: 10,
});

console.log(`Found ${searchResults.metadata.count} series`);
for (const series of searchResults.data) {
  console.log(`${series.id}: ${series.title}`);
}

Usage Examples

Working with Categories

// Get root category
const root = await client.categories.get();

// Get child categories
const children = await client.categories.getChildren({
  categoryId: 0,
  limit: 10,
});

// Get series in a category
const series = await client.categories.getSeries({
  categoryId: 125,
  limit: 20,
});

Working with Series

// Search for series
const results = await client.series.search({
  searchText: "unemployment rate",
  limit: 10,
});

// Get series with specific tags
const taggedSeries = await client.series.search({
  searchText: "gdp",
  tagNames: ["quarterly", "usa"],
});

// Get series metadata
const series = await client.series.get({ seriesId: "UNRATE" });

// Get observations with date range
const obs = await client.series.getObservations({
  seriesId: "UNRATE",
  observationStart: "2023-01-01",
  limit: 100,
});

Working with Releases

// List all releases
const releases = await client.releases.list({ limit: 50 });

// Get a specific release
const release = await client.releases.get({ releaseId: 50 });

// Get release dates
const dates = await client.releases.getDates({
  releaseId: 50,
  includeReleaseDatesWithNoData: false,
});

// Get series in a release
const series = await client.releases.getSeries({
  releaseId: 50,
  limit: 20,
});

Auto-Pagination with Async Iterators

// Manually handle pagination
const page1 = await client.series.search({
  searchText: "inflation",
  limit: 100,
  offset: 0,
});

const page2 = await client.series.search({
  searchText: "inflation",
  limit: 100,
  offset: 100,
});

// Or use async iterator for automatic pagination
for await (const batch of client.series.searchIterate({
  searchText: "inflation",
  limit: 100,
})) {
  // Process each batch of 100 results
  console.log(`Processing ${batch.length} results`);
}

Configuration

Basic Configuration

const client = new FREDClient({
  apiKey: "your-api-key",
  baseUrl: "https://api.stlouisfed.org/fred", // Optional, uses default
});

Retry Policy

const client = new FREDClient({
  apiKey: "your-api-key",
  retry: {
    maxRetries: 3,
    initialDelayMs: 1000,
    maxDelayMs: 10000,
    retryableStatusCodes: [429, 500, 502, 503, 504],
  },
});

Rate Limiting

const client = new FREDClient({
  apiKey: "your-api-key",
  rateLimit: {
    requestsPerSecond: 5,
    burstSize: 10,
  },
});

Caching

const client = new FREDClient({
  apiKey: "your-api-key",
  cache: {
    ttlSeconds: 300, // 5 minutes
    maxEntries: 1000, // Max cached responses
    keyPrefix: "fred:", // Cache key prefix
  },
});

Custom Fetch Implementation

import { fetch as undiciFetch } from "undici";

const client = new FREDClient({
  apiKey: "your-api-key",
  fetch: undiciFetch, // Use custom fetch implementation
});

Derived Clients with with()

const baseClient = new FREDClient({ apiKey: "your-api-key" });

// Create a client with different retry settings
const retryClient = baseClient.with({
  retry: { maxRetries: 5 },
});

// Create a cached client for expensive queries
const cachedClient = baseClient.with({
  cache: { ttlSeconds: 600, maxEntries: 500 },
});

API Documentation

Namespaces

The client is organized into namespaces that mirror the FRED API structure:

  • client.categories - Browse and search the FRED category structure
  • client.releases - Access economic data releases
  • client.series - Work with data series and observations
  • client.sources - Explore data sources
  • client.tags - Search and filter using tags
  • client.relatedTags - Discover related tags

For detailed API documentation, see docs/api.md.

Error Handling

All errors are instances of FREDClientError with structured information:

import { FREDClientError } from "@mjesuele/fred-client";

try {
  const series = await client.series.get({ seriesId: "INVALID" });
} catch (error) {
  if (error instanceof FREDClientError) {
    console.error("Status:", error.status); // HTTP status code
    console.error("URL:", error.url); // Request URL (API key redacted)
    console.error("Params:", error.params); // Request parameters (API key redacted)
    console.error("Excerpt:", error.bodyExcerpt); // Response excerpt

    // Handle specific errors
    if (error.status === 404) {
      console.error("Series not found");
    } else if (error.status === 429) {
      console.error("Rate limited - slow down requests");
    }
  }
  throw error;
}

Automatic Retry and Rate Limiting:

const client = new FREDClient({
  apiKey: "your-api-key",
  retry: {
    maxAttempts: 3, // Retry transient errors
    baseDelayMs: 1000,
    useJitter: true,
  },
  rateLimit: {
    maxBurst: 10,
    refillRate: 2, // 2 req/sec = 120/min
  },
});

// Requests automatically retry on 429, 500, 502, 503, 504
// Rate limiting prevents hitting API limits

Learn More:

TypeScript Support

This library is written in TypeScript and provides full type definitions:

import type {
  FREDClient,
  FREDClientConfig,
  Series,
  Observation,
  Page,
  PageIterator,
} from "@mjesuele/fred-client";

// All types are exported for your convenience
const config: FREDClientConfig = {
  apiKey: "your-api-key",
  retry: { maxRetries: 3 },
};

const client = new FREDClient(config);

Contributing

We welcome contributions! Please see CONTRIBUTING.md for:

  • Quick start guide (≤15 minutes setup)
  • Development workflow
  • Coding standards
  • Commit message conventions
  • Pull request process

Key principles:

  • Zero runtime dependencies (NON-NEGOTIABLE)
  • TypeScript-first with strict mode
  • Native Fetch API only
  • 1:1 mapping to FRED API structure

License

MIT - see LICENSE for details.

Resources

Acknowledgments

This project is not affiliated with or endorsed by the Federal Reserve Bank of St. Louis. FRED® is a registered trademark of the Federal Reserve Bank of St. Louis.

About

TypeScript client for the St. Louis Federal Reserve FRED API

Resources

License

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors