# SEC Form D Scraper — Offering Data (`muhammadafzal/sec-form-d-scraper`) Actor

- **URL**: https://apify.com/muhammadafzal/sec-form-d-scraper.md
- **Developed by:** [Muhammad Afzal](https://apify.com/muhammadafzal) (community)
- **Categories:** Automation, MCP servers
- **Stats:** 1 total users, 0 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $8.00 / 1,000 form d record returneds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## SEC Form D Scraper

**Free plan limit:** Free-plan users can receive up to **5 result records per run**. Paid-plan and local/unknown runs retain the Actor's existing limits.

Extract structured exempt-offering data from SEC EDGAR Form D and Form D/A filings. The actor is designed for venture-capital research, private-market intelligence, compliance review, fundraising research, and downstream analytics pipelines.

It uses SEC’s public EDGAR interfaces: filer submission history for CIK lookups, EDGAR full-text search for keyword discovery, and the machine-readable `primary_doc.xml` filing document for structured Form D fields. It does not require an SEC API key.

### What it returns

Each dataset row represents one unique accession number and includes:

- filing identity: accession number, form type, filing date, acceptance timestamp, CIK, file number, and filer name;
- issuer identity: issuer name, issuer CIK when reported, address, signature name/title/date;
- offering data: total offering amount, amount sold, amount remaining, minimum investment, investor count, first-sale date, and offering duration;
- classification: industry group, investment-fund type, Investment Company Act flag, security types, revenue range, net-asset-value range, and federal exemptions;
- related persons listed in the filing;
- traceability: filing detail URL, primary XML URL, retrieval source, scrape timestamp, and per-record warnings;
- optional complete raw XML when `includeRawXml` is enabled.

Amounts reported by the issuer as labels such as `Indefinite` are preserved in the raw filing option and represented as `null` in numeric fields. The actor never converts non-numeric SEC labels into invented numbers.

### Input modes

The actor accepts multiple discovery paths. You can use one or combine them; output is deduplicated by accession number.

#### CIK lookup

Pass one or more SEC Central Index Keys in `ciks`. This is the most predictable mode and reads each filer’s recent EDGAR submission history, filtering to Form D and Form D/A.

```json
{
  "ciks": ["0002072074"],
  "maxResults": 10
}
```

CIKs may be supplied with or without leading zeroes. The output always uses a ten-digit zero-padded CIK.

#### Keyword discovery

Pass `searchQuery` to use EDGAR full-text search. Queries can contain a company name, ticker, CIK, industry term, or phrase such as `venture capital` or `biotechnology`. Use `dateFrom` and `dateTo` to narrow the filing date range.

```json
{
  "searchQuery": "venture capital",
  "dateFrom": "2025-01-01",
  "dateTo": "2025-12-31",
  "maxResults": 25
}
```

#### Direct filing URLs

Pass SEC filing detail pages, primary XML URLs, or archive text URLs in `startUrls` when you already know the filing. The URL must be on `sec.gov` or `www.sec.gov` and include the EDGAR CIK/accession path.

#### Exact accession numbers

Pass accession numbers with `ciks` to fetch only the specified filings:

```json
{
  "ciks": ["0002072074"],
  "accessionNumbers": ["0002072074-25-000001"]
}
```

### SEC fair-access requirements

Set the `SEC_USER_AGENT` environment variable to identify your organization and a monitored contact address before production use, for example:

```text
SEC_USER_AGENT=Acme Research sec-form-d-scraper/1.0 (contact: data@acme.example)
```

The actor defaults to a descriptive user agent so the Apify default-input health run can execute, but an owner-controlled contact address is strongly recommended. The actor spaces requests, retries transient failures, and stops when the SEC returns a persistent denial or throttle response.

### Limits and honest behavior

- `maxResults` defaults to 10 and is capped at 1,000.
- CIK discovery reads the recent submissions array exposed by the SEC submissions API. Older filings should be requested by direct URL or exact accession number when they are outside that recent history.
- Search results depend on EDGAR full-text search availability and indexing. A keyword search that is valid but finds nothing exits cleanly with a warning.
- Direct URL parsing only accepts SEC archive paths; non-SEC URLs are skipped.
- If every discovered filing fails to download or parse, the actor reports an error rather than returning fabricated empty business records.

### Run locally

```bash
npm install
npm run validate:schema
npm test
npm run build
```

With the Apify CLI installed, run the actor using the default input or a JSON input file:

```bash
apify run
apify push -f -w 120
```

### Pricing

This Actor uses **pay-per-event** pricing. These are the current Apify Store event prices:

| Event | Price (USD) | When it is charged |
|---|---:|---|
| `form-d-record` | $0.01 | Form D record returned — Charged for each successfully parsed SEC Form D or Form D/A record returned in the dataset. |
| `apify-actor-start` | $0.00005 | Actor Start — Charged when the Actor starts running. Number of events charged depends on Actor memory (one event per GB, minimum one event). — Charged once per run. |

Apify platform usage for this Actor run is included alongside the event prices above; no separate per-run platform-usage fee is passed to users.

This covers Apify platform usage for this Actor run. Other Apify products or usage outside this Actor run may still follow your account plan.

### Data source and disclaimer

The source is public SEC EDGAR filing data. Form D fields are supplied by individual filers and may contain inaccuracies; the structured output is not a substitute for reviewing the complete filing or for investment, legal, or compliance advice. See the SEC’s [EDGAR API documentation](https://www.sec.gov/search-filings/edgar-application-programming-interfaces), [Form D data documentation](https://www.sec.gov/file/dera_formddata), and [Form D XML technical specification](https://www.sec.gov/info/edgar/formdxmltechspec.6.3_d.htm).

# Actor input Schema

## `ciks` (type: `array`):

Use this field when you know one or more SEC Central Index Keys. The actor reads each filer's submission history and keeps only Form D and Form D/A filings. Example: \["0002036057"]. Use searchQuery instead when you want keyword discovery.

## `searchQuery` (type: `string`):

Use this field when you want keyword, company-name, ticker, or CIK full-text discovery across Form D filings. Do not use it for a known filer list; use ciks for that. Example: venture capital, biotechnology, or Tesla.

## `accessionNumbers` (type: `array`):

Optional exact EDGAR accession numbers. When supplied with ciks, the actor fetches only these filings. Example: \["0002072074-25-000001"].

## `startUrls` (type: `array`):

Optional direct SEC EDGAR filing detail, primary XML, or archive text URLs. Use this when you already have filing URLs; otherwise use ciks or searchQuery. Only sec.gov URLs are accepted.

## `dateFrom` (type: `string`):

Optional inclusive filing date in YYYY-MM-DD format. Applies to CIK and EDGAR search discovery.

## `dateTo` (type: `string`):

Optional inclusive filing date in YYYY-MM-DD format. Applies to CIK and EDGAR search discovery.

## `maxResults` (type: `integer`):

Maximum number of unique Form D records to return. Results are deduplicated by accession number and pushed as soon as each filing is parsed.

## `includeRawXml` (type: `boolean`):

Include the complete primary Form D XML in each output record. Keep this off for compact CRM or analytics exports.

## `requestDelayMs` (type: `integer`):

Delay between SEC requests. SEC automated access should be polite; increase this for larger runs or when using a shared network.

## Actor input object example

```json
{
  "ciks": [],
  "searchQuery": "",
  "accessionNumbers": [],
  "startUrls": [],
  "dateFrom": "",
  "dateTo": "",
  "maxResults": 10,
  "includeRawXml": false,
  "requestDelayMs": 250
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset containing normalized Form D and Form D/A records.

## `resultsCsv` (type: `string`):

CSV export of the normalized Form D and Form D/A dataset.

## `summary` (type: `string`):

Terminal run counts and warnings stored in the default key-value store.

## `consoleRun` (type: `string`):

Open the live run in Apify Console.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {};

// Run the Actor and wait for it to finish
const run = await client.actor("muhammadafzal/sec-form-d-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {}

# Run the Actor and wait for it to finish
run = client.actor("muhammadafzal/sec-form-d-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{}' |
apify call muhammadafzal/sec-form-d-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,muhammadafzal/sec-form-d-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/bidA3EzcdZng0RRQs/builds/6hhOKF1KB5r8zBbY0/openapi.json
