Events & payloads
Every webhook delivery is a JSON POST with the same stable envelope. This page documents the
envelope, the event types, and how the block field maps to the profile.
The envelope
| Field | Type | Description |
|---|---|---|
type |
string | The event type — e.g. profile.changed. See Event types. |
apiVersion |
string | Payload schema version. Currently v1. |
occurredAt |
string | ISO-8601 UTC instant the change occurred, e.g. 2026-06-30T19:40:00Z. |
idempotencyKey |
string | Stable key identifying this change — dedupe on it. |
block |
string | Which part of the profile changed. Matches a field name in the profile response — see Blocks. |
data |
object | Minimal event data: jurisdiction and companyNumber. |
The contract is additive — we may add fields without notice, so parse defensively and ignore
unknown fields. A breaking change bumps apiVersion.
Event types
type |
Meaning |
|---|---|
profile.changed |
A tracked profile block changed. The block field says which one. |
profile.early_signal.detected |
A new early-warning signal was detected on the company. block is earlySignals. |
profile.early_signal.updated |
An existing early signal changed state (superseded or expired). block is earlySignals. |
The block field
For profile.changed, block tells you which section of the profile changed — and its value
is exactly the corresponding field name in the GET /v1/profile/{companyNumber} response, so you
can map it straight onto the section to re-read.
block |
Profile field it maps to | Changes when… |
|---|---|---|
overview |
overview |
Company size, complexity, maturity, or type changes. |
tradingStatus |
tradingStatus |
The company's trading status changes (e.g. Active → Ceased). |
filingBehaviour |
filingBehaviour |
Filing behaviour/consistency changes. |
riskOfFailure |
riskOfFailure |
The risk-of-failure level changes (e.g. Low → High). |
creditCapacity |
creditCapacity |
The estimated credit/trade limit changes. |
earlySignals |
earlySignals |
An early-warning signal appears or changes state. |
Example payloads
Trading status changed:
{
"type": "profile.changed",
"apiVersion": "v1",
"occurredAt": "2026-06-30T19:40:00Z",
"idempotencyKey": "PROFILE_CHANGED:SC855307:ACTIVE_TO_CEASED:20260630",
"block": "tradingStatus",
"data": { "jurisdiction": "GB", "companyNumber": "SC855307" }
}
Early signal detected:
{
"type": "profile.early_signal.detected",
"apiVersion": "v1",
"occurredAt": "2026-06-30T19:40:00Z",
"idempotencyKey": "EARLY_SIGNAL:SC855307:winding_up_petition:ACTIVE",
"block": "earlySignals",
"data": { "jurisdiction": "GB", "companyNumber": "SC855307" }
}
Reacting to an event
data carries only jurisdiction and companyNumber — enough to re-fetch. Use block to decide
which part of the returned profile you care about:
curl -s -H "Authorization: Bearer $TOKEN" \
"https://public-api.heygrand.com/v1/profile/SC855307?jurisdiction=GB"
Because the payload never carries the changed values, you never act on stale data and you don't need to handle out-of-order deliveries field-by-field — the profile you fetch is always current.