Webhooks

Real-time webhooks for company events.

Subscribe to filings, ownership changes, status flips, and news across US, SE, NO, FI, UK, DK. Idempotent, signed, retried.

● US ● SE ● NO ● FI ● UK ● DK
Step 1 - The payload

What we deliver.

Every event is a small, flat JSON object posted to your endpoint with an HMAC-SHA256 signature. No polling, no diffing, no schema drift.

POST https://app.example.com/hooks/regna
X-Regna-Signature: sha256=7c2f9b...

{
  "event_id": "evt_01HW8...",
  "event_type": "ownership.changed",
  "delivered_at": "2026-05-05T12:34:56Z",
  "data": {
    "org_nr": "5567037485",
    "name": "Spotify AB",
    "change": {
      "holder_name": "Daniel Ek",
      "previous_pct": 7.4,
      "current_pct": 9.8
    }
  }
}

Each event is delivered at-least-once. Use event_id for idempotency.

Step 2 - Catalogue

Event types.

Six event families. Subscribe to any combination, scoped to specific companies or to the full universe.

filing.added
New annual or quarterly filing for a company.
filing.updated
Filing replaced (rare; correction or restatement).
ownership.changed
Shareholder crossed a 5% / 10% / 20% / 50% threshold.
status.changed
Company status flipped (active, dormant, dissolved).
news.published
News event surfaced for a company you subscribe to.
event.regulatory
FI / SEC enforcement action, sanction, or material announcement.
Step 3 - Verify

Verify signatures.

Every delivery carries an X-Regna-Signature: sha256=... header. Compute the HMAC over the raw request body with your subscription secret and compare in constant time.

import crypto from 'crypto'

const sig = req.headers['x-regna-signature'].split('=')[1]
const expected = crypto.createHmac('sha256', WEBHOOK_SECRET)
  .update(req.rawBody).digest('hex')

if (!crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(expected))) {
  return res.status(401).end()
}

Always compare with a constant-time function (timingSafeEqual, hmac.compare_digest, hmac.Equal). String equality leaks the secret one byte at a time.

Step 4 - Subscribe

Manage subscriptions.

One REST endpoint creates, lists, updates, and deletes subscriptions. Scope to specific org numbers or omit the filter to receive every event for the types you pick.

Live Subscription management and event delivery are live on Pro and Business tiers. Create a key in your dashboard, register a subscription, and we sign every payload with HMAC-SHA256.
# register a subscription:
curl https://regnaverkt.com/api/v1/webhooks \
  -H "Authorization: Bearer rk_secret_..." \
  -d '{"endpoint_url":"https://app.example.com/hooks/regna",
       "event_types":["filing.published","financials.new"],
       "entity_ids":["regna:US:0000320193","regna:SE:5560157912"]}'
Retry policy

5 retries with exponential backoff (1m, 5m, 30m, 2h, 12h). After the 5th failure the subscription is paused; we email the account owner.

Delivery semantics

At-least-once. Dedupe on event_id. Acknowledge with any 2xx within 10 seconds; everything else is treated as a failure.

Step 5 - Render

Render events in your app.

<ChangeFeed /> is a tree-shakeable React component from @regna-verkt/ui. Drop it into a dashboard and it streams the same events your backend receives, filtered to a single company or an explicit list.

import { ChangeFeed } from '@regna-verkt/ui'

<ChangeFeed
  companyId="5567037485"
  publishableKey={key}
  eventTypes={["filing.added", "ownership.changed"]}
/>

For an upcoming-filings calendar use <EventsCalendar /> from the same package - same data layer, calendar layout. Both components ship with TypeScript types and import per-component, so a single feed adds roughly 8 kB gzipped to your bundle.

See the full component catalogue →

Subscribe to events.

Webhooks ship on Pro and Business tiers from $149/mo. 14-day trial.