What are Webhooks?
Webhooks notify your application when customers reach limit thresholds. Use them to:
- Alert customers before they hit limits
- Sync usage data to billing systems
- Trigger automated actions (upgrade prompts, notifications)
How Alerts Work
When an event is recorded, Limitry checks all applicable limits. If a threshold is crossed, a webhook is fired:
Setting Alert Thresholds
Configure thresholds when creating limits:
limit = client.limits.create(
name="Monthly token limit",
meter_id="mtr_tokens",
limit_value=100000,
period="month",
customer_id="cust_123",
alert_thresholds=[80, 100] # Alert at 80% and 100%
)
Common threshold patterns:
| Pattern | Thresholds | Use Case |
|---|
| Warning only | [80] | Soft limits, usage awareness |
| Warning + exceeded | [80, 100] | Standard enforcement |
| Multiple warnings | [50, 75, 90, 100] | Gradual notifications |
| Exceeded only | [100] | Hard cutoffs |
Configuring Webhook Endpoints
Configure webhook endpoints in your project settings in the Limitry dashboard:
- Go to Settings > Webhooks
- Click Add Webhook
- Enter your endpoint URL (e.g.,
https://api.yourapp.com/limitry-webhook)
- Copy the signing secret for verification
Store the webhook secret securely. You’ll need it to verify incoming requests.
Webhook Payload
When a threshold is crossed, Limitry sends a POST request:
{
"event": "limit.threshold_reached",
"timestamp": "2024-01-15T10:30:00Z",
"data": {
"customerId": "cust_123",
"limitId": "lmt_abc123",
"limitName": "Monthly token limit",
"threshold": 80,
"limit": 100000,
"currentUsage": 82000,
"percentage": 82,
"remaining": 18000,
"period": "month",
"windowStart": "2024-01-01T00:00:00Z",
"windowEnd": "2024-02-01T00:00:00Z"
}
}
| Field | Description |
|---|
event | limit.threshold_reached or limit.exceeded |
threshold | The percentage threshold that was crossed (e.g., 80) |
percentage | Current usage as a percentage of limit |
remaining | Units remaining before limit is reached |
windowStart | Start of the current billing period |
windowEnd | End of the current billing period (null for all_time) |
Verifying Webhooks
Verify the signature to ensure requests are from Limitry:
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)
# In your webhook handler
@app.post("/limitry-webhook")
def handle_webhook(request):
signature = request.headers.get("X-Limitry-Signature")
payload = request.body
if not verify_webhook(payload, signature, WEBHOOK_SECRET):
return {"error": "Invalid signature"}, 401
data = request.json()
# Handle the webhook...
Handling Webhooks
Example webhook handler:
@app.post("/limitry-webhook")
def handle_webhook(request):
data = request.json()
if data["event"] == "limit.threshold_reached":
customer_id = data["data"]["customerId"]
threshold = data["data"]["threshold"]
percentage = data["data"]["percentage"]
if threshold == 80:
# Send warning email
send_usage_warning(customer_id, percentage)
elif threshold == 100:
# Limit exceeded
notify_customer_limit_reached(customer_id)
# Optionally sync to Stripe
update_stripe_usage(customer_id, data["data"]["currentUsage"])
return {"received": True}
Deduplication
Alerts are deduplicated per billing period. If a customer crosses 80% multiple times in the same month, only the first crossing triggers a webhook.
This is tracked by:
- Customer ID
- Limit ID
- Threshold percentage
- Period window start
Retry Behavior
Failed webhook deliveries are logged but not automatically retried. Check the webhook delivery status in the Limitry dashboard under Settings > Webhooks > Delivery Logs.
Integrating with Slack
Send limit alerts to Slack:
import requests
@app.post("/limitry-webhook")
def handle_webhook(request):
data = request.json()
if data["event"] == "limit.threshold_reached":
d = data["data"]
# Format Slack message
message = {
"text": f"Usage alert for customer {d['customerId']}",
"blocks": [
{
"type": "section",
"text": {
"type": "mrkdwn",
"text": f"*{d['limitName']}*\n{d['percentage']}% used ({d['currentUsage']:,} / {d['limit']:,})"
}
}
]
}
requests.post(SLACK_WEBHOOK_URL, json=message)
return {"received": True}
Integrating with Stripe
Sync usage to Stripe metered billing:
import stripe
@app.post("/limitry-webhook")
def handle_webhook(request):
data = request.json()
if data["event"] == "limit.threshold_reached":
customer_id = data["data"]["customerId"]
usage = data["data"]["currentUsage"]
# Get Stripe subscription from customer metadata
customer = limitry.customers.retrieve(customer_id)
subscription_item_id = customer.metadata.get("stripe_subscription_item_id")
if subscription_item_id:
# Report usage to Stripe
stripe.SubscriptionItem.create_usage_record(
subscription_item_id,
quantity=usage,
timestamp=int(time.time()),
action="set"
)
return {"received": True}