Back to Blog

Free SEC EDGAR API Guide: Endpoints, Rate Limits, CIK Lookup, and Full-Text Search

SEC EDGAR financial data

Learn how to programmatically access SEC filing data, financial metrics, and XBRL information using the free EDGAR API: every endpoint, the rate limits, CIK numbers for popular tickers, and working code.

The SEC provides free programmatic access to all EDGAR filing data through their API. This guide shows you how to access company information, filing histories, structured XBRL financial data, and full-text search, without any API keys or paid subscriptions. If you just want to read filings without writing code, you can also browse companies on TL;DR Filing or jump straight to a ticker via the A-Z ticker index.

Is the SEC EDGAR API Free?

Yes, completely. There is no API key, no sign-up, no OAuth flow, and no billing. The SEC's EDGAR data APIs on data.sec.gov and the full-text search API on efts.sec.gov are public services. The only rules are the fair access rules described below: identify yourself with a User-Agent header and stay under 10 requests per second.

Rate Limits and Fair Access Rules

The SEC does not use API keys to control access. Instead it enforces a fair access policy that applies to everyone:

curl -H "User-Agent: YourName email@domain.com" \
  "https://data.sec.gov/submissions/CIK0000320193.json"

The Three Main Endpoint Families

Nearly everything you will do with the EDGAR API uses one of three endpoint families on data.sec.gov. In every URL, the CIK must be zero-padded to 10 digits.

1. Submissions: a company's filing history

https://data.sec.gov/submissions/CIK##########.json

# Example (Apple):
https://data.sec.gov/submissions/CIK0000320193.json

Returns company metadata (name, tickers, SIC code, addresses) plus the complete filing history: form types (10-K, 10-Q, 8-K, and more), filing dates, accession numbers, and document links.

2. CompanyFacts: every XBRL fact a company has reported

https://data.sec.gov/api/xbrl/companyfacts/CIK##########.json

# Example (Apple):
https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json

One large JSON document with all of a company's structured financial data across every filing: revenue, net income, assets, share counts, and hundreds of other concepts, each with full history.

3. CompanyConcept: one concept for one company

https://data.sec.gov/api/xbrl/companyconcept/CIK##########/us-gaap/{Tag}.json

# Example (Apple's net income):
https://data.sec.gov/api/xbrl/companyconcept/CIK0000320193/us-gaap/NetIncomeLoss.json

When you only need a single metric, this endpoint returns that one concept's full history in a much smaller payload than CompanyFacts.

Full-Text Search API (efts.sec.gov)

The EDGAR full-text search API lets you search the text of filings from 2001 onward. It lives on a different host than the XBRL endpoints:

https://efts.sec.gov/LATEST/search-index?q={query}

# Search for an exact phrase:
https://efts.sec.gov/LATEST/search-index?q=%22supply+chain+disruption%22

# Restrict to a form type and date range:
https://efts.sec.gov/LATEST/search-index?q=%22cybersecurity+incident%22&forms=8-K&dateRange=custom&startdt=2026-01-01&enddt=2026-06-30

Results come back as JSON with matching accession numbers, filer names, CIKs, form types, and filing dates. This is the same backend that powers the EDGAR full-text search page at sec.gov/edgar/search. The same fair access rules apply: send a User-Agent header and stay under 10 requests per second. URL-encode your query (quotes become %22, spaces become + or %20).

Inside companyfacts.json: Structure Walkthrough

The CompanyFacts response has a consistent shape. At the top level:

{
  "cik": 320193,
  "entityName": "Apple Inc.",
  "facts": {
    "dei": { ... },
    "us-gaap": {
      "Revenues": {
        "label": "Revenues",
        "description": "...",
        "units": {
          "USD": [
            {
              "start": "2024-09-29",
              "end": "2025-09-27",
              "val": 123456000000,
              "form": "10-K",
              "fy": 2025,
              "fp": "FY",
              "filed": "2025-10-31"
            }
          ]
        }
      }
    }
  }
}

The practical pattern: pick a tag under facts["us-gaap"], pick a unit, filter by form (10-K for annual, 10-Q for quarterly), and sort by end to get the latest value.

CIK Quick Reference for Popular Tickers

API URLs require CIKs zero-padded to 10 digits. Here are the CIKs for commonly requested companies (each links to its TL;DR Filing company page):

Company Ticker Zero-Padded CIK CompanyFacts URL
AppleAAPL0000320193.../companyfacts/CIK0000320193.json
MicrosoftMSFT0000789019.../companyfacts/CIK0000789019.json
NVIDIANVDA0001045810.../companyfacts/CIK0001045810.json
AmazonAMZN0001018724.../companyfacts/CIK0001018724.json
AlphabetGOOGL0001652044.../companyfacts/CIK0001652044.json
TeslaTSLA0001318605.../companyfacts/CIK0001318605.json
MetaMETA0001326801.../companyfacts/CIK0001326801.json
Berkshire HathawayBRK.B0001067983.../companyfacts/CIK0001067983.json
OracleORCL0001341439.../companyfacts/CIK0001341439.json
AdobeADBE0000796343.../companyfacts/CIK0000796343.json

