Metadata-Version: 2.5
Name: sec-daily-api
Version: 0.5.1
Summary: Official Python SDK for the SEC Daily API — real-time SEC EDGAR filings, company data, and news.
Project-URL: Homepage, https://www.secdailyapi.com
Project-URL: Documentation, https://www.secdailyapi.com/docs
Project-URL: Pricing, https://www.secdailyapi.com/pricing
Author: GoodTech LLC
License-Expression: Apache-2.0
License-File: LICENSE
Keywords: 10-k,10-q,13f,8-k,api-client,edgar,filings,financial-data,fintech,form-4,insider-trading,quantitative-finance,sec
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Financial and Insurance Industry
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Topic :: Office/Business :: Financial :: Investment
Classifier: Typing :: Typed
Requires-Python: >=3.8
Description-Content-Type: text/markdown

# SEC Daily API — Python SDK

Official Python SDK for the [SEC Daily API](https://www.secdailyapi.com) — real-time SEC EDGAR filings, company data, and news.

> **Using Claude, Cursor, ChatGPT, or another AI assistant?** Use the [sec-daily-mcp](https://www.npmjs.com/package/sec-daily-mcp) package instead — it connects your AI tool directly to the SEC Daily API with no code required.

## Installation

```bash
pip install sec-daily-api
```

Requires Python 3.8+. No runtime dependencies.

## Quick Start

```python
import os
from sec_daily_api import SecDailyAPI

client = SecDailyAPI(api_key=os.environ["SEC_DAILY_API_KEY"])

# Get Apple's latest 10-K filings
result = client.get_filings(ticker="AAPL", form_types="10-K", limit=5)

for filing in result["filings"]:
    print(filing["filingDate"], filing["formType"], filing.get("summary", ""))
```

Get your API key at [secdailyapi.com](https://www.secdailyapi.com).

---

## API Reference

For the full reference including all parameters, response schemas, and plan limits, see [secdailyapi.com/docs](https://www.secdailyapi.com/docs).

### `SecDailyAPI(api_key=None, *, timeout=30.0)`

| Argument | Type | Description |
|---|---|---|
| `api_key` | `str` | Your API key. Defaults to `SEC_DAILY_API_KEY` env var |
| `timeout` | `float` | Per-request socket timeout in seconds (default 30) |

---

### `get_filings(**params)`

Search and filter SEC EDGAR filings.

```python
result = client.get_filings(
    ticker="AAPL",
    form_types=["10-K", "10-Q"],
    filing_date_start="2025-01-01",
    filing_date_end="2025-12-31",
    limit=50,
)
for filing in result["filings"]:
    # acceptanceDateTime is absent for most filings before 2025
    print(filing["formType"], filing["filingDate"], filing.get("acceptanceDateTime"))
```

| Parameter | Type | Description |
|---|---|---|
| `ticker` | `str` | Company ticker, e.g. `"AAPL"` |
| `cik` | `str` | Company CIK (numeric) |
| `accession_number` | `str` | Exact SEC accession number |
| `form_types` | `str \| list[str]` | e.g. `"10-K"`, `["10-K","10-Q"]`, `"8-K"`, `"4"` |
| `filing_date` | `str` | Exact filing date `YYYY-MM-DD` (SEC's official filing date, `filingDate`) |
| `filing_date_start` | `str` | Date range start `YYYY-MM-DD` |
| `filing_date_end` | `str` | Date range end `YYYY-MM-DD` |
| `fieldset` | `"minimal" \| "standard" \| "full"` | Response size control |
| `fields` | `str \| list[str]` | Fields to return, e.g. `"filingDate,acceptanceDateTime,filingIndexUrl"` |
| `limit` | `int` | Results per page, default 200, max 1000 |
| `cursor` | `str` | Pagination cursor from a previous response |

**Response:** dict with `filings` (list), `count` (int), `pagination` (dict with `hasMore` and optional `nextCursor`).

#### Filing fields

Each filing is a dict described by the `Filing` type. Every field is optional. The main ones:

| Field | Description |
|---|---|
| `id`, `accessionNumber` | Our filing id and SEC's accession number |
| `formType`, `formFamily`, `isAmendment` | SEC's exact form name (`"10-K/A"`); the family that groups its variants (`10-K`, `10-K405` and `10-K/A` are all `"10-K"`); whether it is an amendment |
| `filingDate` | SEC's official filing date, `YYYY-MM-DD` (Eastern by definition). An evening filing can be dated the next business day |
| `acceptanceDateTime` | When SEC accepted the filing, ISO 8601 UTC ending in `Z`, from SEC's filing header. **Absent** when the header has no acceptance time (most filings before 2025) |
| `periodOfReport`, `effectivenessDate` | Period the filing reports on; effectiveness date |
| `cik`, `companyName` | The main company and its name at filing time |
| `entities` | Every party: list of `{cik, name, role}`, at most 100 (`entitiesTruncated` is `True` beyond that). `role` is SEC's header role: `"Filer"`, `"Issuer"`, `"Subject"`, `"Reporting Owner"`, `"Filed by"` |
| `items` | 8-K items as a string, e.g. `"2.02, 9.01"` |
| `filingIndexUrl`, `submissionTextUrl`, `primaryDocumentUrl` | Links to the filing's index page, complete submission text file, and primary document on SEC.gov |
| `primaryDocument`, `primaryDocDescription` | The primary document's path inside the filing folder (e.g. `"aapl-20250927.htm"`) and description |
| `documentFormatFiles`, `dataFiles` | Documents and data files with `url`, `type`, `description`, `size`, `seq`; at most 1,000 (`documentsTruncated` is `True` beyond that) |
| `documentTypes`, `publicDocumentCount`, `size` | Document types (e.g. `["8-K", "EX-99.1"]`), public document count, bytes in the whole submission |
| `otherFormTypes`, `groupMembers`, `fundSeries` | The other form name on a combined filing; 13D/G group members; fund series and classes |
| `act`, `fileNumber`, `filmNumber`, `coreType`, `isXBRL`, `isInlineXBRL`, `isXBRLNumeric` | SEC's submission fields |
| `textChars` | Length of the stored text, when there is some |
| `entity`, `markdown`, `summary` | Company profile, filing text, AI summary |

#### Deprecated fields

These are still returned for now and stay in the `Filing` type, but will be removed in a later API version. Move to the new names:

| Deprecated | Use instead |
|---|---|
| `filingDateInEst` | `filingDate` |
| `filingMonth` | `filingDate[:7]` |
| `filingDateInUtc` | `acceptanceDateTime[:10]`, or `filingDate` |
| `filingTimeInEst`, `filingTimeInUtc`, `acceptanceDateTimeInEst`, `acceptanceDateTimeInUtc` | `acceptanceDateTime` |
| `linkToFilingDetail`, `linkToFiling` | `filingIndexUrl` |
| `linkToSubmissionTxt`, `linkToTxt` | `submissionTextUrl` |
| `linkToPrimaryDocument` | `primaryDocumentUrl` |
| `filers` | `entities` |
| `linksToDocuments` | `documentFormatFiles[].url` |

Note: when SEC's header has no acceptance time, `filingTimeInEst` and `filingTimeInUtc` show a made-up noon Eastern placeholder, while `acceptanceDateTime` is absent. Use `filing.get("acceptanceDateTime")` and handle `None`.

---

### `iter_filings(**params)`

Auto-paginating generator that yields individual filings across all pages.

```python
# Walk all of Apple's 10-K filings without managing cursors yourself
for filing in client.iter_filings(ticker="AAPL", form_types="10-K", limit=1000):
    print(filing["id"], filing["filingDate"])
```

Accepts the same filters as `get_filings`. Each page counts against your quota — use a larger `limit` to minimize requests.

---

### `get_filing(id)`

Fetch a single filing by its internal ID. Returns `None` if not found.

```python
filing = client.get_filing("abc123...")
```

---

### `get_filing_by_accession(accession_number)`

Fetch a single filing by its SEC accession number. Returns `None` if not found.

```python
filing = client.get_filing_by_accession("0001193125-24-012345")
```

---

### `get_entity(*, ticker=None, cik=None)`

Look up a company's SEC profile. Provide either `ticker` or `cik`.

```python
entity = client.get_entity(ticker="AAPL")
print(entity["name"], entity["cik"], entity["sicDescription"])
```

Returns a dict with: `cik`, `name`, `ticker`, `exchange`, `sicCode`, `sicDescription`, `stateOfIncorporation`, `fiscalYearEnd`, `businessAddress`, `website`, `formerNames`, and more. Returns `None` if not found.

---

### `get_news(**params)`

Retrieve SEC press releases and market news.

```python
result = client.get_news(
    news_type="PressReleases",
    start_date="2026-01-01",
    end_date="2026-01-31",
    limit=40,
)
for item in result["news"]:
    print(item["date"], item["newsType"])
```

| Parameter | Type | Description |
|---|---|---|
| `news_type` | `str` | News category (default: `"PressReleases"`) |
| `start_date` | `str` | Date range start `YYYY-MM-DD` |
| `end_date` | `str` | Date range end `YYYY-MM-DD` |
| `limit` | `int` | Results, default 40, max 100 |

---

### `get_news_item(id)`

Fetch a single news item by ID. Returns `None` if not found.

---

## Dates and times

A filing carries two times, and they answer different questions:

- **`filingDate`** (`YYYY-MM-DD`) is SEC's official filing date. It is an Eastern date by definition, so don't convert it to another time zone. A filing accepted after about 5:30 pm ET is dated the next business day. Filter and group by this field.
- **`acceptanceDateTime`** is the exact moment SEC accepted the filing, in UTC (`"2026-04-20T21:29:51Z"`). It is absent for most filings before 2025, because SEC's header has no acceptance time for them.

To get the acceptance time in a time zone, use `accepted_at`. It returns a timezone-aware `datetime`:

```python
from sec_daily_api import accepted_at

accepted_at(filing)                       # 2026-04-20 21:29:51+00:00 (UTC)
accepted_at(filing, "America/New_York")   # 2026-04-20 17:29:51-04:00 (Eastern, SEC's own time)
accepted_at(filing, "Asia/Tokyo")         # 2026-04-21 06:29:51+09:00
```

It returns `None` when the filing has no `acceptanceDateTime`; fall back to `filingDate` for the day. Daylight saving is applied for the filing's own date. Time zone names need Python 3.9+ (on 3.8, pass a `tzinfo` object), and on Windows `pip install tzdata`. An unknown name raises `ValueError`.

---

## TypeScript / type checking

Full type stubs are included. All response shapes are described as `TypedDict` classes.

```python
from sec_daily_api import Filing, FilingParty, Entity, NewsItem, FilingsResponse
```

---

## Error handling

```python
from sec_daily_api import SecDailyAPI, SecDailyAPIError

try:
    result = client.get_filings(ticker="AAPL")
except SecDailyAPIError as err:
    print(err.status, err)  # e.g. 403, "SecDaily API error 403: Forbidden"
```

| Status | Meaning |
|---|---|
| 400 | Invalid parameters |
| 403 | Invalid or missing API key |
| 429 | Rate limit exceeded — retried automatically up to 3 times |
| 504 | Request timed out — retried automatically up to 3 times |
| 500 | Server error |

---

## Resources

- Docs: [secdailyapi.com/docs](https://www.secdailyapi.com/docs)
- Pricing: [secdailyapi.com/pricing](https://www.secdailyapi.com/pricing)
- Dashboard: [secdailyapi.com/dashboard](https://www.secdailyapi.com/dashboard)
- Node.js SDK: [sec-daily-api on npm](https://www.npmjs.com/package/sec-daily-api)
- MCP Server: [sec-daily-mcp on npm](https://www.npmjs.com/package/sec-daily-mcp)

---

## Legal disclaimer

The data provided through this SDK is for **informational purposes only** and does not constitute investment advice, financial advice, trading advice, or any other type of advice. GoodTech LLC makes no representations as to the accuracy, completeness, or timeliness of the data. You are solely responsible for your use of the data. Always consult a qualified financial professional before making investment decisions.

---

Licensed under the [Apache 2.0 License](./LICENSE). Copyright 2026 GoodTech LLC.
