Building a results calendar
Turn the events feed into a forward calendar for your desk.
The events feed is a forward calendar: what is scheduled, when, and how much it is likely to matter.
Pulling the next month
curl -sS "https://api.cruxal.in/v1/events" \
-H "Authorization: Bearer $CRUXAL_API_KEY" \
-G --data-urlencode "from=2026-08-18" \
--data-urlencode "to=2026-09-18" \
--data-urlencode "status=upcoming" \
--data-urlencode "limit=200"
Grouping into a calendar
import os
from collections import defaultdict
import httpx
BASE = "https://api.cruxal.in/v1"
HEADERS = {"Authorization": f"Bearer {os.environ['CRUXAL_API_KEY']}"}
def events(filters):
# A plain dict, not **kwargs: the parameter is literally named `from`, which cannot be
# a Python keyword argument. Spelling it `from_` sends the wrong parameter name and the
# start-date filter is silently dropped.
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}/events", params=params)
r.raise_for_status()
body = r.json()
yield from body["data"]
cursor = body["next_cursor"]
if not cursor:
return
calendar = defaultdict(list)
undated = []
for event in events({"from": "2026-08-18", "to": "2026-09-18", "status": "upcoming"}):
# scheduled_date is null for events announced without a date. Bucket them separately
# rather than dropping them — an undated board meeting is still information.
if event["scheduled_date"]:
calendar[event["scheduled_date"]].append(event)
else:
undated.append(event)
for day in sorted(calendar):
print(day)
for e in sorted(calendar[day], key=lambda x: -(x["importance"] or 0)):
print(f" {e['ticker']:12} {e['event_type']:20} importance={e['importance']}")
Reading the fields
| Field | What to do with it |
|---|---|
scheduled_date | The date the company announced. Null means announced but undated. |
record_date | For dividends and corporate actions, the entitlement date. |
importance | 0–10. Our estimate of how much this event matters for the name. |
expected_direction | positive, negative or neutral. An estimate, not a forecast. |
conviction | 0–1. How confident the estimate is. Low conviction is a reason to discount it. |
agenda | What the filing said would be discussed. Often the most useful field. |
Treat expected_direction and conviction together: a positive at 0.2 conviction carries
much less information than a positive at 0.8.
Keeping it current
Companies reschedule. Re-pull the window rather than caching indefinitely, and use status to
separate what is still ahead (upcoming) from what has passed (past).