registercheckby openlaw group
Guides

Track changes

Replace a polling loop with a monitor and a webhook.

The shape of it

monitor once  →  we re-read the register  →  event fires  →  your webhook  →  you re-read the company

You monitor a company. We detect that its register entry moved. Your endpoint gets told. You fetch the new state.

Monitor a company

def watch(company_id: str, events=("*",)):
    existing = session.get(f"{BASE}/monitors", params={"limit": 100}).json()
    if any(m["company"]["id"] == company_id for m in existing["data"]):
        return  # already watching it

    r = session.post(f"{BASE}/monitors", json={
        "company_id": company_id,
        "event_types": list(events),
    })
    r.raise_for_status()
    return r.json()["id"]

Only company_id is required; the monitor belongs to the account that owns the key. Reading GET /monitors first is free, so the pre-check costs nothing — and creating a monitor costs 10 credits, so it is worth doing.

Narrow the events

* is the default and it is noisy. Monitor what you will act on:

You care aboutMonitor
A counterparty's solvencycompany.capital.changed, company.legal_form.changed
Who can signcompany.officer.appointed, company.officer.removed
Change of controlcompany.shareholder.added, company.shareholder.removed, company.shareholder.changed
Keeping records tidycompany.name.changed, company.address.changed

"Who can sign" is two types rather than four: an authorised signatory is an officer here, so a grant of Prokura and a board appointment both raise company.officer.appointed.

Change the selection later with PATCH /monitors/{id}, which touches only what you send — so {"status": "paused"} stops delivery without losing your event types.

Handle the webhook

app.post('/hooks/registercheck', async (req, res) => {
  res.status(200).end();               // acknowledge first, work after

  const eventId = req.headers['svix-id'] as string;   // NOT req.body: there is none there
  const { company_id, event_type } = req.body;
  if (await alreadyProcessed(eventId)) return;    // events can repeat

  const fresh = await fetchCompany(company_id);   // the payload is a signal, not state
  await applyChange(company_id, event_type, fresh);
  await markProcessed(eventId);
});

Three rules, in order of how much trouble they save you:

  1. Acknowledge immediately. A slow handler is a retried handler.
  2. Deduplicate on the svix-id header. Assume at-least-once delivery. The body carries no event id — see Webhooks.
  3. Re-read the company. Treat the event as "something changed", not as the new value.

What this is not

Detection runs on a cycle against the register, and the register itself lags the real world by days or weeks. Expect to hear about a change a day or two after it is published, and do not build anything that needs to know within the hour.

Housekeeping

Only creating a monitor costs anything; listing, reading, updating and deleting are free. So read GET /monitors whenever you want the truth rather than trusting a local index, and delete what you no longer watch — the cost of a monitor is the 10 credits you already paid, not an ongoing charge.

On this page