CormorantDocs
Menu

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:

Python
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
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:

Python
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).

View as Markdown