// automation

Sending webhooks

An outbound endpoint is a destination you register once, and an agent then POSTs to it by name. The destination can be a URL you control or another deployed agent in the same workspace, which is how two agents talk to each other without either of them holding a credential.

signed by defaultexternal or agent targetone retry on 5xx
01// what an outbound endpoint is

Two target kinds

A external endpoint POSTs to an http or https URL you supply. It generates a signing secret by default so the receiver can verify the payload, and you can opt out of signing if the receiver will not verify.

An agent endpoint POSTs to a sibling deployed agent. Signing is forced on and cannot be turned off, and the dispatcher signs with the receiving endpoint’s own secret rather than one you manage. The receiver needs an inbound endpoint configured for an agent sender before the send will land, so create that side first. Agent-to-agent deliveries also carry a source-agent header, so the receiving side can attribute who called.

Bind the endpoint to the agent that will use it and the dashboard groups it under that agent, which matters as soon as you have more than a couple.

02// managing endpoints

Over REST

Endpoints live under /v1/outbound-webhook-endpoints, authenticated with Authorization: Bearer <key>. Names follow the same slug rule as inbound endpoints: 3 to 50 characters, lowercase alphanumeric and hyphens, starting and ending with a letter or digit, unique per workspace.

register a destinationbash
curl -X POST https://api.superagnt.com/v1/outbound-webhook-endpoints \
  -H "Authorization: Bearer $AGNTDATA_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "ops-notifier",
    "targetKind": "external",
    "targetUrl": "https://hooks.example.com/agnt",
    "description": "Ping our ops service when a run finishes"
  }'

# 201 → the endpoint id, plus the generated signing secret, shown once.
RouteDoes
POST /v1/outbound-webhook-endpointsRegisters a destination. A target URL is required for an external target and must be http or https; a target agent id is required for an agent target.
GET /v1/outbound-webhook-endpointsEvery outbound endpoint in the workspace.
GET /v1/outbound-webhook-endpoints/:idOne endpoint, including whether it holds a signing secret, but never the secret itself.
GET /v1/outbound-webhook-endpoints/deliveriesThe send log. Filter with endpointId, page with limit and cursor.
DELETE /v1/outbound-webhook-endpoints/:idDeactivates the destination — the soft delete. Sends to it start failing; agnt_webhooks_set_active re-enables it.

no POST that sends

There is deliberately no public route that lets an API key flush a delivery. The REST surface registers and audits destinations; sending is an agent capability, so a leaked key cannot be turned into an outbound relay.
03// sending

One tool does the dispatch

agnt_webhooks_send takes an endpoint (its name or its id) and a JSON payload. The body goes out as application/json with a 10 second timeout.

agnt_webhooks_sendtext
agnt_webhooks_send({
  endpoint: "ops-notifier",          // the endpoint name, or its id
  payload: { run_id: "run_42", status: "completed", rows: 1840 }
})

Four management tools sit alongside it: agnt_webhooks_create_outbound registers a destination, agnt_webhooks_update_outbound patches the target URL, description or signing requirement in place (renaming would break the sender’s calls, so it does not), agnt_webhooks_set_active disables an endpoint without deleting it, and agnt_webhooks_rotate_secret mints a new signing secret.

retries stop at one

A failed send is retried exactly once, and only when the failure looks transient: a network error or a 5xx. A 4xx is terminal, because no amount of retrying fixes a 401 at the receiver. Both attempts are recorded, the second linked back to the first.
04// the signature

The same scheme, both directions

A signed outbound delivery carries x-agnt-webhook-timestamp and x-agnt-webhook-signature (v1=<hex>) over v1:${timestamp}:${rawBody}, HMAC-SHA256, with the same five minute replay window the ingest receiver enforces. Sender and receiver share one implementation, so one verifier covers both directions.

The worked verifier, in Node and Python, is on Receiving webhooks. Hand it to whoever owns the receiving service, along with the signing secret.

signing on with no secret fails the send

An endpoint that requires signing but holds no secret does not send: the delivery is written straight to failed with that reason. Rotate a secret onto the endpoint before you require signing on it.
05// signing secrets

Never on the API-key surface

A newly generated secret is returned once, at creation or at rotation. After that no /v1 route reveals it and none rotates it: reading a signing secret is a dashboard action, logged as a reveal, and rotation happens either in the dashboard or through agnt_webhooks_rotate_secret. An API key on its own can register destinations and read the audit log, but cannot extract the material that would let it forge a signed payload.

Rotation takes effect immediately and the previous secret stops working on the next send, so update the receiver in the same window.

06// auditing what was delivered

Every attempt is a row

Each dispatch writes a delivery row, newest first, whether it succeeded or not. This is the surface that answers “did it actually go out, and what did the receiver say”.

FieldWhat it tells you
dispatch_statuspending, succeeded or failed. Anything below a 400 from the receiver counts as succeeded.
response_statusWhat the receiver returned. Null means the request never completed (timeout or network error).
response_bodyStored truncated. Enough to read an error message, not enough to archive a payload.
attempt1 is the first try, 2 is the single auto-retry. A retry row points back at the attempt it retried.
signedWhether this delivery carried a signature. The first thing to check when a receiver rejects everything.
receiving_delivery_idFor agent-to-agent sends, the delivery id the receiving endpoint created. Joins both halves of the hop.

From an agent, agnt_webhooks_list_deliveries with the outbound direction returns that list, filtered by endpoint or by outcome, and agnt_webhooks_get_delivery returns a single row with the heavy fields the list omits: the full request payload and headers, and the response body and headers.

read the send log over RESTbash
curl "https://api.superagnt.com/v1/outbound-webhook-endpoints/deliveries?endpointId=<id>&limit=50" \
  -H "Authorization: Bearer $AGNTDATA_API_KEY"

# page forward with the returned cursor
curl "https://api.superagnt.com/v1/outbound-webhook-endpoints/deliveries?cursor=<cursor>" \
  -H "Authorization: Bearer $AGNTDATA_API_KEY"
07// related