DOCUMENTATION / WEBHOOKS & SIGNATURES

Webhooks & signatures

OpenAPI 3.1 ↗

Receive CompanyProof claim.stale webhooks. Verify signatures, handle delivery retries and connect company changes to downstream review workflows.

BASE URLhttps://companyproof.ai/v2JSON · Bearer authentication

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

24 of 24 entries
Attribute pathTypePresenceDetails
idstringRequired in parentReturned field; availability depends on the record.
eventstringRequired in parentValue: "claim.stale".
typestringRequired in parentValue: "claim.stale".
created_atstringRequired in parentEvent creation timestamp. Format: date-time.
dataobjectRequired in parentExpand using the nested attributes listed below.
data.proof_idstringRequired in parentReturned field; availability depends on the record.
data.claim_idstringRequired in parentReturned field; availability depends on the record.
data.companyobjectRequired in parentExpand using the nested attributes listed below.
data.company.idstringRequired in parentReturned field; availability depends on the record.
data.company.namestringRequired in parentReturned field; availability depends on the record.
data.company.registration_numberstringRequired in parentReturned field; availability depends on the record.
data.company.countrystringRequired in parentReturned field; availability depends on the record.
data.fieldstringRequired in parentValues: "registered_name", "registration_number", "status", "incorporation_date", "vat_number", "legal_form".
data.published_valuestringRequired in parentReturned field; availability depends on the record.
data.verified_valuestring | nullRequired in parentReturned field; availability depends on the record.
data.previous_valuestring | nullRequired in parentReturned field; availability depends on the record.
data.current_valuestring | nullRequired in parentReturned field; availability depends on the record.
data.verified_atstringRequired in parentFormat: date-time.
data.changed_atstringRequired in parentFormat: date-time.
data.sourceobjectRequired in parentExpand using the nested attributes listed below.
data.source.sourceNamestringRequired in parentReturned field; availability depends on the record.
data.source.sourceUrlstring | nullRequired in parentFormat: uri.
data.source.retrievedAtstringRequired in parentFormat: date-time.
data.source.recordIdstringRequired in parentReturned 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.

claim.stale · JSON PAYLOAD
{
  "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"
    }
  }
}
Signature contractCompanyProof-Signature: t=UNIX_SECONDS,v1=HEX_HMAC

v1 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.

NODE.JS · SIGNATURE VERIFICATION
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-Id

Stable event ID. Persist it and ignore duplicates.

CompanyProof-Signature

Timestamp and HMAC-SHA256 signature.

User-Agent

CompanyProof-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.