Webhooks
Receive real-time notifications when events occur.
Overview
Webhooks allow your application to receive HTTP POST requests when certain events happen, such as:
- Usage threshold reached (80%, 90%, 100%)
- API key created or revoked
- Plan upgraded or downgraded
Setting Up Webhooks
Via Dashboard
- Go to glyphnet.io/dashboard/settings (opens in a new tab)
- Navigate to "Webhooks"
- Click "Add Webhook"
- Enter your endpoint URL
- Select events to subscribe to
- Save
Via API
curl -X POST https://api.glyphnet.io/v1/webhooks \
-H "X-API-Key: gn_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"url": "https://your-app.com/webhooks/glyphnet",
"events": ["usage.threshold", "key.created", "key.revoked"],
"secret": "your_webhook_secret"
}'Webhook Events
| Event | Description |
|---|---|
usage.threshold.80 | 80% of monthly limit used |
usage.threshold.90 | 90% of monthly limit used |
usage.threshold.100 | Monthly limit reached |
key.created | New API key created |
key.revoked | API key revoked |
plan.upgraded | Plan upgraded |
plan.downgraded | Plan downgraded |
Webhook Payload
All webhooks include:
{
"id": "evt_abc123def456",
"type": "usage.threshold.80",
"created_at": "2024-01-20T15:30:00Z",
"organization_id": "org_xyz789",
"data": {
// Event-specific data
}
}Usage Threshold Example
{
"id": "evt_usage_123",
"type": "usage.threshold.80",
"created_at": "2024-01-20T15:30:00Z",
"organization_id": "org_xyz789",
"data": {
"current_usage": 400000,
"monthly_limit": 500000,
"percentage": 80,
"days_remaining": 11
}
}Key Created Example
{
"id": "evt_key_456",
"type": "key.created",
"created_at": "2024-01-20T15:30:00Z",
"organization_id": "org_xyz789",
"data": {
"key_id": "key_new123",
"key_prefix": "gn_live_a1b2",
"name": "Production Key",
"created_by": "user@example.com"
}
}Verifying Webhooks
We sign all webhook payloads. Verify the signature to ensure authenticity.
Signature Header
X-GlyphNet-Signature: sha256=abc123def456...Verification Code
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, secret: str) -> bool:
"""Verify GlyphNet webhook signature."""
expected = hmac.new(
secret.encode(),
payload,
hashlib.sha256
).hexdigest()
received = signature.replace("sha256=", "")
return hmac.compare_digest(expected, received)
# In your webhook handler
@app.post("/webhooks/glyphnet")
async def handle_webhook(request: Request):
payload = await request.body()
signature = request.headers.get("X-GlyphNet-Signature")
if not verify_webhook(payload, signature, WEBHOOK_SECRET):
raise HTTPException(status_code=401, detail="Invalid signature")
event = await request.json()
if event["type"] == "usage.threshold.80":
send_slack_alert("GlyphNet usage at 80%!")
return {"received": True}Retry Policy
If your endpoint returns a non-2xx status, we retry:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
| 4 | 30 minutes |
| 5 | 2 hours |
After 5 failed attempts, the webhook is marked as failing and you'll receive an email notification.
Best Practices
- Return 200 quickly - Process webhooks asynchronously
- Verify signatures - Always validate the signature header
- Handle duplicates - Use the event
idfor idempotency - Monitor failures - Set up alerts for webhook errors