MCP Server live — AI agents can now query 105M+ SEC facts. Connect your agent →
ValueinValuein
Python SDK

Python SDK Guide

Install valuein-sdk, set your API key, and run your first DuckDB query against 105M+ SEC EDGAR facts in under 60 seconds.

pip install valuein-sdk·Get API key →

Install

Install the SDK with pip

bash
pip install valuein-sdk

Authenticate

Store your API key in a .env file — the SDK reads it automatically

bash
echo 'VALUEIN_API_KEY="your_api_key"' >> .env

First Query

Define your SQL, open a client context, run client.query() — returns a pandas DataFrame

python
from valuein_sdk import ValueinClient, ValueinError

sql = """
SELECT
    r.symbol,
    r.name,
    f.fiscal_year,
    MAX(CASE WHEN standard_concept = 'Revenues'      THEN numeric_value END) AS revenue,
    MAX(CASE WHEN standard_concept = 'NetIncomeLoss' THEN numeric_value END) AS net_income,
    MAX(CASE WHEN standard_concept = 'EarningsPerShareDiluted' THEN numeric_value END) AS eps_diluted
FROM fact f
JOIN references r USING (entity_id)
WHERE f.form_type = '10-K'
  AND r.symbol = 'AAPL'
GROUP BY r.symbol, r.name, f.fiscal_year
ORDER BY f.fiscal_year DESC
LIMIT 10
"""

try:
    with ValueinClient() as client:
        df = client.query(sql)
        print(df)
except ValueinError as e:
    print(f"Valuein error: {e}")

Client Methods

All available client methods — check connection, inspect your plan, list tables, download full tables, and run named templates

python
from valuein_sdk import ValueinClient, ValueinError

try:
    with ValueinClient() as client:
        # Connection check — no API key required
        print(client.health())     # {"ok": true, "latency_ms": 42}

        # Your account details
        print(client.me())         # {"plan": "growth", "status": "active", "email": "...", "createdAt": "..."}

        # Dataset snapshot metadata
        print(client.manifest())   # {"snapshot": "2026-03-26", "last_updated": "...", "tables": [...]}

        # List available table names
        print(client.tables())     # ["entity", "security", "filing", "fact", "valuation", "references", ...]

        # Download a full table as a DataFrame (no SQL needed)
        filing_df = client.get(table="filing")
        print(filing_df.head())

        # Run a named SQL template by name + parameters
        name, tickers = "01_fundamentals_by_ticker", "'AAPL','MSFT','GOOGL'"
        df = client.run_template(name, tickers)
        print(df)
except ValueinError as e:
    print(f"Valuein error: {e}")

Point-in-Time

Filter by knowledge_at to reconstruct exactly what was known on any historical date — no look-ahead bias in your backtests

python
from valuein_sdk import ValueinClient, ValueinError

# What did investors KNOW about AAPL's FY2022 revenue as of Jan 1, 2023?
# Excludes any restatements or 10-K/A amendments filed after that date.
sql = """
SELECT
    r.symbol,
    f.fiscal_year,
    f.period_end,
    f.knowledge_at,
    MAX(CASE WHEN standard_concept = 'Revenues'      THEN numeric_value END) AS revenue,
    MAX(CASE WHEN standard_concept = 'NetIncomeLoss' THEN numeric_value END) AS net_income
FROM fact f
JOIN references r USING (entity_id)
WHERE f.form_type = '10-K'
  AND r.symbol = 'AAPL'
  AND f.knowledge_at <= '2023-01-01'   -- Only facts known by this date
GROUP BY r.symbol, f.fiscal_year, f.period_end, f.knowledge_at
ORDER BY f.fiscal_year DESC
LIMIT 10
"""

try:
    with ValueinClient() as client:
        df = client.query(sql)
        print(df[["fiscal_year", "period_end", "knowledge_at", "revenue", "net_income"]])
except ValueinError as e:
    print(f"Valuein error: {e}")

Screener

Screen the S&P500 with a single pivot query — one pass over the fact table, no self-joins

python
from valuein_sdk import ValueinClient, ValueinError

# S&P500 companies with ROE > 20% and Debt/Equity < 1.0 in the latest fiscal year
sql = """
SELECT
    r.symbol,
    r.name,
    r.sector,
    ROUND(
        MAX(CASE WHEN standard_concept = 'NetIncomeLoss'        THEN numeric_value END) /
        NULLIF(MAX(CASE WHEN standard_concept = 'StockholdersEquity' THEN numeric_value END), 0),
        3
    ) AS roe,
    ROUND(
        MAX(CASE WHEN standard_concept = 'LongTermDebt'         THEN numeric_value END) /
        NULLIF(MAX(CASE WHEN standard_concept = 'StockholdersEquity' THEN numeric_value END), 0),
        3
    ) AS debt_to_equity,
    MAX(CASE WHEN standard_concept = 'EarningsPerShareDiluted' THEN numeric_value END) AS eps_diluted
FROM fact f
JOIN references r USING (entity_id)
WHERE f.form_type = '10-K'
  AND f.fiscal_year = 2024
  AND r.is_sp500  = TRUE
  AND r.is_active = TRUE
GROUP BY r.symbol, r.name, r.sector
HAVING roe > 0.20 AND debt_to_equity < 1.0
ORDER BY roe DESC
LIMIT 20
"""

try:
    with ValueinClient() as client:
        df = client.query(sql)
        print(df)
except ValueinError as e:
    print(f"Valuein error: {e}")

Error Handling

Catch ValueinError to handle all SDK exceptions — authentication failures, rate limits, and network errors in one place

python
from valuein_sdk import ValueinClient, ValueinError

sql = "SELECT COUNT(*) AS total_facts FROM fact"

try:
    with ValueinClient() as client:
        df = client.query(sql)
        print(df)
except ValueinError as e:
    # ValueinError covers all SDK exceptions:
    #   - missing or invalid VALUEIN_API_KEY
    #   - rate limit exceeded for your plan tier
    #   - network or connection failures
    #   - malformed SQL or query execution errors
    print(f"Valuein error: {e}")

Quick Reference

All client methods at a glance.

MethodReturnsDescription
client.health()dictConnection status check. No API key required.
client.me()dictYour plan, status, email, and account creation date.
client.manifest()dictSnapshot date, last_updated timestamp, and available tables.
client.tables()list[str]Names of all tables loaded in the current session.
client.query(sql)DataFrameExecute any DuckDB SQL query → pandas DataFrame.
client.get(table=...)DataFrameDownload a full table as a pandas DataFrame. No SQL needed.
client.run_template(name, params)DataFrameRun a named SQL template with positional parameters.

Ready to pull real data?

Generate your API key and run these examples against live SEC EDGAR data. Free tier includes 100 API calls/day — no credit card required.