EDGAR API documentation for direct filing access.

Query raw SEC filing facts, targeted metrics, filing sections, multi-period series, and estimate coverage from a single API. The playground below uses the same Bearer header flow supported in production.

Base URL

Production endpoint

https://www.edgarparser.com

All public endpoints live under /api/*. This page documents all 11 public routes, the shared playground, MCP access, and the OpenAPI docs.

Make your first request

Use an API key in the query string for simple scripts, or send Authorization: Bearer when you want Swagger, the playground, and modern HTTP clients to share the same auth pattern.

curl
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://www.edgarparser.com/api/financials?ticker=AAPL&year=2025&quarter=1"
Python
import requests

API_KEY = "YOUR_API_KEY"

response = requests.get(
    "https://www.edgarparser.com/api/financials",
    headers={"Authorization": f"Bearer {API_KEY}"},
    params={"ticker": "AAPL", "year": 2025, "quarter": 1},
    timeout=30,
)

print(response.json())

Run a live request against the public API

The shared demo key is cache-only and intended for quick inspection. Try AAPL, MSFT, or NVDA for the best chance of a warm cache hit.

Playground traffic is authenticated with a shared Bearer token, rate limited per visitor IP, and restricted to pre-cached tickers.
Request Builder

The playground always sends Authorization: Bearer ... so you can copy the same pattern into your own client.

Response
waiting 0 ms
No request sent yet

Query param or Bearer header

Both auth styles are supported. If you send both on the same request, the Bearer header wins and the query-string key is ignored.

Query Param
curl "https://www.edgarparser.com/api/financials?ticker=AAPL&year=2025&quarter=1&key=YOUR_API_KEY"
Bearer Header
curl -H "Authorization: Bearer YOUR_API_KEY" \
  "https://www.edgarparser.com/api/financials?ticker=AAPL&year=2025&quarter=1"

Empty or whitespace-only Bearer tokens resolve to the public tier. Non-Bearer schemes such as Basic fall back to ?key= if you provide it.

Public API surface

Each endpoint below includes the actual FastAPI query signature, a curl example, a Python example using the Bearer header, and a compact example response.

GET /api/financials

Full extracted fact payload for a quarter or fiscal year, including metadata about the filing source.

Parameters

ParameterTypeRequiredNotes
tickerstringyesSupported SEC ticker, normalized to uppercase.
yearintegeryesFiscal year.
quarterintegeryes1 through 4.
full_year_modebooleannoDefault false. Set true for FY extraction.
sourcestringnoDefault auto. Set 8k to force earnings-release extraction.
curl
curl "https://www.edgarparser.com/api/financials?ticker=AAPL&year=2025&quarter=1&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/financials",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"ticker": "AAPL", "year": 2025, "quarter": 1},
    timeout=30,
)

Example Response

{
  "status": "success",
  "metadata": {
    "ticker": "AAPL",
    "year": 2025,
    "quarter": 1,
    "source": {"filing_type": "10-Q"}
  },
  "facts": [
    {
      "tag": "us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax",
      "current_value": 124300.0,
      "prior_value": 119575.0,
      "scale": "millions"
    }
  ]
}
GET /api/filings

Returns filing metadata and normalized SEC filing URLs for the requested fiscal period.

Parameters

ParameterTypeRequiredNotes
tickerstringyesSupported SEC ticker.
yearintegeryesFiscal year.
quarterintegeryes1 through 4.
curl
curl "https://www.edgarparser.com/api/filings?ticker=MSFT&year=2025&quarter=2&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/filings",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"ticker": "MSFT", "year": 2025, "quarter": 2},
    timeout=30,
)

Example Response

{
  "status": "success",
  "filings": [
    {
      "filing_type": "10-Q",
      "filing_date": "2025-01-29",
      "url": "https://www.sec.gov/Archives/edgar/data/789019/...",
      "accession_number": "0000950170-25-000123"
    },
    {
      "filing_type": "8-K",
      "filing_date": "2025-01-28",
      "url": "https://www.sec.gov/Archives/edgar/data/789019/...",
      "accession_number": "0000950170-25-000118"
    }
  ]
}
GET /api/metric

Target one metric or XBRL tag without downloading the entire financials payload.

Parameters

ParameterTypeRequiredNotes
tickerstringyesSupported SEC ticker.
yearintegeryesFiscal year.
quarterintegeryes1 through 4.
metric_namestringyesFriendly alias (revenue, net_income), bare XBRL tag (Revenues), or namespaced tag (us-gaap:Revenues). Raw tags fall back to the concept's full alias group when the literal tag isn't in the filing.
full_year_modebooleannoDefault false.
sourcestringnoDefault auto; supports 8k.
date_typestringnoOptional Q, YTD, or FY filter.
curl
curl "https://www.edgarparser.com/api/metric?ticker=AAPL&year=2025&quarter=1&metric_name=Revenue&date_type=Q&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/metric",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "ticker": "AAPL",
        "year": 2025,
        "quarter": 1,
        "metric_name": "Revenue",
        "date_type": "Q",
    },
    timeout=30,
)

Example Response

{
  "status": "success",
  "matches": [
    {
      "metric": "Revenue",
      "tag": "us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax",
      "current_value": 124300.0,
      "prior_value": 119575.0,
      "yoy_change_pct": "3.9%",
      "scale": "millions",
      "date_type": "Q"
    }
  ],
  "source": {"filing_type": "10-Q"}
}

Errors

When the financials are cached but the requested metric isn't present in that filing, the endpoint returns 404 with an error_type field clients can branch on:

{
  "status": "error",
  "message": "Metric 'FooBar' not found in AAPL Q1 2025 filing",
  "error_type": "metric_not_found"
}

When no financials are cached for the requested period, the endpoint returns 404 directing callers to populate the cache via /api/financials first. Genuine extraction failures still return 502.

GET /api/sections

Extract narrative sections and tables from 10-Q, 10-K, or 8-K filing text.

Parameters

ParameterTypeRequiredNotes
tickerstringyesSupported SEC ticker.
yearintegeryesFiscal year.
quarterintegeryes1 through 4.
sectionsstringnoComma-separated section keys such as part1_item2.
sourcestringnoOmit for 10-Q/10-K, or set 8k.
formatstringnoDefault summary; supports full.
max_wordsstringnoInteger or none.
curl
curl "https://www.edgarparser.com/api/sections?ticker=AAPL&year=2025&quarter=1&sections=part1_item2&format=summary&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/sections",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "ticker": "AAPL",
        "year": 2025,
        "quarter": 1,
        "sections": "part1_item2",
        "format": "summary",
    },
    timeout=30,
)

Example Response

{
  "status": "success",
  "sections": {
    "part1_item2": {
      "title": "Management's Discussion and Analysis",
      "text": "Net sales increased year over year across the iPhone and Services segments...",
      "word_count": 612
    }
  }
}
GET /api/metric/series

Fetch one metric across multiple periods in a single request with per-period cache and fetch status.

Parameters

ParameterTypeRequiredNotes
tickerstringyesSupported SEC ticker.
metric_namestringyesFriendly alias or raw XBRL tag (bare or namespaced). Periods where the metric isn't in the cached filing are returned with status: "missing".
end_yearintegeryesFinal year in the series.
end_quarterintegeryes1 through 4. Ignored in FY mode.
periodsintegernoDefault 8; range 1-20.
full_year_modebooleannoDefault false.
sourcestringnoDefault auto; supports 8k.
date_typestringnoOptional Q, YTD, or FY.
cached_onlybooleannoDefault false. Skip live fetches for uncached periods.
curl
curl "https://www.edgarparser.com/api/metric/series?ticker=AAPL&metric_name=Revenue&end_year=2025&end_quarter=1&periods=6&date_type=Q&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/metric/series",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "ticker": "AAPL",
        "metric_name": "Revenue",
        "end_year": 2025,
        "end_quarter": 1,
        "periods": 6,
        "date_type": "Q",
    },
    timeout=30,
)

Example Response

{
  "status": "partial",
  "ticker": "AAPL",
  "metric_name": "Revenue",
  "date_type": "Q",
  "full_year_mode": false,
  "periods_requested": 6,
  "periods_returned": 5,
  "periods_cached": 4,
  "periods_fetched": 1,
  "periods_failed": 0,
  "periods_missing": 1,
  "series": [
    {
      "period": "Q4 2024",
      "year": 2024,
      "quarter": 4,
      "value": 124300.0,
      "prior_value": 119575.0,
      "yoy_change_pct": "3.9%",
      "scale": "millions",
      "metric_tag": "us-gaap:RevenueFromContractWithCustomerExcludingAssessedTax",
      "date_type": "Q",
      "filing_type": "10-Q",
      "source": "auto",
      "status": "ok"
    },
    {
      "period": "Q1 2025",
      "year": 2025,
      "quarter": 1,
      "value": null,
      "prior_value": null,
      "yoy_change_pct": null,
      "scale": null,
      "metric_tag": null,
      "date_type": null,
      "filing_type": null,
      "source": null,
      "status": "missing",
      "error": "No cached data available"
    }
  ]
}
POST /api/warm

Batch-submit tickers/periods for background cache population. Paid tier only. Returns a job_id immediately; poll GET /api/warm/{job_id} for per-item status. Useful when a client (Excel add-in, MCP server, batch job) knows in advance which filings it will need — firing a warm request upfront means /api/financials and /api/metric requests hit cache when they arrive.

Request body

FieldTypeRequiredNotes
itemsarrayyes1–50 items per batch. Each item: {ticker, year, quarter, full_year_mode?}. Unknown fields (including source) return 422; warm always runs XBRL with no 8-K fallback.

Quotas (per paid key)

  • 50 items per batch
  • 200 pending items at any moment (error_type: pending_quota_exceeded)
  • 500 items per rolling 24h (error_type: daily_quota_exceeded)
  • 60 POSTs per rolling 24h (error_type: rate_limit_exceeded)
curl
curl -X POST "https://www.edgarparser.com/api/warm?key=YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"items":[
        {"ticker":"AAPL","year":2024,"quarter":4,"full_year_mode":true},
        {"ticker":"MSFT","year":2024,"quarter":2}
      ]}'
Python
import requests, time

job = requests.post(
    "https://www.edgarparser.com/api/warm",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    json={"items": [
        {"ticker": "AAPL", "year": 2024, "quarter": 4, "full_year_mode": True},
        {"ticker": "MSFT", "year": 2024, "quarter": 2},
    ]},
    timeout=10,
).json()

while True:
    status = requests.get(
        f"https://www.edgarparser.com{job['poll_url']}",
        headers={"Authorization": "Bearer YOUR_API_KEY"},
        timeout=10,
    ).json()
    if status["status"] in {"done", "partial", "failed"}:
        break
    time.sleep(10)

Example Response (accept)

{
  "job_id": "wrm_01HXXXXXXXXXXXXXXXXXXXXXX",
  "status": "accepted",
  "items_received": 2,
  "items_enqueued": 1,
  "items_skipped_cached": 1,
  "poll_url": "/api/warm/wrm_01HXXXXXXXXXXXXXXXXXXXXXX"
}

Example Response (poll)

{
  "job_id": "wrm_01HXXXXXXXXXXXXXXXXXXXXXX",
  "status": "done",
  "created_at": "2026-04-14T20:11:03Z",
  "updated_at": "2026-04-14T20:12:47Z",
  "counts": {"pending": 0, "running": 0, "done": 1, "error": 0, "skipped_cached": 1},
  "items": [
    {"idx": 0, "ticker": "AAPL", "year": 2024, "quarter": 4, "full_year_mode": true,
     "status": "skipped_cached", "cached": true, "duration_ms": 0},
    {"idx": 1, "ticker": "MSFT", "year": 2024, "quarter": 2, "full_year_mode": false,
     "status": "done", "cached": true, "duration_ms": 36449}
  ]
}
The estimates endpoints below return 503 until the estimates database is configured with FMP_DATA_DATABASE_URL.
GET /api/estimates/latest

Latest estimate snapshot rows for one ticker.

Parameters

ParameterTypeRequiredNotes
tickerstringyesNormalized to uppercase.
periodstringnoDefault quarter.
curl
curl "https://www.edgarparser.com/api/estimates/latest?ticker=AAPL&period=quarter&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/latest",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"ticker": "AAPL", "period": "quarter"},
    timeout=30,
)

Example Response

[
  {
    "ticker": "AAPL",
    "period": "quarter",
    "fiscal_date": "2025-06-28",
    "metric": "revenue",
    "estimate": 89700000000.0,
    "updated_at": "2026-04-01T00:14:33Z"
  }
]
GET /api/estimates/revisions

Revision history for a specific fiscal period.

Parameters

ParameterTypeRequiredNotes
tickerstringyesNormalized to uppercase.
fiscal_datestringyesFiscal period end date, for example 2025-06-28.
periodstringnoDefault quarter.
curl
curl "https://www.edgarparser.com/api/estimates/revisions?ticker=AAPL&fiscal_date=2025-06-28&period=quarter&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/revisions",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={
        "ticker": "AAPL",
        "fiscal_date": "2025-06-28",
        "period": "quarter",
    },
    timeout=30,
)

Example Response

[
  {
    "ticker": "AAPL",
    "fiscal_date": "2025-06-28",
    "metric": "revenue",
    "revision_date": "2026-03-28",
    "old_value": 89000000000.0,
    "new_value": 89700000000.0
  }
]
GET /api/estimates/revision-summary

Aggregate revision activity across one or more tickers over a rolling window.

Parameters

ParameterTypeRequiredNotes
tickersstringnoComma-separated ticker list. Omit for the whole universe.
daysintegernoDefault 30.
periodstringnoDefault quarter.
curl
curl "https://www.edgarparser.com/api/estimates/revision-summary?tickers=AAPL,MSFT&days=14&period=quarter&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/revision-summary",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"tickers": "AAPL,MSFT", "days": 14, "period": "quarter"},
    timeout=30,
)

Example Response

[
  {
    "ticker": "AAPL",
    "direction": "up",
    "revisions": 6,
    "net_change_pct": 1.8,
    "period": "quarter"
  }
]
GET /api/estimates/freshness

Check the last successful estimate snapshot timestamp for each ticker.

Parameters

ParameterTypeRequiredNotes
tickersstringyesComma-separated ticker list.
periodstringnoDefault quarter.
curl
curl "https://www.edgarparser.com/api/estimates/freshness?tickers=AAPL,MSFT&period=quarter&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/freshness",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"tickers": "AAPL,MSFT", "period": "quarter"},
    timeout=30,
)

Example Response

{
  "AAPL": "2026-04-02T03:11:24Z",
  "MSFT": "2026-04-02T03:12:07Z"
}
GET /api/estimates/failures

Failure summary from estimate collector runs, useful for auditing thin or unstable coverage.

Parameters

ParameterTypeRequiredNotes
min_runsintegernoDefault 1.
curl
curl "https://www.edgarparser.com/api/estimates/failures?min_runs=2&key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/failures",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    params={"min_runs": 2},
    timeout=30,
)

Example Response

[
  {
    "ticker": "AAPL",
    "failure_count": 2,
    "last_error": "Missing consensus rows",
    "last_seen": "2026-04-01T05:22:10Z"
  }
]
GET /api/estimates/tickers

List all tickers currently available in the estimates store.

Parameters

ParameterTypeRequiredNotes
none-noAuthentication only.
curl
curl "https://www.edgarparser.com/api/estimates/tickers?key=YOUR_API_KEY"
Python
import requests

response = requests.get(
    "https://www.edgarparser.com/api/estimates/tickers",
    headers={"Authorization": "Bearer YOUR_API_KEY"},
    timeout=30,
)

Example Response

[
  "AAPL",
  "MSFT",
  "NVDA"
]

Tier behavior

Playground traffic is intentionally constrained. Production tiers are meant for direct client use; the shared demo key is for read-only cache inspection.

TierLimitBucketNotes
Public5 per 7 daysPer IPNo key required.
Registered6 per 7 daysPer keyFree signup tier.
Paid500 per 7 daysPer keyFull production access.
Playground30 per hourPer visitor IPShared demo key, cache-only for warm tickers.

Use the same API through MCP

The edgar-mcp package wraps the deployed API for agent workflows in Claude Code and other MCP clients.

Install
pip install edgar-mcp
Claude Code config
"edgar-financials": {
  "type": "stdio",
  "command": "python3",
  "args": [
    "/Users/henrychien/Documents/Jupyter/Edgar_updater/mcp_server.py"
  ],
  "env": {
    "EDGAR_API_KEY": "YOUR_KEY_HERE"
  }
}

GitHub: henrysouchien/edgar-mcp

Available Tools
ToolPurpose
get_filingsFiling metadata for a quarter.
get_financialsFull fact payload, optionally file output.
get_metricOne metric or XBRL tag with YoY values.
get_metric_seriesOne metric across multiple periods.
list_metricsCatalog candidate tags from filing facts.
search_metricsFuzzy metric discovery from natural language.
get_filing_sectionsNarrative sections and tables from filing text.

Swagger UI and ReDoc

Use the generated schema for client generation, or test requests directly in Swagger UI with the Authorize button. Both the query-param key and Bearer auth are registered in the schema.

Swagger UI exposes both ApiKeyQuery and BearerAuth, so the same schema works for copy-paste curl usage and the interactive Authorize flow.