Skip to main content
Two things separate a toy integration from a production one: you keep the key out of anything a user can see, and you cache each data class on its own clock. Retries and limits link out to the pages that own them.

Keep the key server-side

The X-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 401 or a quota 429 as 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 only 429/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.sec for fundamentals, meta.as_of.market for 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 — at detail: "full" — the sources and accession.
  • Refusals. When a field has unavailable, show the gap and the token; never render it as 0.
  • Coverage bounds. is_covered / ingestion_pending on search, and the coverage block (exhaustive: false) on stock_ownership.
Hiding a refusal or a coverage bound makes a number look more certain than it is. Surface it.

Batch workflows

Run many symbols with bounded concurrency.

Plans and limits

Per-plan minute limits and quotas.