Python SDK

Institutions talk to Scrolls data through the scrolls Python package — not through ad-hoc HTTP wrappers. After one login, notebooks and agents call native gRPC with a Scrolls-issued credential in metadata.

Two planes, one brand

PackageRoleBacked by
scrolls.dataSearch, catalogs, series / variate loadsIDP Read gRPC
scrolls.analyticsAgent / analytics APIs (as they land)TradingPythonAgent

Callers only import scrolls. IDP and TPA stay implementation details.

Install

cd python
pip install -e .

# Needs idp (+ TradingPythonAgent for analytics) on PYTHONPATH or installed

Package sources live in the Scrolls repo under python/scrolls/.

Auth (control plane vs data plane)

  1. Control plane (HTTPS) — Scrolls mints or revokes a scoped credential (POST /api/auth/credentials with SCROLLS_AUTH_SECRET).
  2. Client once — store it locally:
scrolls login --token "$SCROLLS_API_KEY"
# or: export SCROLLS_API_KEY=...
# file default: ~/.scrolls/credentials.json
  1. Data plane (gRPC) — each call sends authorization: Bearer … in metadata. No Scrolls hop per request (keeps streaming fast).

Common scopes: data:search, data:fred, …, analytics:*. When SCROLLS_AUTH_SECRET is set on the read API, gRPC Search requires a valid bearer.

Semantic search

Fan-out across macro sources and EDGAR 8-K. Prefer planning the query first (same allowlisted contract as Explore), then stream results:

from scrolls.data import ScrollsDataClient, plan_query

plan = plan_query("Fed funds rate cuts and bank 8-K guidance")
client = ScrollsDataClient()  # uses stored / env credential

for event in client.search(
    plan["search"]["q"],
    sources=plan["search"]["sources"],
    limit=plan["search"]["limit"],
    **{k: v for k, v in (plan["search"].get("edgar") or {}).items() if v},
):
    print(event.event, event.source, len(event.hits))

Events mirror the HTTP SSE / GraphQL subscription contract: source_result, source_error, done.

Catalogs and series

from scrolls.data import ScrollsDataClient

client = ScrollsDataClient()
catalog = client.load_catalog("fred")
# frame columns depend on source; series loads follow the IdpRead RPCs

Query planner

scrolls.data.plan_query turns natural language into a schema-validated plan (sources, rewritten q, edgar filters, explore actions). Unknown sources/actions are rejected. If planning fails, the fallback keeps the raw user text and searches all allowlisted sources — never a silent drop.

The Explore UI uses the same contract via POST /api/data/plan-query (TypeScript twin in src/lib/search/plan-query.ts).

When to use what

SurfaceBest for
scrolls.data (gRPC)Institutions, agents, high-throughput streaming
HTTP / GraphQLWeb BFF, Excel-adjacent scripts, curl smoke tests
httpx examplesQuick notebook prototypes without the SDK

Logout

scrolls logout