Filings submitted to the U.S. Securities and Exchange Commission (SEC) are a key source of information about public companies. Analyzing this data can reveal patterns in corporate behavior and market trends, but the sheer volume of filings makes manual review difficult.
This guide shows how to use the FinFeedAPI to programmatically access and analyze SEC filing data. We will cover methods for looking at broad trends using filing metadata and then show how to get specific information from within the documents themselves.
This guide covers:
- Fetching filing metadata based on criteria like form type and date.
- Analyzing filing frequency over time and the distribution of different event items.
- Extracting the structured content from a specific filing.
- Searching for keywords inside the full text of documents.
What you need:
- Python 3.x with
pandas
andmatplotlib
. - The
api-bricks-sec-api-rest
library. - Your personal FinFeedAPI key.
1. Environment Setup
First, you need to install the FinFeedAPI client library if it is not already on your system.
pip install api-bricks-sec-api-rest
Next, prepare your Python script by importing the necessary libraries and configuring the API client with your key.
# Import necessary libraries
import pandas as pd
import matplotlib.pyplot as plt
from datetime import datetime
import api_bricks_sec_api_rest
# --- API Configuration ---
# !!! IMPORTANT: Insert your API Key below !!!
API_KEY = "YOUR_API_KEY_HERE" # <--- REPLACE THIS WITH YOUR ACTUAL KEY!
api_client_config = api_bricks_sec_api_rest.Configuration()
api_client_config.api_key['Authorization'] = API_KEY
api_client = api_bricks_sec_api_rest.ApiClient(configuration=api_client_config)
# --- Plotting Configuration ---
plt.style.use('seaborn-v0_8-darkgrid')
plt.rcParams['figure.figsize'] = (12, 6)
2. Fetching and Analyzing Filing Metadata
The /v1/filings
endpoint lets you retrieve metadata about filings. This is useful for high-level analysis without needing to process the full content of each document.
Let's fetch all Form 8-K filings submitted in the first quarter of 2024 to see some trends. The code below handles pagination to retrieve all records in the specified period.
# Define parameters for the API call
start_date_q1_2024 = "2024-01-01"
end_date_q1_2024 = "2024-03-31"
target_form_type = "8-K"
results_limit = 200 # Maximum results per page
filing_metadata_api = api_bricks_sec_api_rest.FilingMetadataApi(api_client)
all_metadata = []
page_number = 1
while True:
print(f"Fetching metadata for {target_form_type} filings (page {page_number})...")
try:
metadata_list = filing_metadata_api.v1_filings_get(
form_type=target_form_type,
filling_date_start=start_date_q1_2024,
filling_date_end=end_date_q1_2024,
page_size=results_limit,
page_number=page_number
)
if metadata_list:
all_metadata.extend(metadata_list)
if len(metadata_list) < results_limit:
print(" Last page reached.")
break
page_number += 1
else:
print(f" No more data found on page {page_number}.")
break
except api_bricks_sec_api_rest.ApiException as e:
print(f"Exception when calling API: {e}")
break
# Create DataFrame after fetching all data
filings_df = pd.DataFrame.from_records([vars(x) for x in all_metadata])
Filings Per Month
With the metadata loaded into a DataFrame, we can plot the number of 8-K filings submitted each month.
if not filings_df.empty:
filings_df['filing_date'] = pd.to_datetime(filings_df['filing_date'], errors='coerce')
filings_df_cleaned = filings_df.dropna(subset=['filing_date']).set_index('filing_date')
if not filings_df_cleaned.empty:
filings_by_month = filings_df_cleaned.resample('ME').size()
filings_by_month.plot(kind='bar', color='skyblue', edgecolor='black')
plt.title(f'Number of {target_form_type} Filings in Q1 2024 (by Month)')
plt.xlabel('Month')
plt.ylabel('Number of Filings')
plt.xticks(rotation=45, ha='right')
plt.show()
Most Common 8-K Items
We can also analyze the items field to see which types of corporate events were most frequently reported.
if not filings_df.empty and 'items' in filings_df.columns:
all_items = filings_df['items'].str.split(',').explode()
item_counts = all_items.value_counts()
item_counts.plot(kind='bar', color='skyblue', edgecolor='black')
plt.title('Distribution of Items in 8-K Filings')
plt.xlabel('Item Number')
plt.ylabel('Number of Occurrences')
plt.xticks(rotation=45, ha='right')
plt.show()
3. Extracting Specific Filing Content
Once you identify a filing of interest from its metadata, you can retrieve its content.
The /v1/extractor
endpoint gets the full, structured content of a filing.
The /v1/extractor/item
endpoint gets the text of a single item within a filing.
Here is how you can extract the items from the first filing in our dataset.
if not filings_df.empty:
example_accession_number = filings_df['accession_number'].iloc[0]
print(f"\nAttempting to extract structure for filing: {example_accession_number}")
content_extraction_api = api_bricks_sec_api_rest.ContentExtractionApi(api_client)
try:
extracted_data = content_extraction_api.v1_extractor_get(
accession_number=example_accession_number
)
if extracted_data:
print(f"Found {len(extracted_data.items)} items.")
# Display details of the first item
first_item = extracted_data.items[0]
print(f" Item Number: {first_item.item_number}")
print(f" Item Title: {first_item.item_title}")
print(f" Content Preview: {first_item.content[:250]}...")
except api_bricks_sec_api_rest.ApiException as e:
print(f"Exception when extracting content: {e}")
4. Performing a Full-Text Search
For topic-based discovery, the /v1/full-text
endpoint allows you to search for keywords within the documents. This is a good way to find filings related to a specific theme that is not captured in the metadata.
For example, let's find 10-K filings from 2025 that mention "artificial intelligence."
print("\nPerforming full-text search...")
full_text_api = api_bricks_sec_api_rest.FullTextSearchApi(api_client)
try:
search_results = full_text_api.v1_full_text_get(
form_type="10-K",
filling_date_start="2025-01-01",
filling_date_end="2025-12-31",
text_contains="artificial intelligence",
page_size=10
)
if search_results:
search_df = pd.DataFrame.from_records([vars(x) for x in search_results])
print("Full-Text Search Results Sample:")
print(search_df[['company_name', 'filing_date']].head())
except api_bricks_sec_api_rest.ApiException as e:
print(f"Exception during full-text search: {e}")
Final Thoughts
This guide showed several methods for working with SEC filing data using the FinFeedAPI. You can begin with broad, metadata-based analysis to identify trends and then use the extractor and full-text search endpoints to get more specific information. This workflow lets you move from a high-level view of filing activity to a detailed look at the content inside the documents.
From here, you could build more advanced applications, such as applying natural language processing (NLP) to extracted text or correlating filing data with market prices.