Real-Time Screenshot Notifications with Webhooks
Instead of polling for results, let SnapSharp push notifications to you. Webhooks fire when screenshots complete, requests fail, or your usage hits a threshold.
What you can subscribe to
| Event | When it fires |
|---|---|
screenshot.completed | Any successful screenshot, OG image, or HTML-to-image request |
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 |
Setting up webhooks
- Go to Dashboard → Settings → Webhooks
- Enter your endpoint URL (must be HTTPS)
- Select which events you want
- Save — copy the webhook secret (shown once)
Building a webhook handler
Here's a minimal Express.js handler that verifies the signature and processes events:
import express from 'express';
import crypto from 'crypto';
const app = express();
app.use(express.raw({ type: 'application/json' }));
const WEBHOOK_SECRET = process.env.SNAPSHARP_WEBHOOK_SECRET!;
app.post('/webhooks/snapsharp', (req, res) => {
const signature = req.headers['x-webhook-signature'] as string;
const expected = 'sha256=' + crypto
.createHmac('sha256', WEBHOOK_SECRET)
.update(req.body)
.digest('hex');
if (!crypto.timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
return res.status(401).send('Invalid signature');
}
const payload = JSON.parse(req.body.toString());
switch (payload.event) {
case 'screenshot.completed':
console.log(`Screenshot done: ${payload.data.url} (${payload.data.response_time_ms}ms)`);
break;
case 'screenshot.failed':
console.error(`Screenshot failed: ${payload.data.url} — ${payload.data.error_message}`);
break;
case 'usage.threshold.80':
console.warn(`Usage at ${payload.data.percentage}% — consider upgrading`);
break;
case 'usage.threshold.100':
console.error('Monthly limit reached!');
break;
}
res.status(200).send('OK');
});Payload structure
Every webhook delivers a JSON payload:
{
"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
}
}Security: always verify signatures
Every webhook request includes an X-Webhook-Signature header with an HMAC-SHA256 hash. Always verify it before processing — this confirms the request came from SnapSharp, not an attacker.
Automatic retries
If your endpoint returns a non-2xx status or doesn't respond within 10 seconds, SnapSharp retries:
- Attempt 1: Immediate
- Attempt 2: After 30 seconds
- Attempt 3: After 5 minutes
- Attempt 4 (final): After 1 hour
After all retries fail, the delivery is marked as failed. Check delivery history in the dashboard.
Use cases
- Slack/Discord notifications — post to a channel when screenshots fail
- Monitoring dashboards — track success rates and response times
- Usage alerts — get warned before hitting your monthly limit
- Pipeline triggers — kick off downstream processing when a screenshot is ready
- Error tracking — log failed screenshots to Sentry or your error tracker
Testing
Use the Test button next to any webhook in the dashboard to send a sample payload and verify your endpoint works.
Full webhook docs: snapsharp.dev/docs/webhooks