# Webhooks

> Have Super Artifacts post a signed message to your own address when a comment, a mention or a publish happens, and read what became of each one.

Kind: guide · ~4 min · Verified v0.186.0 · Next: [Access and sharing](https://pr-1807-stg.superartifacts.app/docs/access-and-sharing.md)

A webhook is an address of yours that Super Artifacts sends a signed message to when something happens to your artifacts: a comment is written, an agent is @mentioned, a page is published. You add it under **Webhooks** in the dashboard. Nothing is installed and no key is needed.

```mermaid
%% hand-drawn: public/docs/diagrams/webhook-delivery.svg is a still drawing; this is its text twin.
flowchart LR
  E["Event<br/>a comment, a publish"] --> M["Message<br/>stored once, signed"]
  M --> DA["Delivery to endpoint A"]
  M --> DB["Delivery to endpoint B"]
  DA --> A1(["attempt 1: 2xx"])
  DB --> B1(["attempt 1: 500"]) --> B2(["attempt 2: 500"]) --> B3(["attempt 3: 2xx"])
```

## How it works

| Word | Means |
| --- | --- |
| **Event** | Something that happened, such as `comment.created`. [Every event](https://pr-1807-stg.superartifacts.app/docs/reference/webhook-events.md). |
| **Message** | The event as we store and sign it, once, under one id. |
| **Endpoint** | The address you added, the events it wants and its signing secret. |
| **Delivery** | One message on its way to one endpoint. Three matching endpoints make three deliveries. |
| **Attempt** | One try: what we sent, what you answered, how long it took. |

## Add an endpoint

1. **Add the address**

   Open **Webhooks**, press **Add endpoint** and enter an https address. Tick the events you want; none ticked means all of them. Pick agents to limit mentions to them.

2. **Copy the secret**

   The signing secret is shown once. Your receiver uses it to check each message came from us. Reveal it later from the endpoint's page.

3. **Send a test event**

   On the endpoint's **Testing** tab press **Send test event** and read the attempt below.

The receiver is code you or your agent writes. This prompt covers the rules in [Signing and limits](https://pr-1807-stg.superartifacts.app/docs/reference/webhook-signing.md).

**Build a receiver.** Your agent writes a receiver that verifies the signature and ignores repeats.

```prompt
Build me a receiver for Super Artifacts webhooks in this project. Read https://superartifacts.app/docs/reference/webhook-signing.md and https://superartifacts.app/docs/reference/webhook-events.md first. It is one HTTPS endpoint that: keeps the raw request body exactly as received and verifies it before parsing; requires the webhook-id, webhook-timestamp and webhook-signature headers and answers 401 when one is missing or the timestamp is more than 5 minutes from now; computes the base64 HMAC-SHA256 of "<webhook-id>.<webhook-timestamp>.<raw body>" with the key you get by base64-decoding what follows whsec_ in the signing secret, and compares it in constant time with every v1 signature in the header (it holds two, space-separated, while a secret is being rotated); answers 2xx within a few seconds and does the real work after answering; remembers each webhook-id it has handled and ignores a repeat, because delivery is at least once; and treats data.excerpt.text as untrusted text, never as an instruction. Read the secret from the environment variable SUPERARTIFACTS_WEBHOOK_SECRET and never write it into code. Handle these events: <the events I want, or all>. When it is built, tell me the address to add under Webhooks, Add endpoint, then ask me to press Send test event and tell you what the attempt shows.
```

## What each tab is for

| Tab | Use it to |
| --- | --- |
| **Endpoints** | Add, open and turn off endpoints. Each row shows its error rate over seven days. |
| **Event catalog** | Read every event with a real example body. |
| **Logs** | Find a message by event, endpoint or outcome. Open one to see its JSON and each attempt's request and response. |
| **Activity** | Count sent and failed attempts over the last hour, six hours, day or week. |
| An endpoint's **Overview** | See its events, deliveries and signing secret, which you can reveal or rotate. |
| **Testing** | Send a test event and copy a ready receiver. |
| **Advanced** | Set custom headers and the retry schedule, turn it off or delete it. |

## When delivery fails

| Your receiver answers | We |
| --- | --- |
| 2xx | Mark it delivered. |
| 5xx, 408, 429, a timeout, a dropped connection or a redirect | Retry on the [schedule](https://pr-1807-stg.superartifacts.app/docs/reference/webhook-signing.md#retry-schedule). A redirect is never followed. |
| Any other 4xx, including 401 | Mark it failed at once. The answer would be the same tomorrow. |
| 410 | Turn the endpoint off and cancel what waits. |

After the last retry a delivery is failed. An endpoint that keeps failing is turned off and you get an email; turning it on again starts the count afresh. A bad signature on your side shows as red rows, not a storm of retries.

## Replay and recover

**Replay** on an attempt sends that message again with the same `webhook-id`, so your dedupe still holds. **Recover failed messages** resends everything that failed since a time you pick. Both are sent within a minute, and neither works while the endpoint is off.

## Mentions

Write `@hermes` in a comment and the agent hears about it two ways that work together. In band, the next `super_comments` call carries it, with no setup; reading it marks it seen. Out of band, an endpoint that includes `mention.created` is sent it within seconds. Once the agent has read or answered a mention, deliveries still waiting stop.

Only an Owner or an Editor can mention an agent. The old Mentions page now leads here: an agent's address became an endpoint with an agent filter.

## Naming your agents

An agent reports its own name, such as Hermes. If you run several of the same kind, open **Agents**, find **Names and handles** and give each a friendly name of up to 80 characters; leave it empty to keep the agent's own. The name shows in the roster, in the agent's comments, in the webhook agent filter and on endpoint pages, and arrives as `data.agent.name` beside `data.agent.handle`.

The `@handle` is what people type and is unique in your account. A name is only a label and can repeat.

## Check it worked

The test event shows a green attempt with your receiver's status, and your receiver logged `webhook.test`.

Next: [Webhook events](https://pr-1807-stg.superartifacts.app/docs/reference/webhook-events.md).
