WEBHOOKS · CLAIM.STALE
Authenticate every event before acting.
Create up to 10 active HTTPS endpoints in the account console. CompanyProof stores each endpoint secret encrypted, displays the secret once, rejects redirects and treats any 2xx response as successful delivery.
The payload below is an illustrative paid live-source scenario with synthetic identifiers. It is not a sandbox response: test keys cannot enable monitoring. Code generators can consume the named ClaimStaleWebhook component in OpenAPI 3.1.
Exact webhook attributes
| Attribute path | Type | Presence | Details |
|---|---|---|---|
id | string | Required in parent | Returned field; availability depends on the record. |
event | string | Required in parent | Value: "claim.stale". |
type | string | Required in parent | Value: "claim.stale". |
created_at | string | Required in parent | Event creation timestamp. Format: date-time. |
data | object | Required in parent | Expand using the nested attributes listed below. |
data.proof_id | string | Required in parent | Returned field; availability depends on the record. |
data.claim_id | string | Required in parent | Returned field; availability depends on the record. |
data.company | object | Required in parent | Expand using the nested attributes listed below. |
data.company.id | string | Required in parent | Returned field; availability depends on the record. |
data.company.name | string | Required in parent | Returned field; availability depends on the record. |
data.company.registration_number | string | Required in parent | Returned field; availability depends on the record. |
data.company.country | string | Required in parent | Returned field; availability depends on the record. |
data.field | string | Required in parent | Values: "registered_name", "registration_number", "status", "incorporation_date", "vat_number", "legal_form". |
data.published_value | string | Required in parent | Returned field; availability depends on the record. |
data.verified_value | string | null | Required in parent | Returned field; availability depends on the record. |
data.previous_value | string | null | Required in parent | Returned field; availability depends on the record. |
data.current_value | string | null | Required in parent | Returned field; availability depends on the record. |
data.verified_at | string | Required in parent | Format: date-time. |
data.changed_at | string | Required in parent | Format: date-time. |
data.source | object | Required in parent | Expand using the nested attributes listed below. |
data.source.sourceName | string | Required in parent | Returned field; availability depends on the record. |
data.source.sourceUrl | string | null | Required in parent | Format: uri. |
data.source.retrievedAt | string | Required in parent | Format: date-time. |
data.source.recordId | string | Required in parent | Returned field; availability depends on the record. |
Paths are relative to the selected schema; $ means the schema value itself. Required applies when its parent object exists. null, an absent field and an empty list are different values. Alternative response shapes are labelled.
{
"id": "evt_0c1d2e3f4a5b6c7d8e9f1011",
"event": "claim.stale",
"type": "claim.stale",
"created_at": "2026-10-14T11:06:02.000Z",
"data": {
"proof_id": "prf_7dcf18e8a2f6c06a9a10d2c1",
"claim_id": "clm_f3df4360de139d4f9d323779",
"company": {
"id": "live_company_example_001",
"name": "COMPANYPROOF EXAMPLE LIMITED",
"registration_number": "EXAMPLE-001",
"country": "GB"
},
"field": "status",
"published_value": "Active",
"verified_value": "Active",
"previous_value": "Active",
"current_value": "Dissolved",
"verified_at": "2026-08-29T10:42:11.000Z",
"changed_at": "2026-10-14T11:06:01.000Z",
"source": {
"sourceName": "Illustrative live registry",
"sourceUrl": "https://registry.example/company/EXAMPLE-001",
"sourceUpdatedAt": null,
"retrievedAt": "2026-10-14T11:05:58.000Z",
"recordId": "EXAMPLE-001"
}
}
}CompanyProof-Signature: t=UNIX_SECONDS,v1=HEX_HMACv1 is HMAC-SHA256 over timestamp + "." + raw_request_body. Verify the raw bytes before parsing JSON, compare in constant time and reject timestamps older than your tolerance.
import { createHmac, timingSafeEqual } from "node:crypto";
export function verifyCompanyProofWebhook(rawBody, header, secret) {
const values = Object.fromEntries(
header.split(",").map(part => part.split("=", 2))
);
const timestamp = Number(values.t);
const supplied = Buffer.from(values.v1 || "", "hex");
if (!Number.isFinite(timestamp)) return false;
if (Math.abs(Date.now() / 1000 - timestamp) > 300) return false;
const signed = Buffer.concat([
Buffer.from(String(timestamp) + ".", "utf8"),
rawBody
]);
const expected = createHmac("sha256", secret).update(signed).digest();
return supplied.length === expected.length &&
timingSafeEqual(supplied, expected);
}CompanyProof-Event-IdStable event ID. Persist it and ignore duplicates.
CompanyProof-SignatureTimestamp and HMAC-SHA256 signature.
User-AgentCompanyProof-Webhooks/1.0
Delivery times out after 10 seconds. CompanyProof makes up to five attempts: immediately, then after roughly 1 minute, 5 minutes, 30 minutes and 2 hours. Delivery order is not guaranteed; deduplicate with CompanyProof-Event-Id and order business events with created_at. There is no public replay endpoint in this version. Return 2xx only after the event is durably accepted.
