Webhooks API
Manage webhook subscriptions programmatically. For the protocol (signing, retries, payloads), see /api/webhooks.
List webhooks
GET /api/v1/webhooksResponse:
{
"success": true,
"data": [
{
"id": "whk_xxx",
"url": "https://example.com/akol-webhook",
"events": ["call.ended", "appointment.scheduled"],
"isActive": true,
"lastTriggeredAt": "2026-04-18T14:23:10.000Z",
"failureCount": 0,
"secret": "whsec_••••••••••",
"createdAt": "2026-03-01T00:00:00.000Z"
}
]
}secret is masked in list responses. The plaintext secret is shown only
once at create time.
Create a webhook
POST /api/v1/webhooks
Content-Type: application/json
{
"url": "https://example.com/akol-webhook",
"events": ["call.ended", "call.transferred"]
}URL requirements:
- Must be HTTPS (HTTP is rejected at validation)
- Must not resolve to a private/internal IP (SSRF protection)
- Must respond
2xxto a probe POST within 10 seconds
Response:
{
"success": true,
"data": {
"id": "whk_xxx",
"url": "https://example.com/akol-webhook",
"events": ["call.ended", "call.transferred"],
"secret": "whsec_abcdefghijklmnopqrstuvwxyz123456"
}
}Save the secret immediately — it’s hashed server-side and we cannot
recover it. If you lose it, rotate the webhook (POST /rotate-secret).
Update events / URL
PATCH /api/v1/webhooks/:id
Content-Type: application/json
{
"events": ["call.ended", "appointment.scheduled"],
"isActive": true
}Updating the URL re-runs the probe. If the new URL doesn’t respond, the
update is rejected with 400.
Rotate the signing secret
POST /api/v1/webhooks/:id/rotate-secretReturns a new plaintext secret. The old secret is immediately invalidated — update your verification code BEFORE rotating in production, or you’ll see signature mismatches.
Send a test event
POST /api/v1/webhooks/:id/test
Content-Type: application/json
{ "event": "call.ended" }Fires a synthetic payload of the requested event type. Useful for verifying your endpoint without waiting for a real call.
View delivery logs
GET /api/v1/webhooks/:id/deliveries?page=1&limit=20&success=falseFilter by success=false to see only failed deliveries — handy for
debugging. Each entry includes the payload sent, the response received,
status code, and timing.
Replay a failed delivery
POST /api/v1/webhooks/:id/deliveries/:deliveryId/replayRe-sends the original payload to the current URL. Counts against your rate limit but doesn’t increment retry counters.
Delete a webhook
DELETE /api/v1/webhooks/:idHard delete — deliveries stop immediately. Historical delivery logs are retained for 30 days.