| Crates.io | edgarkit |
| lib.rs | edgarkit |
| version | 0.1.0 |
| created_at | 2025-12-16 09:28:52.928233+00 |
| updated_at | 2025-12-16 09:28:52.928233+00 |
| description | An unofficial Rust client for the SEC EDGAR system |
| homepage | |
| repository | https://github.com/r007/edgarkit |
| max_upload_size | |
| id | 1987437 |
| size | 288,215 |
An unofficial Rust client for the SEC EDGAR (Electronic Data Gathering, Analysis, and Retrieval) system.
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:
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:
If you’ve hit bottlenecks with scripting solutions, EdgarKit lets you keep the developer ergonomics while upgrading performance and reliability.
Add EdgarKit to your Cargo.toml:
[dependencies]
edgarkit = "0.1.0"
tokio = { version = "1", features = ["full"] }
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)
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(())
}
Understanding common forms helps target the right data:
Other frequent forms for governance and ownership:
NCEN, N-PORT, N-CSRDetailedFiling.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.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.crabrl: High-performance XBRL parser and validator for financial statements. Parse us-gaap concepts at scale. https://crates.io/crates/crabrlquick-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-xmlrig.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/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.
Examples are provided in the examples/ directory to keep this README concise.
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(())
}
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(())
}
Check out the examples/ directory for comprehensive examples:
basic_usage.rs - Getting started with EdgarKitsearch_filings.rs - Advanced search patternsdownload_filings.rs - Filing retrieval and processingrss_feeds.rs - Working with RSS/Atom feedsindex_operations.rs - Index file operationsRun any example with:
cargo run --example basic_usage --all-features
EdgarKit includes two standalone CLI tools in the examples/ directory that demonstrate real-world usage:
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
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
EdgarKit automatically handles rate limiting to comply with SEC.gov's fair access policy:
EdgarConfiguse 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)?;
When using EdgarKit, please follow SEC.gov's guidelines:
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),
}
Full API documentation is available at docs.rs/edgarkit.
Contributions are welcome! Please feel free to submit a Pull Request.
git clone https://github.com/r007/edgarkit.git
cd edgarkit
cargo build --all-features
cargo test --all-features
# 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
This project is licensed under the MIT License - see the LICENSE file for details.
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.Created by Sergey Monin
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