Skip to content
FonteumPublic-records evidence
Docs · Webhooks

Provider event-stream webhooks

Subscribe via the developer console at /developer/webhooks. Delivered payloads use an HMAC-SHA256 header so subscribers can authenticate the transport body. That HMAC does not sign an individual source fact. A payload can also include the nullable provenance fields available for its event and source.

Phase 1 event types

  • provider.exclusion_added
  • provider.enrollment_status_changed

Phase 2 (queued): provider.deficiency_cited, provider.sff_status_changed, provider.ownership_changed.

Sample payload

{
  "event_id": "evt_2026_05_09_a1b2c3d4",
  "event_type": "provider.exclusion_added",
  "occurred_at": "2026-05-08T00:00:00Z",
  "delivered_at": "2026-05-09T18:32:14Z",
  "fonteum_version": "v2026.05.0",
  "subject": {
    "npi": "1245319599",
    "provider_name": null
  },
  "change": {
    "field": "leie_excluded",
    "old_value": null,
    "new_value": true,
    "exclusion_type": "1128(a)(1)",
    "exclusion_date": "2026-05-08"
  },
  "provenance": {
    "source": "OIG LEIE",
    "source_url": "https://oig.hhs.gov/exclusions/...",
    "dataset_id": "leie-2026-05-08",
    "snapshot_date": "2026-05-08",
    "methodology_version": "v2026.05.0",
    "last_checked": "2026-05-09T06:30:00Z",
    "confidence_score": 1,
    "data_availability": [
      "live"
    ],
    "pipeline_version": "abc1234",
    "doi": null,
    "license": "US-Government-Works",
    "coverage_period_start": "1977-10-25",
    "coverage_period_end": "ongoing",
    "slsa_provenance_url": null
  },
  "verify_url": "https://fonteum.com/verify/evt_2026_05_09_a1b2c3d4"
}

HMAC validation

Each POST carries an X-Fonteum-Signature header with format v1=hex_sig. Verify it against the raw request body using your subscriber secret (returned once at registration).

Node.js

// Node 18+ (built-in crypto)
import { createHmac, timingSafeEqual } from "node:crypto";

export function verifyFonteumSignature(
  rawBody: string,         // raw POST body string
  signatureHeader: string, // X-Fonteum-Signature header value, e.g. "v1=hex"
  secret: string,
): boolean {
  const expected = "v1=" + createHmac("sha256", secret)
    .update(rawBody, "utf8")
    .digest("hex");
  if (expected.length !== signatureHeader.length) return false;
  return timingSafeEqual(
    Buffer.from(expected, "utf8"),
    Buffer.from(signatureHeader, "utf8"),
  );
}

Python

# Python 3.6+ (stdlib)
import hashlib, hmac

def verify_fonteum_signature(raw_body: bytes, signature_header: str, secret: str) -> bool:
    expected = "v1=" + hmac.new(
        secret.encode("utf-8"),
        raw_body,
        hashlib.sha256,
    ).hexdigest()
    return hmac.compare_digest(expected, signature_header)

Go

// Go 1.21+
package fonteum

import (
    "crypto/hmac"
    "crypto/sha256"
    "encoding/hex"
)

func VerifyFonteumSignature(rawBody []byte, signatureHeader, secret string) bool {
    mac := hmac.New(sha256.New, []byte(secret))
    mac.Write(rawBody)
    expected := "v1=" + hex.EncodeToString(mac.Sum(nil))
    return hmac.Equal([]byte(expected), []byte(signatureHeader))
}

Retry policy

  • 5xx responses + timeouts (10s per request) → exponential backoff: 1m → 5m → 30m → 2h → 12h → DLQ.
  • 4xx responses → marked failed, no retry. Inspect via the subscriber detail page.
  • 2xx responses → success. last_active_at updated on the subscriber row.
  • Every attempt logs to webhook_delivery_log with status, latency, and error class.
  • After 6 retries (≈12h elapsed), the run moves to the Inngest dead-letter queue. Operator-side replay flow is documented separately.

Source and capture context

The event schema permits a provenance object with up to fourteen fields. Payloads can omit the object or return null fields when the event builder lacks that metadata. The first group is: source, source_url, dataset_id, snapshot_date, methodology_version, last_checked, confidence_score, data_availability. Additional fields include pipeline_version (git commit SHA), doi (reserved persistent identifier; currently always null), license (SPDX identifier), coverage_period_start + coverage_period_end (ISO-8601 dates), slsa_provenance_url (SLSA Build Level 3 artifact). The new fields are nullable. The verify_url field, when present, identifies a separate validation object; it does not create a signature link for every fact in the event. Full schema reference at /docs/provenance-contract.

Source registry · Methodology · Freshness dashboard

What’s on file, by the numbers

Platform snapshot · 2026-08-24

13.4Mproviders & companiesProviders, organizations, owners, and facilities on file
26.2Msource-linked factsSource-linked field facts in the dated platform snapshot
90sources with dataDistinct snapshot source IDs with at least one positive record count
70fresh sourcesDistinct source IDs whose latest positive-data snapshot falls within the preceding 45 days
111sources integratedActive registry rows; integration does not establish a load
13state Medicaid jurisdictionsDistinct states represented in the state-exclusions serving table

Integrated, with-data, and fresh-observation counts are separate. No platform-wide source-completeness count is published. Completeness is source-specific and must be evaluated against the named source's expected scope. State coverage is a separate jurisdiction measure.

Source authority is record-specific

Use the issuer named on the record.

Fonteum spans federal, state, and global public publishers. A source page or returned record identifies its issuer and dataset where that metadata is available. A platform registry count does not assign every page to one authority or establish loaded, fresh, or complete coverage.

Browse source records and their stated limitations →

Reproducible by design

Inspect the evidence each published figure actually supplies.

Source and date

Research pages expose the named public file and observation date where those fields are available. Source-file SHA-256 coverage is separate; facts do not currently link deterministically to signatures.

Available derivation

Studies with a retained release and committed derivation link the SQL or method used. Other studies state the evidence and reproduction limits they actually have.

Daily observations

Dated table row-count observations can detect local drift. They do not imply that an upstream publisher released or Fonteum ingested new data that day.

Named medical review

Reviewed by Jennifer Montecillo, MD, medical reviewer. Non-practicing medical reviewer.

Read the full provenance and attestation methodology →

Request access