Webhooks
Receive real-time notifications when events occur in your StyleGrab account.
Endpoints
Register Webhook
Create a new webhook subscription.
POST /api/webhooks
Request Body:
{
"url": "https://yoursite.com/webhooks/stylegrab",
"events": ["extraction.completed", "diff.detected"],
"secret": "your-webhook-secret"
}
| Field | Type | Required | Description |
|---|---|---|---|
url | string | Yes | HTTPS endpoint to receive events |
events | array | Yes | Events to subscribe to |
secret | string | No | Secret for HMAC signature (auto-generated if not provided) |
Response:
{
"id": "wh_abc123",
"url": "https://yoursite.com/webhooks/stylegrab",
"events": ["extraction.completed", "diff.detected"],
"secret": "whsec_abc123...",
"active": true,
"created_at": "2024-01-15T10:30:00Z"
}
⚠️ Important: Store the
secretsecurely. You’ll need it to verify webhook signatures.
List Webhooks
Get all registered webhooks.
GET /api/webhooks
Response:
{
"data": [
{
"id": "wh_abc123",
"url": "https://yoursite.com/webhooks/stylegrab",
"events": ["extraction.completed", "diff.detected"],
"active": true,
"created_at": "2024-01-15T10:30:00Z"
}
]
}
Update Webhook
Modify a webhook subscription.
PUT /api/webhooks/:id
Request Body:
{
"url": "https://newsite.com/webhooks",
"events": ["extraction.completed"],
"active": false
}
Delete Webhook
Remove a webhook subscription.
DELETE /api/webhooks/:id
Events
extraction.completed
Fired when a CSS extraction finishes successfully.
{
"event": "extraction.completed",
"timestamp": "2024-01-15T10:30:02Z",
"data": {
"extraction_id": "ext_abc123",
"url": "https://example.com",
"snapshot_id": "snap_xyz789",
"token_count": {
"colors": 12,
"typography": 3,
"spacing": 8
}
}
}
diff.detected
Fired when changes are detected between snapshots.
{
"event": "diff.detected",
"timestamp": "2024-01-15T10:30:02Z",
"data": {
"extraction_id": "ext_abc123",
"url": "https://example.com",
"from_snapshot": "snap_abc123",
"to_snapshot": "snap_xyz789",
"changes": {
"colors_changed": 3,
"typography_changed": 1,
"spacing_changed": 2,
"total_changes": 6
}
}
}
snapshot.created
Fired when a new snapshot is stored.
{
"event": "snapshot.created",
"timestamp": "2024-01-15T10:30:02Z",
"data": {
"snapshot_id": "snap_xyz789",
"extraction_id": "ext_abc123",
"version": 3
}
}
Signature Verification
All webhook payloads are signed using HMAC-SHA256. Verify the signature to ensure the request came from StyleGrab.
Headers
| Header | Description |
|---|---|
X-StyleGrab-Signature | HMAC-SHA256 signature |
X-StyleGrab-Timestamp | Unix timestamp of the request |
Verification Example (Node.js)
const crypto = require('crypto');
function verifyWebhook(payload, signature, timestamp, secret) {
const signedPayload = `${timestamp}.${payload}`;
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Use timing-safe comparison
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
// Express middleware
app.post('/webhooks/stylegrab', (req, res) => {
const signature = req.headers['x-stylegrab-signature'];
const timestamp = req.headers['x-stylegrab-timestamp'];
if (!verifyWebhook(req.rawBody, signature, timestamp, WEBHOOK_SECRET)) {
return res.status(401).send('Invalid signature');
}
// Process the webhook
const event = req.body;
console.log(`Received ${event.event}`);
res.status(200).send('OK');
});
Verification Example (Python)
import hmac
import hashlib
def verify_webhook(payload: bytes, signature: str, timestamp: str, secret: str) -> bool:
signed_payload = f"{timestamp}.{payload.decode()}"
expected = hmac.new(
secret.encode(),
signed_payload.encode(),
hashlib.sha256
).hexdigest()
return hmac.compare_digest(signature, expected)
Retry Policy
StyleGrab retries failed webhook deliveries with exponential backoff:
| Attempt | Delay |
|---|---|
| 1 | Immediate |
| 2 | 1 minute |
| 3 | 5 minutes |
After 3 failed attempts, the webhook is marked as failed. Fix your endpoint and the next event will attempt delivery again.
Best Practices
- Respond quickly — Return 2xx within 5 seconds
- Process async — Queue the webhook for background processing
- Verify signatures — Always verify the HMAC signature
- Handle duplicates — Webhooks may be delivered more than once
- Use HTTPS — Webhook URLs must use HTTPS