Screening for material filings
Pull every filing above impact 7 in one sector this week.
A common first integration: surface every materially market-moving filing in one sector, over one week.
The request
curl -sS "https://api.cruxal.in/v1/filings" \
-H "Authorization: Bearer $CRUXAL_API_KEY" \
-G --data-urlencode "industry=Pharmaceuticals" \
--data-urlencode "impact_min=7" \
--data-urlencode "since=2026-08-11T00:00:00+05:30" \
--data-urlencode "until=2026-08-18T00:00:00+05:30" \
--data-urlencode "limit=200"
impact_min=7 is the threshold where a filing is estimated to be materially market-moving.
Start there and tune it against what your desk actually reacts to.
Paging through the whole week
import os
import httpx
BASE = "https://api.cruxal.in/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['CRUXAL_API_KEY']}"}
def screen(**filters):
"""Yield every filing matching `filters`, following the cursor to exhaustion."""
params = {**filters, "limit": 200}
cursor = None
with httpx.Client(headers=HEADERS, timeout=30) as client:
while True:
if cursor:
params["cursor"] = cursor
r = client.get(f"{BASE}/filings", params=params)
r.raise_for_status()
body = r.json()
yield from body["data"]
cursor = body["next_cursor"]
if not cursor:
return
for filing in screen(
industry="Pharmaceuticals",
impact_min=7,
since="2026-08-11T00:00:00+05:30",
until="2026-08-18T00:00:00+05:30",
):
print(filing["filed_at"], filing["ticker"], filing["impact_score"], filing["headline"])
Two things this snippet gets right and hand-rolled versions often do not:
- The filters stay fixed for the whole loop. Changing one mid-pagination invalidates the
cursor and returns a
400, by design — see pagination. - It stops on
next_cursorbeing null, not on an empty page or a row count. There is no total, deliberately.
Narrowing further
sentiment=negative— on Indian filings, negative surprises are where the sharper, faster reaction tends to be.tags=— comma-separated, matching any. Useful once you know which tags your desk cares about.market_cap=small_cap— smaller names move more on the same news, and are less covered.
Polling for new filings
Do not re-run a full screen on a timer. Keep the filed_at of the newest filing you have
processed and pass it as since:
latest = "2026-08-17T19:43:37+05:30"
new = list(screen(impact_min=7, since=latest))
Poll every 30–60 seconds. Filings arrive throughout the trading day, and a filing appears here once it has been fetched and scored, which is usually within a minute of filing.