Skip to content
docs

Webhooks

Get an HTTP POST when something happens on your account: an anomaly fires, or a settlement lands. Send it to your own endpoint (we sign every request) or straight into a Slack, Discord, or Teams channel. Webhooks are free on every plan.

Manage them under Settings → API & webhooks.

Events

  • anomaly.detected: a traffic or earnings anomaly tripped one of your alerts.
  • settlement.completed: a payout settled to an author on one of your sites.

The envelope every delivery carries

A signed (raw) delivery posts one envelope, and the event's own fields are nested inside it under data:

{
  "id": "dlv_01J8...",
  "type": "settlement.completed",
  "eventId": "settlement:pub_123:29650",
  "createdAt": 1719000000000,
  "data": {}
}

Read your fields off data, not off the top level: body.data.tenant, not body.tenant. Every payload example below is the data object, not the whole body.

eventId is stable per underlying occurrence, so a retry or two racing sweeps carry the same value. De-duplicate on eventId; id is unique per delivery attempt and is also sent as the Naulon-Id header. createdAt is Unix epoch milliseconds.

The signature covers the exact bytes of that whole envelope, so verify the HMAC over the raw body before you parse it.

Payload profile: summary or detailed

For a signed (raw) endpoint you choose, per hook, how much the settlement.completed body carries. Pick it when you create the endpoint, or change it any time from the endpoint's detail panel. (Chat channels like Slack, Discord, and Teams always get a one-line summary; the profile doesn't apply to them.)

summary

The count only, meaning how many settlements this delivery covers. Pick it when all you need is a nudge to go look at your earnings.

{ "tenant": "acme", "announced": 3 }

detailed

The full settlement: the gross that moved, a leg per payee with its on-chain reference, and the window it covers. New endpoints default to this.

{
  "tenant": "acme",
  "host": "acme.example.com",
  "window": { "toMs": 1719000000000, "spanMs": 60000 },
  "citations": { "settled": 3 },
  "gross": { "microUsdc": 8800, "usdc": "0.008800" },
  "legs": [
    { "role": "author",   "payTo": "0x…", "microUsdc": 8000, "settled": true, "settlementRef": "0x…" },
    { "role": "operator", "payTo": "0x…", "microUsdc": 800,  "settled": true, "settlementRef": "0x…" }
  ],
  "settlementRefs": ["0x…"]
}

Money is integer micro-USDC (microUsdc). That's the source of truth. The usdc string is a formatted convenience; don't parse it back. gross.microUsdc is the sum of the legs. settlementRef is the on-chain reference for that leg; use it to build an explorer link for your chain. A field we can't attribute is left out, never faked. So if a leg's settlementRef is null, it genuinely couldn't be pinned to one settlement.

Switching a hook from summary to detailed (or back) takes effect on the next delivery. Because the signature covers the exact bytes you receive, adding fields is safe: verify the HMAC over the raw body you got, and it checks out either way.

Inspecting deliveries

Each endpoint's detail panel has a delivery log: event, status, response code, attempt count, and when. Expand a row to see the exact body that was delivered (with a copy button); a settlement row also shows the gross as a chip so the log reads like an earnings feed, not just a status list.

Signing (raw endpoints)

Every raw delivery carries a Naulon-Signature header: t=<unix>,v1=<hex>, an HMAC-SHA256 over `${t}.${rawBody}` with your endpoint's secret. Recompute it over the raw request bytes and compare in constant time; reject anything outside a ~5 minute clock skew. Your secret is shown once when you create the endpoint (and on an explicit reveal or rotate). Store it then.

What we don't send

A settlement webhook tells you the money that landed on your site: the gross, the payees, the on-chain references. It does not carry the query or prompt that led an agent to cite you: that lives with the reading agent, not with your site, so we never claim to have it. What you get is the settlement, in as much depth as we can honestly attribute.