Appearance
Webhook Tools โ
A webhook destination is an HTTP endpoint an owner registers to receive a signed POST every time a Gnosari captures or updates conversation data. This tool creates, configures, and diagnoses destinations conversationally. It does not send deliveries itself: registration and diagnosis happen here, delivery is handled by the platform's delivery pipeline. For the event kinds, the payload envelope, and how to verify a delivery's signature, see Webhook Events Reference and Verifying Webhook Signatures.
gnosari_manage_webhooks โ
Create, read, update, activate, deactivate, delete, or inspect the delivery history of webhook destinations for the authenticated account.
Annotations: readOnlyHint: false ยท destructiveHint: true ยท idempotentHint: false ยท openWorldHint: false
Parameters โ
| Name | Type | Required | Default | Description |
|---|---|---|---|---|
action | string | Yes | - | list, get, create, update, activate, deactivate, delete, or deliveries |
webhook_id | integer | Conditional | - | Destination ID. Required for get, update, activate, deactivate, delete, deliveries |
url | string | Conditional | - | Delivery endpoint address, http(s). Required for create; optional for update. Unsafe addresses (internal networks, unsupported schemes) are refused by the platform's URL guard, with the reason relayed verbatim |
event_kinds | list of string | Conditional | - | Topic ids to subscribe to, e.g. ["data.collected", "data.updated"]. Required for create; optional for update |
include_provenance | boolean | No | false | Include verbatim conversation quotes and message references in deliveries to this destination. Settable on create and update; omit on update to leave unchanged |
active | boolean | No | - | Set the active flag directly (update only). Prefer the activate/deactivate actions for a single state change |
confirmed | boolean | No | false | Must be true to actually delete (delete only). Ask the user to confirm first |
status | string | No | - | Filter delivery history by outcome: success or failed (deliveries only) |
limit | integer | No | 20 | Page size for deliveries (max 100) |
offset | integer | No | 0 | Pagination offset for deliveries |
Returns โ
Return type depends on the action. No response, at any depth and for any action, ever carries the signing secret: see The signing secret below.
| Action | Return Type |
|---|---|
list | list[WebhookDestination] |
get | WebhookDestination |
create | WebhookDestination |
update | WebhookDestination |
activate / deactivate | WebhookDestination |
delete (unconfirmed) | dict with success: false, error: "deletion_not_confirmed", message |
delete (confirmed) | dict with message |
deliveries | WebhookDeliveriesPage |
WebhookDestination fields:
| Field | Type | Description |
|---|---|---|
id | int | Destination ID |
url | str | Delivery endpoint address |
event_kinds | list[str] | Raw subscribed topic ids |
event_kind_details | list[WebhookKindInfo] | Per-kind display name and description |
active | bool | Whether deliveries are currently attempted |
include_provenance | bool | Whether deliveries to this destination include verbatim conversation quotes |
created_at | datetime | Creation time (UTC) |
updated_at | datetime | Last modification time (UTC) |
WebhookKindInfo fields:
| Field | Type | Description |
|---|---|---|
id | str | Stable topic id, e.g. data.collected |
name | str | Display name. Falls back to the raw topic id when the kind is not in the published catalogue |
description | str | One-line explanation of when it fires |
WebhookDeliveriesPage fields:
| Field | Type | Description |
|---|---|---|
data | list[WebhookDeliveryEntry] | Delivery attempts, newest first |
pagination | PaginationMeta | {total, skip, limit, has_more} |
WebhookDeliveryEntry fields:
| Field | Type | Description |
|---|---|---|
delivery_id | uuid | Stable delivery identity (the webhook-id header value on the actual HTTP request) |
event_kind | str | Raw topic id of the delivered event |
event_kind_name | str | Display name of the event kind |
event_kind_description | str | One-line description of the event kind |
attempt_no | int | Attempt number (1-based). Multiple attempts with the same delivery_id are retries of the same delivery |
status | str | Outcome: success or failed |
http_status | int | None | HTTP status code returned by the endpoint, when a response was received |
failure_reason | str | None | See Diagnosing a failing destination below |
occurred_at | datetime | Attempt time (UTC) |
Action: list โ
List every destination for the account.
python
result = gnosari_manage_webhooks(action="list")
for dest in result:
print(f"{dest.id}: {dest.url} ({'active' if dest.active else 'inactive'})")Action: get โ
Get a single destination by id.
python
dest = gnosari_manage_webhooks(action="get", webhook_id=7)
print(dest.url, dest.event_kinds, dest.active)Error: raises "Webhook destination not found" for an unknown id or one owned by another account (the two cases are indistinguishable by design).
Action: create โ
Register a new destination. url and event_kinds are required.
python
dest = gnosari_manage_webhooks(
action="create",
url="https://example.com/hooks/gnosari",
event_kinds=["data.collected", "data.updated"],
)
print(dest.id, dest.active) # active defaults to TrueThe event-content opt-in defaults off; enable it at creation if the owner wants verbatim quotes from the start:
python
dest = gnosari_manage_webhooks(
action="create",
url="https://example.com/hooks/gnosari",
event_kinds=["data.collected"],
include_provenance=True,
)Error: an unknown topic id in event_kinds raises a validation error naming the offending id and the supported kinds (e.g. "Unknown event kind(s): not.a.kind. Supported kinds: data.collected, data.updated.") before anything is created.
Action: update โ
Patch one or more fields. Only the fields you pass change; everything else is left as-is.
python
# Add a second event kind
gnosari_manage_webhooks(action="update", webhook_id=7, event_kinds=["data.collected", "data.updated"])
# Turn the opt-in on for an existing destination
gnosari_manage_webhooks(action="update", webhook_id=7, include_provenance=True)
# Repoint the destination at a new URL
gnosari_manage_webhooks(action="update", webhook_id=7, url="https://example.com/hooks/v2")A url change is re-checked by the URL guard exactly as on create -- see Refusal is server-side below. On refusal, nothing about the destination changes; the previous url stays live.
Action: activate / deactivate โ
Toggle whether a destination receives deliveries, without touching its configuration. Deactivating is reversible and needs no confirmation -- unlike delete.
python
gnosari_manage_webhooks(action="deactivate", webhook_id=7)
# ... later
gnosari_manage_webhooks(action="activate", webhook_id=7)Action: delete โ
Permanently remove a destination. Requires explicit confirmation -- calling delete without confirmed=True never deletes anything; it returns a confirmation-required response and the destination survives untouched.
python
# First call: no confirmed flag -- nothing is deleted
result = gnosari_manage_webhooks(action="delete", webhook_id=7)
# result == {"success": False, "error": "deletion_not_confirmed", "message": "..."}
# Ask the user to confirm, then:
result = gnosari_manage_webhooks(action="delete", webhook_id=7, confirmed=True)
# result == {"message": "Webhook destination 7 deleted"}activate/deactivate need no confirmation because they are reversible. delete is the only gated action, because it is not.
Action: deliveries โ
Paginated, newest-first delivery attempt history for one destination -- the tool to reach for "why is my integration broken?".
python
page = gnosari_manage_webhooks(action="deliveries", webhook_id=7, limit=10)
for entry in page.data:
print(entry.occurred_at, entry.status, entry.http_status, entry.failure_reason)
# Only the failures
failures = gnosari_manage_webhooks(action="deliveries", webhook_id=7, status="failed")
print(f"{failures.pagination.total} failed attempts on record")Diagnosing a failing destination โ
Every failed attempt carries a failure_reason from a fixed taxonomy. Attempts with the same delivery_id and increasing attempt_no are retries of the same delivery, not separate events.
failure_reason | Meaning | Where to look |
|---|---|---|
dns_failure | The destination hostname did not resolve | The hostname is misspelled, or DNS for that domain is down |
tls_failure | The TLS handshake failed | An expired or misconfigured certificate at the endpoint |
connect_timeout | The endpoint did not accept a connection in time | The service is down, or a firewall is dropping the connection |
read_timeout | A connection was made but the endpoint did not respond in time | The endpoint accepted the request but hung before responding |
http_status | The endpoint responded with a non-2xx status | Read http_status for the exact code -- the endpoint itself rejected the delivery |
ssrf_refused | The URL was refused by the platform's URL guard at delivery time | The destination address is not (or is no longer) publicly reachable; the same class of refusal create/update reject at registration time |
A typical walk: call deliveries with status="failed", read the most recent failure_reason, tell the owner what it means and where to look, then -- once they fix the endpoint -- call deliveries again and confirm a new success entry appears.
Event kinds โ
event_kinds accepts the platform's published topic ids. The full catalogue, what triggers each kind, and the exact payload envelope shape are documented once, authoritatively, in Webhook Events Reference -- not repeated here. Every WebhookDestination and WebhookDeliveryEntry this tool returns augments each raw topic id with its display name and one-line description (event_kind_details / event_kind_name + event_kind_description), so a kind can be reported to the user without separately looking up the catalogue. An id outside the published catalogue is returned raw, with its own id as the display name -- never dropped or blanked.
The event-content opt-in โ
include_provenance is a per-destination, default-off setting. When enabled, deliveries to that destination include verbatim conversation quotes and message references alongside the structured data. When left off (the default), deliveries carry only structured field data -- no quotes, no message text.
It is set independently per destination -- turning it on for one destination does not affect any other. Set it at registration time (create) or flip it later (update); both take the same boolean.
The signing secret is never returned โ
No action on this tool ever returns the destination's signing secret, and there is no action that reveals one. The secret is issued once, at destination creation, and from then on it can only be viewed by an owner directly in the dashboard, at /settings/webhooks/{id}.
If an owner (or an agent acting on their behalf) needs the secret to verify a delivery's signature, the answer is always "open the destination in your dashboard settings" -- never a tool call. There is no action that will produce it, no matter how the request is phrased.
Refusal is server-side, not validated by this tool โ
The tool performs no client-side URL validation. Every url passed to create or update is checked by the platform's URL guard, which refuses unsafe addresses (internal networks, link-local and cloud-metadata ranges, unsupported schemes) before anything is created or changed. When a url is refused, the guard's explanation is relayed to the caller unchanged, for example:
Blocked destination: 169.254.169.254 resolves to the internal address 169.254.169.254Report the message to the owner verbatim -- it already states the reason. Nothing is created or modified when a create or update call is refused; a refused update leaves the destination's previous url untouched.
Next Steps โ
- API Overview - Tool relationships and common patterns
- Webhook Events Reference - Event kinds and payload envelope
- Verifying Webhook Signatures - Confirm a delivery is genuine