Webhooks
Webhooks allow your application to receive real-time HTTP notifications when events occur in PUGUH.
How Webhooks Work
- You register an endpoint URL in PUGUH
- You subscribe to specific event types
- When an event occurs, PUGUH sends an HTTP POST to your endpoint
- Your server processes the payload and responds with
200 OK
Event Types
PUGUH emits events across all infrastructure modules:
Identity Events
| Event | Description |
|---|---|
user.created | New user registered |
user.updated | User profile changed |
user.deleted | User account deleted |
auth.login | User logged in |
auth.logout | User logged out |
auth.password_changed | Password was changed |
auth.mfa_enabled | MFA activated |
Organization Events
| Event | Description |
|---|---|
organization.created | New organization created |
organization.updated | Organization settings changed |
member.invited | Member invited |
member.joined | Member accepted invitation |
member.removed | Member removed |
member.role_changed | Member role updated |
Billing Events
| Event | Description |
|---|---|
billing.subscription.created | New subscription started |
billing.subscription.updated | Plan changed |
billing.subscription.cancelled | Subscription cancelled |
billing.invoice.paid | Invoice payment received |
billing.invoice.overdue | Payment past due |
Creating an Endpoint
Via API
bash
curl -X POST https://api-puguh.arsaka.io/webhooks/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Organization-ID: YOUR_ORG_ID" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/puguh",
"events": ["user.created", "member.invited", "billing.invoice.paid"],
"description": "Production webhook"
}' Response:
json
{
"id": "wh_abc123",
"url": "https://your-app.com/webhooks/puguh",
"events": ["user.created", "member.invited", "billing.invoice.paid"],
"secret": "whsec_xxxxxxxxxxxxxxxx",
"is_active": true,
"created_at": "2026-02-20T10:00:00Z"
} Important
The secret is only returned once at creation. Save it securely for signature verification.
Webhook Payload
Each delivery sends a JSON POST request:
json
{
"event": "member.invited",
"timestamp": "2026-02-20T10:30:00Z",
"data": {
"organization_id": "org_abc",
"email": "new-member@example.com",
"role": "member",
"invited_by": "admin@example.com"
},
"webhook_id": "wh_abc123",
"delivery_id": "del_xyz789"
} Headers
| Header | Description |
|---|---|
Content-Type | application/json |
X-Puguh-Signature | HMAC-SHA256 signature |
X-Puguh-Delivery-ID | Unique delivery identifier |
X-Puguh-Event | Event type (e.g. user.created) |
Verifying Signatures
Always verify the X-Puguh-Signature header to ensure the request is from PUGUH.
Python
python
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
expected = hmac.new(
secret.encode(), payload, hashlib.sha256
).hexdigest()
return hmac.compare_digest(f"sha256={expected}", signature) TypeScript
typescript
import { createHmac, timingSafeEqual } from 'crypto';
function verifyWebhook(payload: string, signature: string, secret: string): boolean {
const expected = `sha256=${createHmac('sha256', secret).update(payload).digest('hex')}`;
return timingSafeEqual(Buffer.from(signature), Buffer.from(expected));
} Retry Policy
If your endpoint returns a non-2xx status, PUGUH retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st retry | 1 minute |
| 2nd retry | 5 minutes |
| 3rd retry | 30 minutes |
| 4th retry | 2 hours |
| 5th retry | 12 hours |
After 5 failed attempts, the delivery is moved to the dead letter queue. You can manually retry from the dashboard or API.
Managing Endpoints
List Endpoints
bash
curl https://api-puguh.arsaka.io/webhooks/endpoints \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "X-Organization-ID: YOUR_ORG_ID" Update Endpoint
bash
curl -X PUT https://api-puguh.arsaka.io/webhooks/endpoints/wh_abc123 \
-H "Authorization: Bearer YOUR_TOKEN" \
-d '{"events": ["user.created", "billing.invoice.paid"], "is_active": true}' Delete Endpoint
bash
curl -X DELETE https://api-puguh.arsaka.io/webhooks/endpoints/wh_abc123 \
-H "Authorization: Bearer YOUR_TOKEN" View Deliveries
bash
curl https://api-puguh.arsaka.io/webhooks/endpoints/wh_abc123/deliveries \
-H "Authorization: Bearer YOUR_TOKEN" Limits by Plan
| Plan | Max Endpoints | Retry |
|---|---|---|
| Free | 3 | 3 attempts |
| Pro | 10 | 5 attempts |
| Business | 25 | 5 attempts + guaranteed delivery |
| Enterprise | Unlimited | 5 attempts + guaranteed delivery |
Best Practices
- Always verify signatures to prevent spoofed requests
- Respond quickly with
200 OKand process events asynchronously - Handle duplicates using
delivery_idfor idempotency - Use HTTPS for your endpoint URL
- Monitor delivery failures in the dashboard
- Rotate secrets periodically for security