FinanceSec API Reference
Deterministic SEC EDGAR facts and quantitative risk APIs. Point an agent at
/llms.txt or this page. There is no LLM in the fact path:
the lattice either returns a verified number with provenance, or SAFE_REFUSAL.
What to give your agent
Paste this as system context, or fetch https://finsec.caleralabs.com/llms.txt. It is enough to build a research terminal, compliance proxy, stress dashboard, or HFT pre-trade gate.
You are integrating FinanceSec.
Base: https://financesec.api.caleralabs.com
Auth header: X-License-Key: $FINSEC_API_KEY
Machine contract: https://finsec.caleralabs.com/llms.txt
OpenAPI: https://finsec.caleralabs.com/openapi.json
MCP: https://finsec.caleralabs.com/mcp
Keys: https://dashboard.caleralabs.com/dashboard?domain=finsec
Docs (use cases): https://finsec.caleralabs.com/docs#use-cases
Rules:
- Never invent SEC numbers. Call the API.
- SAFE_REFUSAL is honest unknown, not a failure. Do not rephrase-guess.
- HTTP 429 = quota/RPM exhausted. Send the user to the Console to upgrade.
- Each authenticated request is 1 quota unit.
Build with:
- POST /api/query SEC facts (low_tokens for high QPS)
- POST /api/packs/valuation-inputs 12 EDGAR packs (see /docs#packs)
- POST /api/arith/evaluate cagr|ratio|mul|div|add|sub|growth|margin on verified numbers
- POST /api/query/sector_peers SIC peer screen
- POST /v1/finsec/scenario/stress-test credit shock
- POST /v1/finsec/firewall/verify-payload 1 call per LLM completion
- POST /v1/finsec/hft/verify-route 1 call per child order; execute only if APPROVED
- POST /v1/hft/arbitrage/validate · /v1/hft/liquidity/betti · /v1/hft/orderbook/settle
- POST /api/watchlist/{cik} Startup+ RT ingest
- POST /api/batch · GET /api/trends · GET /api/company/facts
HFT desk loop: betti → optional settle → verify-route. 422 = do not fire.
Credit loop: leverage_screen + altman_z_prime per name, then stress-test.
Screen loop: sector_peers + piotroski_f + beneish_m_score + returns_screen.
Authentication
Every authenticated endpoint requires a license key. Create keys in the Console.
Errors, refusals, and quota
| Code | Meaning | Agent action |
|---|---|---|
200 | JSON body. Inspect status. | Parse. SAFE_REFUSAL = unknown. |
400 | Bad JSON or empty query | Fix payload. |
402 | License missing / inactive | Send user to Console. |
403 | Not on this tier | Upgrade. |
422 | HFT route refused | Do not send the child order. |
429 | Daily quota or RPM exceeded | Stop. Upgrade. |
503 | Model loading | Poll GET /api/ready. |
What to build
FinanceSec is not a document search box. It is a set of verified fact cells plus execution/risk gates. Wire the APIs below into the product you already run. Each authenticated call is one quota unit — size the tier to the hot loop, not the homepage demo.
SAFE_REFUSAL, surface that. If you get 429, the current tier cannot sustain the loop — upgrade at the Console.HFT / algo execution desk
Before a TWAP/VWAP child hits NASDAQ/BATS/ARCA/IEX, certify the route, check liquidity topology, and optionally settle the live book. A 200-name book slicing every 100ms will burn Starter (1,200 RPM) immediately. That is what Institutional (3,000 RPM) and Enterprise (15,000+ RPM) are for.
Session start: GET /api/ready (do not arm if 503)
On each child order (instrument = NVDA):
1. POST /v1/hft/liquidity/betti
{"symbol":"NVDA"}
Hold if flash_crash_risk_state is not STABLE.
2. POST /v1/hft/orderbook/settle (optional, live snapshot)
{venue, symbol, bids[], asks[], mid_price, spread_bps, queue_imbalance}
Read hopfield_support_well / hopfield_resist_well.
3. POST /v1/finsec/hft/verify-route
{
"desk_id": "quant_execution_desk_04",
"instrument": "NVDA",
"order_type": "TWAP_CHILD_SWEEP",
"order_side": "BUY",
"order_size_shares": 15000,
"target_venues": ["NASDAQ","BATS","ARCA","IEX"],
"max_slippage_tolerance_bps": 1.2
}
Send only if status is APPROVED (or PASSED).
Use recommended_split as venue weights.
Abort if liquidity_manifold.flash_crash_potential is a block.
HTTP 422 / status REFUSED → do not send.
Quota: 1 call if you only verify-route; 3 if you add betti + settle.
At 50 children/sec you need Enterprise (15,000+ RPM).Cross-venue arbitrage scanner
Scan mids across lit venues. If arbitrage_executable is true, still run verify-route on the lift so you do not walk into a fragmented book.
POST /v1/hft/arbitrage/validate
{"symbol":"NVDA","venues":["NASDAQ","BATS","ARCA","IEX"]}
Read: arbitrage_executable, gross_spread_bps, net_arbitrage_bps, venue_mid_prices.
If executable → POST /v1/finsec/hft/verify-route on the lift leg, then execute
only on APPROVED + recommended_split.
Scan 500 symbols × 12 scans/min = 6,000 calls/min → Enterprise RPM.Credit / covenant risk book
Pull EDGAR leverage and distress scores, then shock the book across macro regimes. Register CIKs so new 8-Ks pre-warm the lattice (Startup+).
Once per universe:
GET /api/regime/scenarios
GET /api/regime/tickers
POST /api/watchlist/{cik} # each name, Startup+
Per name, per period:
POST /api/packs/valuation-inputs
{"company":"ORCL","period":"FY2023","pack":"leverage_screen"}
POST /api/packs/valuation-inputs
{"company":"ORCL","period":"FY2023","pack":"altman_z_prime"}
On each shock refresh:
POST /v1/finsec/scenario/stress-test
positions[] + macro_shock_vector + superposition_regimes
Flag position_stress_breakdown[].breach_projected
Keep provenance.accession on the breach.
500 names × 2 packs = 1,000 calls before you even stress.
Daily shock grid (10 regimes × 10 ticks) on that book wants Starter+.Research / earnings terminal
Natural-language facts with provenance, plus structured packs so you are not scraping 10-Ks. Out of scope: live quotes, P/E, trading EV. Those refusals are the product working.
GET /api/companies?q=AAPL
GET /api/company/facts?company=AAPL&period=FY2023
GET /api/trends?company=AAPL
POST /api/query {"query":"What was Apple total revenue in FY2023?","low_tokens":true}
POST /api/batch {"queries":["AAPL revenue FY2023","AAPL net income FY2023",...]}
POST /api/packs/valuation-inputs quality_of_earnings | dcf_valuation_inputs | dupont_5step
POST /api/query/sector_peers {"sector_or_industry":"semiconductors","limit":8}
POST /api/arith/evaluate {"op":"cagr","value_a":274515000000,"value_b":383285000000,"periods":["FY2020","FY2023"]}
A 50-name model with 12 packs × 3 years = 1,800 pack calls → Startup or Starter.LLM compliance proxy
Sit this between any chatbot and the user. If the model invents a revenue number, replace it with verified_payload and store audit_trail_sha256. A 25-seat wealth copilot at 4 completions/min/seat is ~6,000 calls/hour — Institutional.
POST /v1/finsec/firewall/verify-payload
{
"client_app_id": "wealth_copilot",
"generated_text": "<model output>",
"compliance_strictness": "FAIL_CLOSED",
"required_entities": ["AAPL"]
}
If hallucination_detected: show verified_payload, log audit_trail_sha256.
Optional:
POST /v1/firewall/verify-causal {cause, effect}
POST /v1/firewall/chat/completions OpenAI-compatible proxy with inline gate
GET /v1/firewall/statsQuant / long-short screen
EDGAR-only factors. No market multiples. Combine sector peers with the scoring packs, then CAGR the survivors.
POST /api/query/sector_peers
{"sector_or_industry":"semiconductors","metrics":["Revenues","OperatingIncome"],"period":"FY2023","limit":25}
For each peer ticker:
POST /api/packs/valuation-inputs pack=piotroski_f
POST /api/packs/valuation-inputs pack=beneish_m_score
POST /api/packs/valuation-inputs pack=returns_screen
POST /api/arith/evaluate {"op":"cagr","value_a":,"value_b":,"periods":["FY2019","FY2023"]}
25 names × 3 packs = 75 calls per screen refresh.
Hourly refresh on 10 sectors = 18,000/day → Institutional. SEC facts — POST /api/query
Natural-language questions over 10-K / 10-Q / 8-K. Use this for research UIs, chat tools, and any metric lookup. Set low_tokens: true on MCP (and on REST when compact JSON is enough) so high-QPS loops stay small.
{
"query": "What was Apple total revenue in FY2023?",
"target_currency": "USD",
"low_tokens": true
}Verbose success includes provenance.audit_hash, XBRL concept, filing, and period. Compact success: st=OK, val, cur, concept, per, hash.
Related: GET /api/companies?q=AAPL (issuer search) · GET /api/trends?company=AAPL (multi-year revenue / net income / margins) · GET /api/company/facts?company=AAPL&period=FY2023 (raw certified cells) · GET /api/provenance/{id} · GET /api/freshness (ingest SLA).
Valuation packs — POST /api/packs/valuation-inputs
A pack is a named bundle of EDGAR cells plus lattice compositions (ratios / scores) for one issuer and one period. You do not scrape a 10-K and compute Altman yourself — you request altman_z_prime and get verified cells, compositions, XBRL tags, and an audit hash. Required cells must all be VERIFIED for pack_status=COMPLETE. Optional cells may REFUSED without killing the pack. Market P/E, trading EV, and macro gauges are refused on purpose — that is the product, not a bug.
POST /api/packs/valuation-inputs
{
"company": "AAPL",
"period": "FY2023",
"pack": "leverage_screen"
}
Response shape:
{
"pack_id": "leverage_screen",
"company": "AAPL",
"period": "FY2023",
"pack_status": "COMPLETE", // COMPLETE | PARTIAL | DEADLINE
"cells": [
{
"metric": "operating_income",
"status": "VERIFIED", // VERIFIED | REFUSED
"value": 114301000000,
"unit": "USD",
"provenance": { "accession": "...", "xbrl_concept": "...", "audit_hash": "..." }
}
],
"compositions": [
{ "id": "interest_coverage_v1", "status": "VERIFIED", "value": 26.4, "formatted": "26.4x" }
],
"disclaimer": "Market price, trading EV, P/E, and macro gauges are not provided by FINSEC."
}Aliases: POST /api/v1/packs/valuation-inputs. Async (large universe): POST /api/v1/packs/valuation-inputs/async then poll GET /api/v1/packs/valuation-inputs/jobs/{id}. MCP tool: valuation_inputs. One quota unit per pack per issuer per period.
| Pack | Required cells | Compositions | Desk |
|---|---|---|---|
equity_screen | revenue, net_income, diluted_eps, equity, total_assets opt: operating_income, cfo, sbc | — | Model kickoff / snapshot |
ev_bridge | cash, total_debt opt: lease_liability, noncontrolling_interest, preferred_stock, short_term_investments | net_debt_v1 | EV bridge without a live quote |
quality_of_earnings | net_income, cfo, sbc, cogs opt: AR, inventory, AP, impairments, deferred_revenue, capex | fcf_v1, fcf_conversion_v1, owner_earnings_v1 | Cash conversion / forensic |
segment_mix | total_revenue + Item 1 segment lines | — | Mix-shift / segment dashboard |
returns_screen | equity, total_assets, net_income, operating_income opt: total_debt, cash | roe_v1, roa_v1, roic_v1 | Quality / returns screen |
leverage_screen | operating_income, interest_expense, total_debt, cash opt: income_tax, depreciation, STI | interest_coverage_v1, net_debt_to_ebitda_v1, net_debt_v1 | Credit / covenants |
piotroski_f | NI, CFO, assets, equity, debt, CA, CL, diluted_shares, revenue opt: gross_profit | piotroski_f_v1 (0–9) | Value / quality long-short |
altman_z_prime | assets, liabilities, CA, CL, RE, operating_income, equity, revenue | altman_z_prime_v1 | Distress / bankruptcy |
beneish_m_score | NI, CFO, assets, revenue, CA, liabilities opt: gross_profit, depreciation, cogs | beneish_m_score_v1 | Earnings-manipulation short |
dupont_5step | NI, operating_income, revenue, assets, equity opt: pretax_income, interest_expense | dupont_5step_v1 + tax / EBIT margin / AT / leverage | ROE attribution |
working_capital_efficiency | revenue, cogs, CA, CL opt: inventory, AR, AP | working_capital_efficiency_v1, dpo_days_v1 | CCC / ops cash |
dcf_valuation_inputs | cfo, capex, revenue, operating_income, equity opt: interest, debt, tax, diluted_shares | dcf_valuation_inputs_v1, fcf_margin_v1, reinvestment_rate_v1 | Historical FCF DCF (not a live-price DCF) |
A 50-name workbook × 12 packs = 600 calls; three fiscal years = 1,800. That is Starter territory before anyone opens a chart.
Lattice arithmetic — POST /api/arith/evaluate
Do not compute CAGR / ratios in the agent. Fetch verified cells (/api/query, packs, or /api/trends), then post the numbers here. The response carries an audit hash. MCP convenience: compute_sec_cagr (company + metric + start/end) and lattice_arith_evaluate.
POST /api/arith/evaluate
{"op":"ratio","value_a":108949000000,"value_b":383285000000}
{"op":"cagr","value_a":274515000000,"value_b":383285000000,"periods":["FY2020","FY2021","FY2022","FY2023"]}
{"op":"growth","value_a":394328000000,"value_b":383285000000}
{"op":"margin","value_a":96995000000,"value_b":383285000000}| op | Aliases | Operands | Use |
|---|---|---|---|
cagr | — | value_a, value_b, periods (≥2). Values must be positive. | Multi-year growth on a verified series |
ratio | div | value_a / value_b | Coverage, turnover, any quotient |
margin | — | value_a = profit, value_b = revenue → percent | NI / EBIT margin |
growth | pct_change | (b − a) / |a| | YoY step |
add / sub / mul | sum, diff, prod | value_a, value_b (add also accepts values[]) | Bridges, products |
Success: status=VERIFIED_SUCCESS, result, formatted, audit_hash. Non-positive CAGR endpoints and divide-by-zero return SAFE_REFUSAL (HTTP 400). Do not invent a substitute number.
Sector peers — POST /api/query/sector_peers
Peer set from SEC SIC codes and 10-K segment language — not a vendor GICS map. Aliases: POST /api/metrics, GET /api/v1/metrics. MCP: query_sec_sector_peers.
{
"sector_or_industry": "semiconductors",
"metrics": ["Revenues", "OperatingIncome", "TotalLongTermDebt"],
"period": "FY2023",
"limit": 8
}Scenario stress — POST /v1/finsec/scenario/stress-test
Stress a portfolio across superposed macro regimes. One call per shock refresh. List regimes with GET /api/regime/scenarios. Issuer debt profiles: GET /api/regime/tickers. Cross-domain bridges: GET /api/regime/bridges. Alias: POST /api/regime/portfolio-shock.
{
"portfolio_id": "credit_book_alpha",
"positions": [
{ "ticker": "ORCL", "exposure_usd": 50000000 },
{ "ticker": "BA", "exposure_usd": 35000000 }
],
"macro_shock_vector": {
"us10y_yield_delta_bps": 150,
"wti_crude_oil_pct": 25.0,
"us_dollar_index_delta_pct": 4.5,
"credit_spread_widening_bps": 85
},
"superposition_regimes": [
"regime:basin:stagflation_2026",
"regime:basin:liquidity_crisis",
"regime:basin:baseline_soft_landing"
]
}Read position_stress_breakdown[].breach_projected and filing provenance.accession.
Firewall — POST /v1/finsec/firewall/verify-payload
Verify LLM-generated financial text against the lattice. Call once per model completion. If hallucination_detected is true, show verified_payload and store audit_trail_sha256.
{
"client_app_id": "desk_copilot",
"generated_text": "Apple reported total revenue of $412.5 billion in FY2025.",
"compliance_strictness": "FAIL_CLOSED",
"required_entities": ["AAPL"]
}compliance_strictness: FAIL_CLOSED or STRICT (block / sanitize contradictions) · PERMISSIVE (log, do not refuse). A seat that talks to an LLM all day will max a lower tier on this loop alone.
Causal check — POST /v1/firewall/verify-causal
{
"cause": "Federal Reserve benchmark interest rate hikes",
"effect": "higher corporate debt servicing costs and borrowing rates",
"relation": "increases",
"domain": "finance"
}Use this when the model asserts a macro mechanism (rates → coverage, oil → airline costs). Contradiction is a fail, not a style note.
Also: POST /v1/firewall/chat/completions (OpenAI-compatible proxy with the gate inline), GET /v1/firewall/stats, POST /v1/firewall/rlhf-score (epistemic reward for DPO / eval loops — candidate_response required).
HFT / microstructure
Pre-trade gates for algorithmic desks. Size the tier to peak child-order RPM. Solver SLA on verify-route is sub-500µs. HTTP 422 means do not fire the order. Poll GET /api/ready before the session; if 503, do not arm the router.
Route certification — POST /v1/finsec/hft/verify-route
{
"desk_id": "quant_execution_desk_04",
"instrument": "NVDA",
"order_type": "TWAP_CHILD_SWEEP",
"order_side": "BUY",
"order_size_shares": 15000,
"target_venues": ["NASDAQ", "BATS", "ARCA", "IEX"],
"max_slippage_tolerance_bps": 1.2,
"target_latency_us": 400,
"snapshots": []
}Aliases: symbol ≈ instrument, order_size ≈ order_size_shares, max_slippage_bps ≈ max_slippage_tolerance_bps. Optional proposed_venue_split and live snapshots[] (same shape as settle). Execute only if status is APPROVED or PASSED. Do not fire on WARNING unless the desk policy allows it. Never fire on REFUSED / HTTP 422.
Read: recommended_split / recommended_routing (venue weights), projected_slippage_bps, liquidity_manifold.flash_crash_potential, betti_0_fragmentation, betti_1_cycles, spectral_gap, liquidity_exhaustion_probability, regime_shift_risk, latency_microseconds, calera_audit.
Arbitrage — POST /v1/hft/arbitrage/validate
{ "symbol": "NVDA", "venues": ["NASDAQ", "BATS", "ARCA"] }Read arbitrage_executable, gross_spread_bps, net_arbitrage_bps.
Liquidity topology — POST /v1/hft/liquidity/betti
{ "symbol": "NVDA" }Read betti_0_components, betti_1_cycles, flash_crash_risk_state.
Order book settle — POST /v1/hft/orderbook/settle
{
"venue": "NASDAQ",
"symbol": "NVDA",
"timestamp_nano": 0,
"bids": [{ "price": 120.1, "volume": 800 }],
"asks": [{ "price": 120.2, "volume": 600 }],
"mid_price": 120.15,
"spread_bps": 8.3,
"queue_imbalance": 0.12,
"micro_price": 120.16
}Empty body uses the engine fallback book. Read status=SETTLED and Hopfield wells. Full desk loop is under HFT execution desk.
Watchlist — POST /api/watchlist/{cik}
Register a 10-digit CIK for real-time 8-K / 10-Q ingest and lattice pre-warm. Startup and above. Example: POST /api/watchlist/0000320193 (Apple). Metrics: GET /api/watchlist/metrics, GET /api/freshness.
Batch & facts dump
POST /api/batch runs many fact queries in one request (each query still counts). Body is {"queries":["..."]} or a JSON array of strings. GET /api/company/facts?company=AAPL&period=FY2023 dumps certified cells for an issuer. Professional/Enterprise historically gated heavy batch — if you get 403, upgrade.
POST /api/batch
{"queries":[
"AAPL total revenue FY2023",
"MSFT net income FY2023",
"NVDA operating income FY2023"
]}MCP tools
agy mcp add finsec https://finsec.caleralabs.com/mcp (or Claude Code: claude mcp add --transport http finsec https://finsec.caleralabs.com/mcp) to auto-configure in seconds. View the complete interactive guide at /mcp-docs.
Hosted at https://finsec.caleralabs.com/mcp. Header X-License-Key. Install: MCP guide. Core tools map 1:1 onto REST:
| MCP tool | REST | Use |
|---|---|---|
query_financial_sec | POST /api/query | NL SEC facts |
query_sec_metric_exact | POST /api/query | company + metric + period |
valuation_inputs | POST /api/packs/valuation-inputs | 12 packs |
compute_sec_cagr | POST /api/arith/evaluate | CAGR |
lattice_arith_evaluate | POST /api/arith/evaluate | cagr / ratio / mul / div |
query_sec_sector_peers | POST /api/query/sector_peers | SIC peer screen |
vln_capabilities_overview | — | Machine catalog of packs + ops |
query_fomc_dotplot | POST /api/fomc/dotplot | FOMC Dot Plot rate projections |
query_macro_indicator | POST /api/macro/indicator | FRED / Macro indicators |
query_treasury_curve | POST /api/treasury/curve | Treasury constant maturity curve |
stress_test_portfolio | POST /api/portfolio/stress-test | Multi-regime shock vector testing |
simulate_macro_regime | POST /api/macro/simulate-regime | Corporate debt regime simulations |
verify_financial_claim | POST /api/firewall/verify-claim | Zero-hallucination claim audit |
firewall_audit_trail | POST /api/firewall/audit-trail | SHA-256 Merkle telemetry |
Production Latency & SLAs
Published performance characteristics and SLA gates for live hosted endpoints (warm execution; cold starts excluded):
| Route / Mode | Endpoint | SLA Gate | Target Usage |
|---|---|---|---|
| Compact Protocol | POST /api/query (low_tokens=true) | < 50 ms | High-frequency agent tool calling (~38 tokens) |
| Conversational Fact Recall | POST /api/query | < 2.0 s | Full SEC provenance & verification trail |
| Microstructure Solver | POST /v1/finsec/hft/verify-route | < 500 µs | Sub-millisecond algorithmic pre-trade gating |
Tiers
Core APIs (facts, packs, scenario, firewall, HFT) are on every paid path. Tiers differ by daily quota and RPM. Watchlist / RT ingest starts at Startup. Machine list: GET /api/tiers. Upgrade when you hit 429:
https://dashboard.caleralabs.com/dashboard?domain=finsec
| Tier | Price | Daily quota | RPM | Fits |
|---|---|---|---|---|
| Pilot | $0 (14-day) | 50 | 30 | Wire-up and first queries |
| Hacker | $99/mo | 500 | 120 | Single-issuer research tools |
| Startup | $499/mo | 2,500 | 300 | Watchlist + small team apps |
| Starter | $2,000/mo | 10,000 | 1,200 | Desk copilot + stress loops |
| Institutional | $5,000/mo | 50,000 | 3,000 | Bank-wide firewall / multi-book risk |
| Enterprise | custom ($10k+) | metered | 15,000+ | HFT child-order gating |
HFT verify-route is 1 call per child order. Firewall is 1 call per LLM completion. Packs are 1 call per pack per name. Those three loops are what exhaust lower tiers first. Build the app against the real cadence, then upgrade when 429 shows up.