Webhooks
Get notified when things happen — screenshots complete, requests fail, or your usage reaches a threshold. SnapSharp sends signed HTTP POST requests to your endpoint.
Manage webhooks in Dashboard → Settings → Webhooks.
Events
| Event | When it fires |
|---|---|
screenshot.completed | A screenshot, OG image, or HTML-to-image request succeeded |
screenshot.failed | A request failed (timeout, unreachable URL, etc.) |
usage.threshold.80 | Monthly usage hit 80% of your plan limit |
usage.threshold.100 | Monthly usage hit 100% — requests will be rejected |
Payload format
All webhook payloads follow this structure:
{
"event": "screenshot.completed",
"timestamp": "2026-03-25T14:30:00.000Z",
"data": {
"request_id": "550e8400-e29b-41d4-a716-446655440000",
"endpoint": "/v1/screenshot",
"url": "https://example.com",
"status_code": 200,
"response_time_ms": 1247,
"cached": false
}
}Event-specific data
screenshot.completed: request_id, endpoint, url, status_code, response_time_ms, cached, format, size_bytes
screenshot.failed: request_id, endpoint, url, status_code, error_message
usage.threshold.80 / usage.threshold.100: current_usage, limit, percentage, plan
Signature verification
Every webhook request includes an HMAC-SHA256 signature to verify authenticity.
Headers
| Header | Value |
|---|---|
Content-Type | application/json |
User-Agent | SnapSharp-Webhook/1.0 |
X-Webhook-Id | Unique delivery ID |
X-Webhook-Signature | sha256=<hex HMAC> |
X-Webhook-Timestamp | ISO 8601 timestamp |
X-Webhook-Attempt | Attempt number (1, 2, or 3) |
Verifying the signature
The signature is computed over the raw request body using your webhook secret:
import crypto from 'crypto';
function verifyWebhook(body: string, signature: string, secret: string): boolean {
const expected = 'sha256=' + crypto
.createHmac('sha256', secret)
.update(body)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expected)
);
}
// In your webhook handler:
const isValid = verifyWebhook(
rawBody,
req.headers['x-webhook-signature'],
'whsec_your_webhook_secret'
);import hmac
import hashlib
def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
expected = "sha256=" + hmac.new(
secret.encode(), body, hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)Always verify the signature before processing the payload. Never trust unverified webhook requests.
Retry policy
If your endpoint returns a non-2xx status code or doesn't respond within 10 seconds, SnapSharp retries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1st | Immediate |
| 2nd | 30 seconds |
| 3rd | 5 minutes |
| 4th (final) | 1 hour |
After 3 failed retries, the delivery is marked as failed. You can see delivery history in the dashboard.
Creating a webhook
Via dashboard
- Go to Settings → Webhooks in your dashboard
- Enter the endpoint URL (must be HTTPS)
- Select the events you want to receive
- Save — your webhook secret is shown once, copy it
Testing
Use the Test button next to any webhook to send a sample payload. This helps verify your endpoint is working before real events fire.
Delivery history
Each webhook shows its recent deliveries with:
- Event type and timestamp
- HTTP status code from your endpoint
- Response body (first 1KB)
- Attempt number
View delivery history in Dashboard → Settings → Webhooks → expand any webhook.
Best practices
- Respond quickly — return a
200within 5 seconds. Process the payload asynchronously if your handler does heavy work. - Handle duplicates — use the
X-Webhook-Idheader to deduplicate. The same event may be delivered more than once during retries. - Verify signatures — always check
X-Webhook-Signatureto confirm the request came from SnapSharp. - Use HTTPS — webhook URLs must use HTTPS. HTTP endpoints are rejected.