Partner Webhooks
Configure webhook notifications for partner-scoped events. Requires a partner API key (pvp_ or pvt_ prefix).
Auth: Authorization: Bearer pvp_... or Authorization: Bearer pvt_...
Base URL: https://provenonce.io
PUT /api/v1/partner/webhook
Register or update a webhook endpoint.
curl -X PUT https://provenonce.io/api/v1/partner/webhook \
-H "Content-Type: application/json" \
-H "Authorization: Bearer pvp_..." \
-d '{
"url": "https://example.com/webhook",
"events": ["sigil.purchased", "heartbeat.recorded", "agent.frozen"]
}'Request body
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS webhook endpoint URL |
events | string[] | Yes | Event types to subscribe to |
Event types
| Event | Trigger |
|---|---|
sigil.purchased | An agent under this partner purchases a SIGIL |
heartbeat.recorded | An agent under this partner sends a heartbeat |
agent.frozen | An agent under this partner is frozen by the DMS |
agent.unfrozen | An agent under this partner resyncs and becomes active |
Response
{
"webhook_url": "https://example.com/webhook",
"webhook_secret": "a1b2c3d4e5f6...",
"events": ["sigil.purchased", "heartbeat.recorded", "agent.frozen"]
}The webhook_secret is a 32-byte hex string generated server-side. Use it to verify webhook signatures.
DELETE /api/v1/partner/webhook
Remove the webhook configuration.
curl -X DELETE https://provenonce.io/api/v1/partner/webhook \
-H "Authorization: Bearer pvp_..."Response
{ "ok": true }GET /api/v1/partner/webhook
Retrieve current webhook configuration.
curl https://provenonce.io/api/v1/partner/webhook \
-H "Authorization: Bearer pvp_..."Response
{
"webhook_url": "https://example.com/webhook",
"events": ["sigil.purchased", "heartbeat.recorded", "agent.frozen"],
"configured": true
}The secret is not returned in GET requests.
Webhook payload
Webhook deliveries are POST requests with HMAC-SHA256 signature in the x-provenonce-signature header.
x-provenonce-signature: sha256=<hex_hmac>Verify by computing HMAC-SHA256(webhook_secret, request_body) and comparing to the header value.
Delivery timeout is 3 seconds. Failed deliveries are queued in a dead-letter queue for retry.
Error responses
| Status | Body | Cause |
|---|---|---|
| 400 | {"error": "...", "code": "WEBHOOK_INVALID"} | Missing or invalid URL/events |
| 401 | {"error": "...", "code": "AUTH_MISSING"} | Missing auth header |
| 403 | {"error": "...", "code": "AUTH_FORBIDDEN"} | Partner not found or suspended |
| 429 | {"error": "...", "code": "RATE_LIMITED"} | Rate limit exceeded |