Note: CIKs must be zero-padded to 10 digits in API URLs. Apple's CIK is 320193, but the URL requires CIK0000320193. Need a ticker not listed here? Every company page on this site is reachable from the A-Z ticker index, or download the SEC's own mapping at sec.gov/files/company_tickers.json.

Getting Started

The SEC requires a User-Agent header identifying yourself:

curl -H "User-Agent: YourName email@domain.com" \
  "https://data.sec.gov/submissions/CIK0000320193.json"

JavaScript Example

async function getCompanyData(cik) {
  const response = await fetch(`https://data.sec.gov/submissions/CIK${cik.padStart(10, '0')}.json`, {
    headers: {
      'User-Agent': 'YourName email@domain.com'
    }
  });
  return response.json();
}

// Get Apple's data
const appleData = await getCompanyData('320193');

Key API Features

1. Company Submissions

Get all filings for a company:

2. XBRL Financial Data

Access structured financial metrics:

3. Rate Limiting

The API has generous limits:

Practical Examples

Example 1: Get Company Revenue

async function getRevenue(cik) {
  const url = `https://data.sec.gov/api/xbrl/companyconcept/CIK${cik.padStart(10, '0')}/us-gaap/Revenues.json`;
  
  const response = await fetch(url, {
    headers: { 'User-Agent': 'YourName email@domain.com' }
  });
  
  const data = await response.json();
  const annualData = data.units.USD.filter(item => item.form === '10-K');
  
  return annualData.sort((a, b) => b.end.localeCompare(a.end));
}

Example 2: Compare Companies

async function compareMetrics(companies, metric) {
  const results = {};
  
  for (const [ticker, cik] of Object.entries(companies)) {
    try {
      const data = await getMetric(cik, metric);
      results[ticker] = data[0]?.val; // Latest value
    } catch (e) {
      results[ticker] = null;
    }
    
    // Respect rate limit
    await new Promise(resolve => setTimeout(resolve, 100));
  }
  
  return results;
}

// Usage
const results = await compareMetrics({
  'AAPL': '320193',
  'MSFT': '789019',
  'GOOGL': '1652044'
}, 'Revenues');

Common XBRL Tags

Here are the most useful XBRL tags for financial analysis:

Income Statement

Balance Sheet

Cash Flow

Error Handling

async function safeAPICall(url) {
  try {
    const response = await fetch(url, {
      headers: { 'User-Agent': 'YourName email@domain.com' }
    });
    
    if (!response.ok) {
      throw new Error(`HTTP ${response.status}: ${response.statusText}`);
    }
    
    return await response.json();
  } catch (error) {
    console.error(`API call failed: ${error.message}`);
    return null;
  }
}

Building a Financial Dashboard

Here's a complete example for building a basic financial dashboard:

class SECAnalyzer {
  constructor() {
    this.baseURL = 'https://data.sec.gov';
    this.userAgent = 'YourName email@domain.com';
  }

  async getCompanyOverview(cik) {
    const submissions = await this.fetch(`/submissions/CIK${cik.padStart(10, '0')}.json`);
    const facts = await this.fetch(`/api/xbrl/companyfacts/CIK${cik.padStart(10, '0')}.json`);
    
    return {
      name: submissions.name,
      ticker: submissions.tickers?.[0],
      sic: submissions.sic,
      filings: submissions.filings.recent,
      financials: this.extractKeyMetrics(facts)
    };
  }

  extractKeyMetrics(facts) {
    const metrics = {};
    const gaap = facts.facts['us-gaap'] || {};
    
    // Extract key metrics with error handling
    ['Revenues', 'NetIncomeLoss', 'Assets', 'StockholdersEquity'].forEach(tag => {
      if (gaap[tag]?.units?.USD) {
        const annual = gaap[tag].units.USD
          .filter(item => item.form === '10-K')
          .sort((a, b) => b.end.localeCompare(a.end))[0];
        
        metrics[tag] = annual?.val || null;
      }
    });
    
    return metrics;
  }

  async fetch(endpoint) {
    const response = await fetch(`${this.baseURL}${endpoint}`, {
      headers: { 'User-Agent': this.userAgent }
    });
    
    if (!response.ok) throw new Error(`HTTP ${response.status}`);
    return response.json();
  }
}

Best Practices

Quick Reference: SEC EDGAR API Endpoints

Quick lookup table for the most commonly used SEC EDGAR API endpoints:

