Prospectus Supplements (424B): Parse Offering Terms from SEC Filings
Overview
424B filings are prospectus supplements that companies file when they sell securities off a shelf registration (S-3/F-3). They contain the final deal terms: price, shares, proceeds, underwriting fees, and dilution impact. EdgarTools parses all 424B variants into a Prospectus424B object, with a Deal property that normalizes everything into clean numeric values.
| Form | Typical Use |
|---|---|
| 424B2 | Structured notes, debt (large banks) |
| 424B3 | Resale prospectuses (PIPE resales) |
| 424B4 | Final priced prospectuses (IPOs) |
| 424B5 | Shelf takedowns (ATM, firm commitment, PIPE) |
Quick Start
from edgar import Company
company = Company("ALZN")
filing = company.get_filings(form="424B5")[0]
prospectus = filing.obj() # Prospectus424B
deal = prospectus.deal # Deal: normalized summary
deal.price # 2.48
deal.shares # 1_500_000
deal.gross_proceeds # 3_720_000.0
deal.lead_bookrunner # "H.C. Wainwright & Co."
The Deal Object
Access via prospectus.deal. Always returns a Deal object (never None). Individual properties return None when data is unavailable.
Core Deal Terms
| Property | Type | Description |
|---|---|---|
price |
float \| None |
Per-unit offering price |
shares |
int \| None |
Number of shares offered |
gross_proceeds |
float \| None |
Total offering amount (before fees) |
net_proceeds |
float \| None |
Proceeds after underwriting fees |
security_type |
str \| None |
Security description ("Common Stock", "Senior Notes") |
offering_type |
OfferingType |
Enum: FIRM_COMMITMENT, ATM, BEST_EFFORTS, etc. |
is_atm |
bool |
Whether this is an at-the-market offering |
Underwriting Economics
| Property | Type | Description |
|---|---|---|
fee_per_share |
float \| None |
Per-unit underwriting discount |
total_fees |
float \| None |
Total underwriting fees |
discount_rate |
float \| None |
Fee as fraction of price (0.05 = 5%) |
fee_type |
str \| None |
"underwriting_discount" or "placement_agent_fees" |
lead_bookrunner |
str \| None |
Lead underwriter or placement agent |
underwriter_count |
int |
Number of underwriters in syndicate |
Dilution (Equity Offerings Only)
| Property | Type | Description |
|---|---|---|
dilution_per_share |
float \| None |
Dilution to new investors |
dilution_pct |
float \| None |
Dilution as percentage |
shares_before |
int \| None |
Shares outstanding before offering |
shares_after |
int \| None |
Shares outstanding after offering |
ntbv_before |
float \| None |
Net tangible book value per share before |
ntbv_after |
float \| None |
Net tangible book value per share after |
Serialization
deal.to_dict() # Flat dict of all non-None values (good for DataFrames)
deal.to_context() # Markdown-KV text for LLM prompts
Offering Classification
The offering_type property classifies the deal:
| Value | Description | Price/Shares Available? |
|---|---|---|
FIRM_COMMITMENT |
Bank buys all shares, resells | Yes |
ATM |
At-the-market (sold gradually) | Usually no (market price) |
BEST_EFFORTS |
Agent sells on best-efforts basis | Yes |
PIPE_RESALE |
Resale of privately placed shares | Varies |
STRUCTURED_NOTE |
Bank-issued structured product | Different meaning |
DEBT_OFFERING |
Corporate bonds / notes | Usually percentage |
if deal.is_atm:
# Price and shares are typically None for ATM offerings
print(f"ATM program: up to ${deal.gross_proceeds:,.0f}")
else:
print(f"{deal.shares:,} shares @ ${deal.price:.2f}")
Prospectus Sub-Objects
The Prospectus424B exposes the raw extracted data that the Deal synthesizes:
prospectus.cover_page # CoverPageData: company, registration, flags
prospectus.pricing # PricingData: per-unit and total columns
prospectus.underwriting # UnderwritingInfo: syndicate, fee type
prospectus.offering_terms # OfferingTerms: shares, warrants, use of proceeds
prospectus.selling_stockholders # SellingStockholdersData: PIPE resale tables
prospectus.dilution # DilutionData: NTBV impact table
prospectus.capitalization # CapitalizationData: actual vs. as-adjusted
prospectus.structured_note_terms # StructuredNoteTerms: CUSIP, maturity (424B2)
prospectus.filing_fees # FilingFeesData: from XBRL exhibit
Selling Stockholders (PIPE Resale Filings)
For PIPE resale prospectuses (typically 424B3), the selling stockholders table lists investors reselling privately placed shares:
ss = prospectus.selling_stockholders # SellingStockholdersData or None
if ss:
ss.count # Number of selling stockholders
for entry in ss.stockholders:
entry.name # "Lincoln Park Capital Fund, LLC"
entry.shares # 1500000 (parsed int, None on failure)
entry.shares_before # 2000000
entry.shares_after # 500000
entry.pct_before # 9.5 (parsed float)
entry.pct_after # 2.8
entry.warrants # 750000 (warrants/convertibles, if present)
Raw string values are always preserved (shares_offered, shares_before_offering, etc.). The numeric properties (shares, shares_before, etc.) parse them to int/float, returning None on failure.
DataFrame Output
df = ss.to_dataframe()
# Returns DataFrame with numeric columns:
# name | shares_before | pct_before | shares_offered | shares_after | pct_after | warrants
Offering Type Check
if prospectus.offering_type.has_selling_stockholders:
# This is a PIPE_RESALE or BASE_PROSPECTUS_UPDATE
ss = prospectus.selling_stockholders
Shelf Lifecycle
Track where a prospectus sits in its shelf registration lifecycle:
lc = prospectus.lifecycle # ShelfLifecycle
lc.takedown_number # 3 (this is the 3rd offering)
lc.total_takedowns # 5
lc.shelf_expires # date(2027, 8, 2)
lc.avg_days_between_takedowns # 180.0
lc.shelf_registration # Filing object for the S-3
To navigate the other direction -- from the S-3 shelf forward to its 424B takedowns -- use the RegistrationS3 data object. filing.obj() returns it automatically for S-3, S-3/A, S-3ASR, S-3D, and S-3DPOS filings.
from edgar import Company
company = Company("ALZN")
s3_filing = company.get_filings(form="S-3")[0]
s3 = s3_filing.obj() # RegistrationS3
s3.total_offering # total registered amount in dollars
s3.takedowns # Filings with all 424B forms from this shelf
s3.offering_type.display_name # "Resale Registration"
See the S-3 Registration Statement guide for the full API.
Working with Multiple Offerings
Build a DataFrame of a company's offering history:
import pandas as pd
from edgar import Company
company = Company("ALZN")
filings = company.get_filings(form="424B5")
rows = []
for filing in filings:
prospectus = filing.obj()
d = prospectus.deal.to_dict()
d['filing_date'] = str(filing.filing_date)
rows.append(d)
df = pd.DataFrame(rows)
Rich Display
Both Prospectus424B and Deal render as Rich panels in terminals and notebooks:
prospectus # Shows cover page, pricing table, underwriting
prospectus.deal # Compact deal summary panel