Skip to content

r007/edgarkit

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

55 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

EdgarKit

EdgarKit Mascot

Crates.io Documentation License: MIT

An unofficial Rust client for the SEC EDGAR (Electronic Data Gathering, Analysis, and Retrieval) system.

Why EdgarKit

EdgarKit is built for financial apps and high-throughput, production-grade pipelines that need to ingest, search, and process SEC filings reliably and fast. It’s a great fit for:

  • High-performance financial data pipelines (ETL and streaming)
  • Quantitative and fundamental investment research
  • Corporate event tracking and governance analytics
  • Compliance monitoring and audit workflows
  • Building dashboards and alerting for market-moving filings

Rust shines here: many SEC filings (especially S-1, 10-K, 10-Q) are large and complex. Parsing, validating, and extracting structure from these can be very CPU- and IO-intensive. With Rust’s zero-cost abstractions and async runtime, you can scale to millions of documents with predictable latency and minimal overhead.

Compared to Python tools like edgartools or sec-edgar-downloader, Rust typically:

  • Processes heavy filings dramatically faster (no GIL, native threading)
  • Uses far less memory (no large dynamic overhead)
  • Offers compile-time guarantees and stronger type safety
  • Integrates cleanly into modern distributed systems (containers, services)

If you’ve hit bottlenecks with scripting solutions, EdgarKit lets you keep the developer ergonomics while upgrading performance and reliability.

Features

  • 🚦 Rate-Limited HTTP Client - Automatic compliance with SEC.gov fair access rules
  • 📄 Filing Operations - Access company filings, submissions, and documents
  • 🏢 Company Information - Retrieve company facts, tickers, and metadata
  • 🔍 Search Capabilities - Find filings with customizable search criteria
  • 📡 Feed Operations - Monitor Atom and RSS feeds for filings and news
  • 📊 Index Operations - Download and parse daily and quarterly filing indices
  • ⚡ Async-First - Built on tokio for high-performance concurrent operations
  • 🎯 Type-Safe - Strongly-typed API with comprehensive error handling
  • 🔧 Flexible - Feature flags for modular compilation

Installation

Add EdgarKit to your Cargo.toml:

[dependencies]
edgarkit = "0.1.0"
tokio = { version = "1", features = ["full"] }

Feature Flags

EdgarKit uses feature flags to allow you to compile only what you need:

[dependencies]
edgarkit = { version = "0.1.0", features = ["search", "filings", "company"] }

Available features:

  • search - Search API functionality (requires serde_urlencoded, futures)
  • filings - Filing operations (requires flate2, chrono)
  • company - Company information APIs (requires chrono)
  • feeds - RSS/Atom feed support (requires quick-xml)
  • index - Index file operations (requires flate2, chrono, regex)

Default features: ["search", "filings", "company", "feeds", "index"] (all features enabled)

Quick Start

use edgarkit::{Edgar, FilingOperations, FilingOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // Initialize the client with a proper user agent
    // SEC.gov requires format: "AppName contact@example.com"
    let edgar = Edgar::new("MyApp contact@example.com")?;
    
    // Get recent 10-K filings for Apple (CIK: 320193)
    let options = FilingOptions::new()
        .with_form_type("10-K")
        .with_limit(5);
    
    let filings = edgar.filings("320193", Some(options)).await?;
    
    for filing in filings {
        println!("Filed: {} - {}", filing.filing_date, filing.form);
    }
    
    Ok(())
}

Filing Types You’ll Use Most

Understanding common forms helps target the right data:

Other frequent forms for governance and ownership:

  • 3/4/5: Insider ownership changes
  • Schedule 13D/13G: Beneficial ownership disclosures
  • Form D: Exempt offerings
  • Investment company forms like NCEN, N-PORT, N-CSR

Tips & Tricks

  • DetailedFiling.items: Quickly scan 8-K items to identify important events. The official 8-K item reference is here: https://www.sec.gov/files/form8-k.pdf. For example, items like 1.01, 2.03, 5.01 indicate significant agreements, creation of liabilities, or a change in control of registrant (5.01).
  • is_xbrl vs is_inline_xbrl: Indicates whether the filing contains XBRL (machine-readable financials) or Inline XBRL (embedded in HTML). Use XBRL parsers for precise numeric extraction; Inline XBRL often improves context and presentation.
  • primary_document: Often the main HTML/XML file to parse. If you fetch the text filing, the primary document usually appears first.
  • Use feature filters and FilingOptions to constrain the workload (form types, limits, offsets). For S-1 workflows, consider including amendments (S-1/A) or disabling them when you need only originals.

Companion Crates (Recommended)

  • crabrl: High-performance XBRL parser and validator for financial statements. Parse us-gaap concepts at scale. https://crates.io/crates/crabrl
  • quick-xml: Fast XML parsing, perfect for lightweight forms (3/4/5, Form D, NCEN, Schedule 13D/13G) and structured feeds. https://crates.io/crates/quick-xml
  • rig.rs: For complex, narrative-heavy filings (S-1, 10-K, 10-Q), use rig.rs with strong models (DeepSeek 3.2, Claude Haiku 4.5, Qwen Plus) to extract sections, summarize, and classify. https://rig.rs/