Endpoint Name URL Pattern Returns
Company Facts data.sec.gov/api/xbrl/companyfacts/CIK{number}.json All XBRL financial facts
Submissions data.sec.gov/submissions/CIK{number}.json Filing history and metadata
Company Concept data.sec.gov/api/xbrl/companyconcept/CIK{number}/{taxonomy}/{tag}.json Specific data point across periods
Full-Text Search efts.sec.gov/LATEST/search-index?q={query} Filing search results

Code Examples

Here are complete working examples in different languages for fetching companyfacts data:

Python Example

import requests

def get_company_facts(cik):
    """Fetch companyfacts for a company by CIK number."""
    cik_padded = str(cik).zfill(10)
    url = f'https://data.sec.gov/api/xbrl/companyfacts/CIK{cik_padded}.json'
    headers = {'User-Agent': 'YourName email@domain.com'}
    response = requests.get(url, headers=headers)
    return response.json()

# Get Apple facts
apple_facts = get_company_facts('320193')
gaap = apple_facts['facts'].get('us-gaap', {})
if 'Revenues' in gaap:
    revenues = gaap['Revenues']['units'].get('USD', [])
    latest = max(revenues, key=lambda x: x['end'])
    print(f"Latest Revenue: {latest['val']:,}")

Node.js / JavaScript Example

async function getCompanyFacts(cik) {
  const cikPadded = String(cik).padStart(10, '0');
  const url = `https://data.sec.gov/api/xbrl/companyfacts/CIK${cikPadded}.json`;
  const response = await fetch(url, {
    headers: {'User-Agent': 'YourName email@domain.com'}
  });
  if (!response.ok) throw new Error(`HTTP ${response.status}`);
  return response.json();
}

const appleFacts = await getCompanyFacts('320193');
const revenues = appleFacts.facts['us-gaap']?.Revenues?.units?.USD || [];
const latest = revenues.sort((a, b) => new Date(b.end) - new Date(a.end))[0];
console.log(`Latest Revenue: $${latest?.val?.toLocaleString()}`);

cURL Command Line

curl -H "User-Agent: YourName email@domain.com" \
  "https://data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json" \
  | jq '.facts."us-gaap".Revenues.units.USD | sort_by(.end) | .[-1]'

Troubleshooting

403 Forbidden Error

Problem: You get a 403 error when making API requests.

Solution: The SEC requires a User-Agent header. Include it in all requests:

headers: {
  'User-Agent': 'YourCompanyName email@domain.com'
}

Rate Limiting

Problem: You're getting rate limited (HTTP 429 errors).

Solution: The SEC allows maximum 10 requests per second. Add delays:

// Wait 100ms between requests
await new Promise(resolve => setTimeout(resolve, 100));

CIK Padding Issues

Problem: API returns 404 or incorrect data.

Solution: CIK must be zero-padded to 10 digits:

FAQ

Is the SEC EDGAR API free?

Yes, completely free. No API key, no registration, no authentication, no paid tier. The only requirement is a User-Agent header identifying you with a contact email.

What are the SEC EDGAR API rate limits?

Maximum 10 requests per second per user, with no daily quotas. Exceeding the limit can get your IP temporarily blocked, so add roughly a 100ms delay between requests.

Does the SEC EDGAR API require an API key?

No. There is no API key and no authentication. You only need a User-Agent header such as "YourName email@domain.com". Requests without it are typically rejected with a 403 error.

What is data.sec.gov/api/xbrl/companyfacts/CIK0000320193.json?

That is the CompanyFacts endpoint for Apple (CIK 0000320193). It returns one JSON document with every XBRL-tagged financial fact Apple has reported, organized under facts.us-gaap with values, units, dates, and source forms.

What is the SEC EDGAR full-text search API?

The endpoint at efts.sec.gov/LATEST/search-index?q= searches the text of EDGAR filings from 2001 onward. It supports form-type and date filters and returns JSON with accession numbers and filing metadata.

How do I find a company's CIK number?

Search at sec.gov/cgi-bin/browse-edgar by name or ticker, or download the ticker-to-CIK map at sec.gov/files/company_tickers.json. Remember to zero-pad the CIK to 10 digits in API URLs.

Alternative: Use TL;DR Filing

While the SEC API is powerful, it can be complex to work with. Our TL;DR Filing platform sits on top of the same EDGAR data and provides:

Conclusion

The SEC EDGAR API provides free access to a wealth of financial data. Start with basic company lookups via the Submissions endpoint, pull structured financials from CompanyFacts, use CompanyConcept for single metrics, and reach for full-text search when you need to find filings by content. Remember to be respectful of the 10 requests per second limit and always include proper attribution in your User-Agent header.

For more complex analysis needs, consider using our TL;DR Filing platform which provides AI-powered insights on top of this raw SEC data.