Change feeds and watches
The change feed#
GET /v1/companies/changes lists every change of the register, oldest
first: which company and which top-level fields changed (names, status,
addresses, …). Start with since, then keep the next_cursor:
cursor = None
while True:
params = {"cursor": cursor} if cursor else {"since": "2026-10-19T00:00:00Z"}
page = api.get("/v1/companies/changes", params=params).json()
for change in page["items"]:
print(change["seq"], change["company_id"], change["kind"], change["fields"])
cursor = page["next_cursor"]
if not page["items"]:
break
kind is created, updated, merged (the record was merged into another
one; its id redirects) or split. Read the record for the new values and
GET /v1/companies/{id}/history for the old ones.
Watches (webhooks)#
Register the companies you care about and an HTTPS endpoint:
curl -s -X POST https://api.cormorant.ch/v1/companies/watches \
-H "Authorization: Bearer $CORMORANT_API_KEY" -H "Content-Type: application/json" \
-d '{"companies": ["lei:BFM8T61CT2L1QCEMIK50", "ch_uid:CHE-116.281.710"], "url": "https://example.org/hooks/companies"}'
The answer has the watch id and its secret (shown only once). Every
minute, changes of the watched companies are POSTed as one
company.changed delivery (event, id, watch_id, changes). Verify
X-Cormorant-Signature: t=<unix>,v1=<hex>, the HMAC-SHA256 of
"<t>.<raw body>" under the secret, exactly as for
usage alerts:
import hashlib, hmac, time
def verify(secret: str, body: bytes, header: str, tolerance_s: int = 300) -> bool:
parts = dict(p.split("=", 1) for p in header.split(","))
t = int(parts["t"])
expected = hmac.new(secret.encode(), f"{t}.".encode() + body, hashlib.sha256).hexdigest()
return abs(time.time() - t) <= tolerance_s and hmac.compare_digest(expected, parts["v1"])
Answer any 2xx to acknowledge. Failed deliveries are retried after 1, 5, 15,
60 and 180 minutes, then hourly, and no change is skipped; use the delivery
id as idempotency key. A watched company merged into another is followed
automatically. GET /v1/companies/watches lists your watches,
DELETE /v1/companies/watches/{id} removes one (at most 20 per project,
1000 companies each).