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_cursor being 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.

Get started

Create a free account, then mint an API key and make your first request in under two minutes.