Why Rust (A Short Story)

I originally built a filing pipeline in TypeScript. It worked—until it needed to process heavy S-1 filings at scale. Regex-based parsing slowed to a crawl, memory usage spiked, and throughput collapsed. Rewriting the pipeline in Rust solved the core problems: faster IO, deterministic performance, safe concurrency, and efficient parsing. EdgarKit is the distilled client layer born from that migration.

Usage Examples

Examples are provided in the examples/ directory to keep this README concise.

Download Filing Content

use edgarkit::{Edgar, FilingOperations};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let edgar = Edgar::new("MyApp contact@example.com")?;
    
    // Get the latest 10-K for a company
    let content = edgar.get_latest_filing_content("320193", &["10-K"]).await?;
    
    // Save to file or process the content
    println!("Downloaded {} bytes", content.len());
    
    Ok(())
}

Access Index Files

use edgarkit::{Edgar, EdgarDay, IndexOperations, FilingOptions};

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let edgar = Edgar::new("MyApp contact@example.com")?;
    
    // Get all filings from a specific day
    let day = EdgarDay::new(2024, 8, 15)?;
    let options = FilingOptions::new().with_form_type("10-K");
    
    let filings = edgar.get_daily_filings(day, Some(options)).await?;
    
    for filing in filings {
        println!("{} - {}", filing.company_name, filing.form_type);
    }
    
    Ok(())
}

More Examples

Check out the examples/ directory for comprehensive examples:

Run any example with:

cargo run --example basic_usage --all-features

Mini-Projects

EdgarKit includes two standalone CLI tools in the examples/ directory that demonstrate real-world usage:

IPO Scanner

Scans recent EDGAR daily indices for S-1 filings (IPOs) and displays them in an interactive terminal UI (TUI).

# Run from examples/ipo-scanner
cargo run --release -- --weekly

Investment Adviser

A CLI that fetches the latest 10-K/10-Q filings and uses an LLM (via OpenRouter) to generate investment recommendations.

# Run from examples/investment-adviser
export OPENROUTER_API_KEY="..."
cargo run --release -- --ticker AAPL --model deepseek/deepseek-v3.2

Rate Limiting

EdgarKit automatically handles rate limiting to comply with SEC.gov's fair access policy:

  • Default: 10 requests per second
  • Configurable: Adjust via EdgarConfig
  • Automatic retry: Exponential backoff on rate limit errors
use edgarkit::{Edgar, EdgarConfig, EdgarUrls};
use std::time::Duration;

let config = EdgarConfig {
    user_agent: "MyApp contact@example.com".to_string(),
    rate_limit: 5, // 5 requests per second
    timeout: Duration::from_secs(30),
    base_urls: EdgarUrls::default(),
};

let edgar = Edgar::with_config(config)?;

SEC.gov Compliance

When using EdgarKit, please follow SEC.gov's guidelines:

  1. User Agent Required: Always provide a descriptive user agent with contact information
  2. Rate Limiting: Respect the 10 requests/second limit (enforced automatically)
  3. Fair Use: Avoid excessive bulk downloading during peak hours (9 AM - 5 PM ET)
  4. Terms of Service: Review SEC.gov's guidelines

Error Handling

EdgarKit provides comprehensive error types:

use edgarkit::{Edgar, EdgarError, FilingOperations};

match edgar.filings("invalid-cik", None).await {
    Ok(filings) => println!("Found {} filings", filings.len()),
    Err(EdgarError::NotFound) => println!("Company not found"),
    Err(EdgarError::RateLimitExceeded) => println!("Rate limit hit"),
    Err(e) => println!("Error: {}", e),
}

Documentation

Full API documentation is available at docs.rs/edgarkit.

Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

Development Setup

git clone https://github.com/r007/edgarkit.git
cd edgarkit
cargo build --all-features
cargo test --all-features

Running Tests

# Run unit tests
cargo test --lib

# Run all tests including integration tests
cargo test --all-features

# Run integration tests separately (requires network)
cargo test --all-features -- --ignored

License

This project is licensed under the MIT License - see the LICENSE file for details.

Acknowledgments

  • Inspired in part by Joey Chilson’s work-in-progress edgar_client (Elixir/Rust). Thanks to Joey for publishing the endpoint URLs and early implementation ideas that helped shape this client; EdgarKit rewrites and extends those concepts in a Rust-first, consistent API.
  • Built with reqwest for HTTP requests
  • Rate limiting via governor
  • XML parsing with quick-xml
  • Powered by the tokio async runtime

Author

Created by Sergey Monin

Disclaimer

This library is not affiliated with or endorsed by the U.S. Securities and Exchange Commission. Please ensure your use complies with SEC.gov's terms of service and applicable regulations.


Made with ❤️ for the Rust community

About

An unofficial Rust client for the SEC EDGAR (Electronic Data Gathering, Analysis, and Retrieval) system.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages