Keep the key server-side
TheX-API-Key secret belongs in your backend, an agent runtime config, or a secret manager — never anywhere a user or a model can read it.
- No key in a browser bundle, mobile app, public repo, prompt, log line, or screenshot.
- Proxy client calls through your own backend; the key never reaches the browser.
- The raw secret is shown once at creation. Store it in a secret manager. New keys come from the dashboard.
- On a suspected leak, revoke the key in the dashboard and issue a new one.
- Do not cache a
401or a quota429as if it were data; a fixed key or a reset window should take effect immediately.
Cache by data class
Fundamentals change only when a new filing lands; prices change every trading day. Cache each on its own clock. These are starting points, not API contracts — tune against your traffic.
Two hooks make these self-tuning. Fundamentals responses carry
meta.published_at and meta.last_verified_at, so you can tell how fresh the projection is. Price data carries its own meta.as_of.market clock. Key by tool plus normalized body — for example sctx:financials:AAPL:annual:3. Uppercase the symbol and apply defaults so an omitted period_kind and annual hit the same entry.
Scope cache keys per plan or tenant if different keys can see different quotas. A shared cache that ignores scope can let one tenant’s requests count against another’s budget.
Retries and limits
Wrap every call in the retry loop that retries only429/5xx, honors Retry-After, and caps total wait. The code is in Errors and retries. The per-plan minute and quota numbers are on Plans and limits. Track X-Credits-Remaining when it is present so long-running jobs can stop before they hit quota_exhausted.
SEC-backed tools can be slow cold
stock_filings, stock_insider, and stock_ownership read SEC data and can be slow on a cold path for a heavy filer. Do not block a page render on them: run them in a background job and cache the result, since filing facts are effectively immutable once published.
Preserve provenance and refusals
Whatever your UI shows, carry these through so the answer stays truthful:- The clocks.
meta.as_of.secfor fundamentals,meta.as_of.marketfor prices. If you present a price-derived multiple, keep its price date. - Provenance.
status(direct/derived),provenance(licensed_market_data,computed_from_prices,sec_filing), and — atdetail: "full"— thesourcesandaccession. - Refusals. When a field has
unavailable, show the gap and the token; never render it as0. - Coverage bounds.
is_covered/ingestion_pendingon search, and thecoverageblock (exhaustive: false) onstock_ownership.
Batch workflows
Run many symbols with bounded concurrency.
Plans and limits
Per-plan minute limits and quotas.