Webhooks#
Agent API webhooks send signed HTTPS POSTs when supported agent events are persisted. Webhook delivery is at least once; receivers should dedupe by event id.
Management Routes#
Agents can manage up to 10 webhook endpoints.
GET /v1/agent/webhooks
POST /v1/agent/webhooks
GET /v1/agent/webhooks/{id}
PATCH /v1/agent/webhooks/{id}
DELETE /v1/agent/webhooks/{id}
GET /v1/agent/webhooks/{id}/deliveries
POST /v1/agent/webhooks/{id}/rotate-secret
POST /v1/agent/webhooks/{id}/testWebhook management writes use the webhook_management rate-limit class and require Idempotency-Key.
Create and rotate responses return the signing secret once. Store it immediately.
Endpoint Requirements#
Webhook URLs must be public HTTPS endpoints. Hightop rejects:
- plain HTTP
- private networks
- localhost and
*.localhost - redirects
- unsupported schemes such as
file://,gopher://, orftp:// - URL credentials such as
https://user:pass@example.com/hook
Hightop revalidates DNS before delivery and pins the request to the validated public address set.
Event Envelope#
{
"id": "uuid",
"type": "payment.executed",
"created_at": "2026-05-16T00:00:00.000Z",
"agent_id": "uuid",
"wallet_id": "wallet-id",
"operation_id": "uuid",
"resource": {
"type": "payment",
"id": "uuid"
},
"data": {}
}Emitted Event Types#
Shipped v1 producers emit:
payment.executed
payment.execution_failed
one_off_payment.created
conversion.executed
conversion.execution_failed
earn.deposit.executed
earn.withdraw.executed
earn.move.executed
rewards.claimed
debt.borrowed
debt.repaid
debt.deleveraged
collateral.added
collateral.removed
withdrawal.settled
withdrawal.execution_failed
agent.webhook_disabled
operation.policy_rejected
webhook.testSubscribable but not normally triggered by public Agent API calls:
trusted_destination.confirmed
trusted_destination.cancelled
trusted_destination.removedThese trusted-destination event types can be emitted by internal or system finalization paths. Public Agent API v1 does not expose trusted-destination mutation routes.
Reserved or not emitted by shipped v1 producers:
payment.submitted
payment.received
one_off_payment.claimed
one_off_payment.expired
withdrawal.submitted
deposit.received
recurring_payment.updated
recipient.changed
agent.limit_approaching
agent.limit_reached
agent.disabled
agent.expired
agent.expiring_soonExecution-failure webhook events are explicit only for payment, conversion, and withdrawal operation families in v1. Other operation families still finalize and create Activity, but they do not emit a public failure webhook until a stable v1.x event type exists.
Signing#
Deliveries include:
User-Agent: Hightop-Webhooks/1.0
Hightop-Webhook-Id: <event id>
Hightop-Webhook-Timestamp: <unix timestamp>
Hightop-Webhook-Signature: v1=<hex hmac>
Content-Type: application/jsonDuring the 24-hour secret-rotation grace window, Hightop-Webhook-Signature contains both current and previous signatures as comma-separated v1=<hex hmac> values.
The HMAC covers:
${timestamp}.${raw_body}Verify the raw body bytes, not parsed JSON. Use a 5-15 minute timestamp tolerance.
TypeScript Verification#
import crypto from 'crypto'
export function verifyHightopWebhook(secret: string, timestamp: string, rawBody: string, signature: string) {
const expected = crypto.createHmac('sha256', secret).update(`${timestamp}.${rawBody}`).digest('hex')
const expectedBuffer = Buffer.from(expected, 'hex')
return signature.split(',').some((part) => {
const [version, value] = part.trim().split('=')
if (version !== 'v1' || !value) return false
const actualBuffer = Buffer.from(value, 'hex')
return actualBuffer.length === expectedBuffer.length && crypto.timingSafeEqual(actualBuffer, expectedBuffer)
})
}Delivery Rules#
- Payloads are capped at 256 KB.
- Each delivery attempt has a 10-second total deadline.
- Receiver response bodies are captured up to 4 KB for diagnostics.
- Retryable failures retry for up to 72 hours.
- Exhausted endpoints are auto-disabled with
disabled_reason = "sustained_failures". - Endpoints auto-disabled for
sustained_failuresmust be re-enabled by the owner in the app;PATCH enabled=truereturnsowner_only_action. - Rotating the secret for an endpoint disabled by
sustained_failuresalso returnsowner_only_action.
Retryable failures:
- network errors and timeouts
- HTTP 408
- HTTP 429
- HTTP 5xx
Terminal outcomes:
- HTTP 2xx is delivered
- HTTP 3xx redirects fail terminally
- most HTTP 4xx fail terminally, except 408 and 429
- TLS certificate failures fail terminally
- SSRF validation failures fail terminally
- oversize payloads fail terminally
