Skip to main content
Inviolet posts webhook events to your HTTP endpoint when something worth knowing happens out-of-band — most commonly when a human approver grants or denies a pending intent request. Every event is HMAC-signed; verify the signature before trusting the payload.

Configure a destination

App dashboard → Settings → Webhooks → Add endpoint.
  • URL — your HTTPS endpoint
  • Signing secret — copy this; you cannot view it again
  • Events — pick approval.granted, approval.denied, audit.export.completed, etc.

Payload shape

{
  "event": "approval.granted",
  "organization_id": "org_2pX9...",
  "created_at": "2026-04-26T12:34:56Z",
  "data": {
    "approval_request_id": "ar_2pX9...",
    "user_id": "user_2pX9...",
    "intent_label": "pii_export",
    "data_elements": ["customer.email", "customer.phone"],
    "data_source_id": "salesforce_prod",
    "intent_token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...",
    "intent_token_id": "it_2pX9...",
    "approved_by": "user_admin42",
    "expires_at": "2026-04-26T12:39:56Z"
  }
}

Headers

HeaderDescription
inviolet-eventEvent type, e.g. approval.granted
inviolet-delivery-idUnique delivery UUID — use for idempotency
inviolet-timestampUnix ms — reject if > 5 min skew
inviolet-signaturesha256=<hex> HMAC of ${timestamp}.${body}

Verify with the Node SDK

The Node SDK ships a constant-time signature verifier:
import { InVioletWebhook } from "@inviolet/sdk"

const webhook = new InVioletWebhook({
  secret: process.env.INVIOLET_WEBHOOK_SECRET!,
})

// In your route handler (Next.js App Router shown):
export async function POST(req: Request) {
  try {
    const event = await webhook.constructEvent(req)
    if (event.event === "approval.granted") {
      // event.data.intent_token is the JWT now valid for downstream calls
    }
    return new Response("ok")
  } catch (err) {
    return new Response("invalid signature", { status: 401 })
  }
}

Verify by hand

signature = sha256=hex(HMAC-SHA256(secret, timestamp + "." + body)). Compare with constant-time equality. The SDK verifyWebhookSignature function exposes this primitive directly if you need to verify without constructing the full event object.

Retries

Inviolet retries 4xx and 5xx responses with exponential backoff for 24 hours. After that, the event is moved to a dead-letter queue visible in the dashboard.