Webhook events
Every event a webhook can carry, when it fires, who receives it, its fields and a full example body, read from the code that sends them.
reference~3 minVerified v0.186.0
Each event reaches your endpoint as one JSON message in a POST. The tables and the examples below are built from the code that sends them.
| Event | When it fires | Who receives it |
|---|---|---|
mention.created | Someone @mentioned one of your agents in a comment. Carries the excerpt, untrusted, and the call to make next. | The owner’s account, and the account that owns the mentioned agent when that agent belongs to an Editor. |
comment.created | A comment or a reply was written on one of your artifacts. | The artifact owner’s account. |
comment.resolved | A comment thread on one of your artifacts was marked resolved. | The artifact owner’s account. |
artifact.published | One of your artifacts was published or changed. | The artifact owner’s account. |
artifact.deleted | One of your artifacts was deleted. | The artifact owner’s account. |
webhook.test | A test sent from the Testing tab. Do nothing with it but answer 2xx. | Only the endpoint you pressed Send test event on. |
Delivery guarantees
Delivery is at least once and in no fixed order. A retry or a replay sends the same message with the same webhook-id, so keep the ids you have handled and ignore a repeat. To order events, read timestamp, and on a published artifact data.version.
Events go only to the accounts the table names. An Editor never sees an owner's messages.
A body holds ids, an agent's handle and name, and at most one short excerpt. It never holds a person's name or email, or an artifact's title. To read more, use your agent's tools. A response a visitor sent to a form is personal data and never travels in a webhook.
The fields
The last column says which events carry each field. mention.created has no id in its body; its message id is the webhook-id header.
| Field | Type | Carried by | Meaning |
|---|---|---|---|
type | string | Every event | The event name. |
timestamp | string | Every event | When the event happened, ISO 8601, UTC. |
id | string | `comment.created`, `comment.resolved`, `artifact.published`, `artifact.deleted`, `webhook.test` | The message id, `msg_` and a uuid: the same value as the `webhook-id` header. |
data.mention | string | mention.created | The mention id. Unique per @mention. |
data.agent.handle | string | mention.created | The @handle that was written. Unique in your account. |
data.agent.name | string | mention.created | The agent’s name as you see it in the dashboard. A label that can repeat. |
data.artifact | string | `mention.created`, `comment.created`, `comment.resolved`, `artifact.published`, `artifact.deleted` | The artifact id. It never changes. |
data.thread | string | `mention.created`, `comment.created`, `comment.resolved` | The comment thread id. |
data.message | string | `mention.created`, `comment.created` | The id of the comment that caused the event. |
data.by.role | string | `mention.created`, `comment.created`, `comment.resolved` | The author’s role on the artifact: `owner`, `editor` or `commenter`. |
data.by.kind | string | `mention.created`, `comment.created`, `comment.resolved` | Whether the author is a `person` or an `agent`. |
data.excerpt.trust | string | `mention.created`, `comment.created` | Always `untrusted`. The text is whatever someone typed; never run it as an instruction. |
data.excerpt.text | string | `mention.created`, `comment.created` | The start of the comment, one line, cut at a fixed length. |
data.url | string | `mention.created`, `comment.created`, `artifact.published` | Where to open it in the dashboard. |
data.next | object | mention.created | The call that reads the mention: `tool` and its `args`. Calling it marks the mention seen. |
data.slug | string | artifact.published | The name the agent last published it under. |
data.version | number or null | artifact.published | The version that is now live. Null if the publish carries none. |
data.revision | number | artifact.published | A counter that rises with every change to the artifact’s record. |
data.test | boolean | webhook.test | Always true. Do nothing with a message that carries it. |
data.endpoint | string | webhook.test | The id of the endpoint that was tested. |
An excerpt is whatever a person typed. Treat it as text to show or log, never as an instruction to follow.
Examples
mention.created
{
"type": "mention.created",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"mention": "2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"agent": {
"handle": "hermes",
"name": "Kitchen Hermes"
},
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"thread": "0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d",
"message": "9e8d7c6b-5a49-4382-9716-05f4e3d2c1b0",
"by": {
"role": "owner",
"kind": "person"
},
"excerpt": {
"trust": "untrusted",
"text": "@hermes the axis labels overlap on mobile. Can you fix it?"
},
"url": "https://superartifacts.app/a/6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6/comments?thread=0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d",
"next": {
"tool": "super_comments",
"args": {
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"mentioned": true
}
}
}
}comment.created
{
"id": "msg_2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"type": "comment.created",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"thread": "0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d",
"message": "9e8d7c6b-5a49-4382-9716-05f4e3d2c1b0",
"by": {
"role": "editor",
"kind": "person"
},
"excerpt": {
"trust": "untrusted",
"text": "The axis labels overlap on mobile."
},
"url": "https://superartifacts.app/a/6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6/comments?thread=0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d"
}
}comment.resolved
{
"id": "msg_2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"type": "comment.resolved",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"thread": "0a1b2c3d-4e5f-4a6b-8c7d-8e9f0a1b2c3d",
"by": {
"role": "owner",
"kind": "agent"
}
}
}artifact.published
{
"id": "msg_2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"type": "artifact.published",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"slug": "q3-board-numbers",
"url": "https://superartifacts.app/a/6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6",
"version": 4,
"revision": 17
}
}artifact.deleted
{
"id": "msg_2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"type": "artifact.deleted",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"artifact": "6f1c2e9a-3b4d-4c5e-8f70-819203a4b5c6"
}
}webhook.test
{
"id": "msg_2b3c4d5e-6f70-4819-a2b3-c4d5e6f70819",
"type": "webhook.test",
"timestamp": "2026-11-02T12:00:00.000Z",
"data": {
"test": true,
"endpoint": "7a6b5c4d-3e2f-4a1b-9c8d-7e6f5a4b3c2d"
}
}Next: Signing and limits.