Guides

Using the REST API

One Bearer token, one JSON shape across every source. Authenticate, call an endpoint, handle errors and rate limits — in curl, Python, JavaScript, or Go.

Get Your API Key

Sign up for a free account to get your API key. No credit card required.

Sign Up / Sign In Rate limits depend on your plan — see pricing

After signing in, copy your API key from the dashboard. All requests require a Bearer token in the Authorization header.

First Request

Search for a company by name. No CIK lookup needed.

curl "https://api.financeapis.dev/v1/edgar/filers/search?q=berkshire" \
  -H "Authorization: Bearer YOUR_API_KEY"
import requests

response = requests.get( https://api.financeapis.dev/v1/edgar/filers/search", params={“q”: “berkshire”}, headers={“Authorization”: “Bearer YOUR_API_KEY”} )

data = response.json() for filer in data[“filers”]: print(f”{filer[‘cik’]}{filer[’name’]}")

const response = await fetch(
"https://api.financeapis.dev/v1/edgar/filers/search?q=berkshire",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const { filers } = await response.json();
filers.forEach(f => console.log(`${f.cik}${f.name}`));
req, \_ := http.NewRequest("GET",
"https://api.financeapis.dev/v1/edgar/filers/search?q=berkshire", nil)
req.Header.Set("Authorization", "Bearer YOUR_API_KEY")

resp, \_ := http.DefaultClient.Do(req)
defer resp.Body.Close()
Response
{
  "filers": [
    {
      "cik": "0001067983",
      "name": "BERKSHIRE HATHAWAY INC",
      "ticker": "BRK-B",
      "exchange": "NYSE"
    }
  ]
}

SEC Filings

Fetch recent filings for any company using their CIK number. This returns the same data as EDGAR's submissions endpoint, normalized to JSON.

curl "https://api.financeapis.dev/v1/edgar/raw/submissions/0000320193" \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://api.financeapis.dev/v1/edgar/raw/submissions/0000320193",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

data = response.json() print(data[“name”]) # APPLE INC

const response = await fetch(
"https://api.financeapis.dev/v1/edgar/raw/submissions/0000320193",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const data = await response.json();
console.log(data.name); // APPLE INC
Response (abbreviated)
{
  "cik": "0000320193",
  "name": "APPLE INC",
  "tickers": ["AAPL"],
  "filings": {
    "recent": {
      "form": ["10-K", "10-Q", "8-K"],
      "filingDate": ["2025-10-31", "2025-08-01", "2025-07-31"],
      "primaryDocument": ["aapl-20250927.htm", "..."]
    }
  }
}

FRED Economic Data

Pull macroeconomic time series from FRED. Over 800,000 series available, including GDP, CPI, unemployment, and interest rates.

curl "https://api.financeapis.dev/v1/fred/series/GDP/observations" \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://api.financeapis.dev/v1/fred/series/GDP/observations",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

for obs in response.json()[“observations”][-3:]: print(f"{obs[‘date’]}: ${obs[‘value’]}B")

const response = await fetch(
"https://api.financeapis.dev/v1/fred/series/GDP/observations",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const { observations } = await response.json();
observations.slice(-3).forEach(o =>
console.log(`${o.date}: $${o.value}B`)
);
Response (abbreviated)
{
  "series_id": "GDP",
  "title": "Gross Domestic Product",
  "units": "Billions of Dollars",
  "frequency": "Quarterly",
  "observations": [
    { "date": "2025-04-01", "value": "29719.758" },
    { "date": "2025-07-01", "value": "30148.102" }
  ]
}

BEA National Accounts

Pull national accounts from the Bureau of Economic Analysis. The NIPA dataset covers GDP, personal income, consumer spending, and corporate profits. Table T10101 returns the percent change in real GDP by quarter.

curl "https://api.financeapis.dev/v1/bea/datasets/NIPA?TableName=T10101&Frequency=Q&Year=2024" \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://api.financeapis.dev/v1/bea/datasets/NIPA",
    params={"TableName": "T10101", "Frequency": "Q", "Year": "2024"},
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

for row in response.json()[“data”][:3]: print(f"{row[‘TimePeriod’]}: {row[‘DataValue’]}%")

const response = await fetch(
"https://api.financeapis.dev/v1/bea/datasets/NIPA?TableName=T10101&Frequency=Q&Year=2024",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const { data } = await response.json();
data.slice(0, 3).forEach(r =>
console.log(`${r.TimePeriod}: ${r.DataValue}%`)
);
Response (abbreviated)
{
  "provenance": { "source": "BEA", "dataset": "NIPA" },
  "data": [
    {
      "TableName": "T10101",
      "SeriesCode": "A191RL",
      "LineDescription": "Gross domestic product",
      "TimePeriod": "2024Q1",
      "DataValue": "1.6",
      "CL_UNIT": "Percent"
    }
  ]
}

World Bank Indicators

Fetch development indicators for any country by ISO code. The World Bank publishes thousands of series — GDP, population, inflation, life expectancy. This call returns US GDP in current dollars, by year.

curl "https://api.financeapis.dev/v1/worldbank/countries/US/indicators/NY.GDP.MKTP.CD" \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://api.financeapis.dev/v1/worldbank/countries/US/indicators/NY.GDP.MKTP.CD",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

for obs in response.json()[:3]: print(f"{obs[‘date’]}: ${obs[‘value’]:,}")

const response = await fetch(
"https://api.financeapis.dev/v1/worldbank/countries/US/indicators/NY.GDP.MKTP.CD",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const series = await response.json();
series.slice(0, 3).forEach(o =>
console.log(`${o.date}: $${o.value.toLocaleString()}`)
);
Response (abbreviated)
[
  {
    "indicatorId": "NY.GDP.MKTP.CD",
    "indicatorName": "GDP (current US$)",
    "countryId": "US",
    "countryName": "United States",
    "countryIso3": "USA",
    "date": "2023",
    "value": 27360935000000
  }
]

13F Holdings

See what institutional investors are holding. 13F filings are required for investment managers with over $100M in assets.

curl "https://api.financeapis.dev/v1/edgar/forms/13f/holdings/0001067983/2024-Q4" \
  -H "Authorization: Bearer YOUR_API_KEY"
response = requests.get(
    "https://api.financeapis.dev/v1/edgar/forms/13f/holdings/0001067983/2024-Q4",
    headers={"Authorization": "Bearer YOUR_API_KEY"}
)

for h in response.json()[“holdings”][:5]: print(f"{h[’nameOfIssuer’]}: ${h[‘value’]:,}")

const response = await fetch(
"https://api.financeapis.dev/v1/edgar/forms/13f/holdings/0001067983/2024-Q4",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);

const { holdings } = await response.json();
holdings.slice(0, 5).forEach(h =>
console.log(`${h.nameOfIssuer}: $${h.value.toLocaleString()}`)
);
Response (abbreviated)
{
  "cik": "0001067983",
  "name": "BERKSHIRE HATHAWAY INC",
  "period": "2024-Q4",
  "holdings": [
    {
      "nameOfIssuer": "APPLE INC",
      "titleOfClass": "COM",
      "cusip": "037833100",
      "value": 75124000,
      "shares": 300000000
    }
  ]
}

Error Handling

The API returns standard HTTP status codes with JSON error bodies. Handle these three cases and you're covered:

# 401 — Missing or invalid API key
{ "error": "Unauthorized" }

# 404 — Resource not found { “error”: “Not found” }

# 429 — Rate limit exceeded { “error”: “Rate limit exceeded” } # Check Retry-After header for seconds to wait

Rate limit headers are included in every response:

X-RateLimit-Limit: 42        # requests per hour (plan-dependent)
X-RateLimit-Remaining: 38    # requests left this window
X-RateLimit-Reset: 1710543600 # window reset (Unix timestamp)
Retry-After: 60              # seconds (only on 429)

A simple retry pattern for 429 responses:

import time, requests

def api*get(url, api_key, retries=3): for * in range(retries): resp = requests.get(url, headers={ “Authorization”: f"Bearer {api_key}" }) if resp.status_code != 429: return resp wait = int(resp.headers.get(“Retry-After”, 60)) time.sleep(wait) return resp

async function apiGet(url, apiKey, retries = 3) {
for (let i = 0; i < retries; i++) {
const resp = await fetch(url, {
headers: { Authorization: `Bearer ${apiKey}` }
});
if (resp.status !== 429) return resp;
const wait = resp.headers.get("Retry-After") ?? 60;
await new Promise(r => setTimeout(r, wait \* 1000));
}
}

Next Steps