Webhooks Guide
Webhooks allow your application to receive real-time notifications when specific events occur in the leasing API. Instead of polling the API for changes, webhooks push event data to your application as events happen, enabling faster response times and more efficient integrations.
This guide covers how webhooks work, how to set them up, what events are available, and how to securely verify webhook requests. Before you begin, make sure you have your API key ready. If you need help with authentication, check out our Authentication guide.
How Webhooks Work
Webhooks allow you to receive real-time notifications when events occur in the Sweet Spot API. Instead of polling the API for changes, we send HTTP POST requests to your registered endpoint whenever a subscribed event happens.
Getting Started
- Create a Webhook: Register a webhook by providing your endpoint URL and selecting which events you want to receive
- Store Your Secret: When you create a webhook, you'll receive a secret key. Save this securely - you'll need it to verify incoming requests
- Receive Events: When subscribed events occur, we'll send HTTP POST requests to your endpoint with event data
- Verify & Process: Always verify the webhook signature before processing events to ensure they're authentic
Note: Your webhook endpoint must respond with a 2xx status code to acknowledge receipt. If your endpoint doesn't respond or returns an error, we'll automatically retry the delivery. Only active webhooks receive events - you can enable or disable webhooks at any time.
Available Events
You can subscribe to various event types to receive notifications about changes in your system. Events are organized by resource type (checkouts, customers, products, leases, payments).
Checkout Events
checkout.created- Fired when a new checkout is createdcheckout.updated- Fired when a checkout is updatedcheckout.completed- Fired when a checkout is completedcheckout.cancelled- Fired when a checkout is cancelled
Customer Events
customer.created- Fired when a new customer is createdcustomer.updated- Fired when customer information is updatedcustomer.credit_check_completed- Fired when a customer credit check completes
Product Events
product.created- Fired when a new product is createdproduct.updated- Fired when product information is updatedproduct.deleted- Fired when a product is deleted
Lease Events
lease.started- Fired when a lease beginslease.ended- Fired when a lease ends
Payment Events
payment.received- Fired when a payment is received
Webhook Payload
When an event occurs, your webhook endpoint receives an HTTP POST request with a JSON payload containing the event data. The payload includes the event type, unique event ID, timestamp, and the event data.
Example Payload
{
"id": "evt_1234567890",
"type": "checkout.created",
"data": {
"id": "chk_123456",
"state": "unpaid",
"productVariantId": "pvar_123456",
"customerId": "cust_123456",
"createdAt": "2024-01-15T10:30:00Z"
},
"createdAt": "2024-01-15T10:30:00Z"
}Note: The payload structure varies by event type. Each event includes an id,type, data object with event-specific information, and a createdAt timestamp.
Security
All webhook requests include security headers for verification. You should always verify the signature of incoming webhook requests to ensure they're coming from the Sweet Spot API and haven't been tampered with.
Webhook Headers
Every webhook request includes the following headers:
X-Webhook-Signature- HMAC-SHA256 signature in formatsha256=hex_signatureX-Webhook-Timestamp- Unix timestamp when the request was signedX-Webhook-Event-Type- The event type that triggered this webhookX-Webhook-Event-ID- Unique identifier for this event occurrence
Signature Verification
The signature is computed as an HMAC-SHA256 hash of the timestamp and request body, using your webhook secret. The format is: HMAC-SHA256(timestamp + "." + body, secret)
To verify a webhook request:
- Extract the
X-Webhook-Signatureheader (remove thesha256=prefix) - Extract the
X-Webhook-Timestampheader - Reconstruct the signed payload:
timestamp + "." + request_body - Compute the expected signature using HMAC-SHA256 with your webhook secret
- Compare the signatures using constant-time comparison to prevent timing attacks
- Optionally check the timestamp to prevent replay attacks (recommended: reject requests older than 5 minutes)
Example: Verify Signature (Node.js)
const crypto = require('crypto');
function verifyWebhookSignature(payload, signature, secret, timestamp) {
// Reconstruct the signed payload
const signedPayload = `${timestamp}.${payload}`;
// Compute the expected signature
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(signedPayload)
.digest('hex');
// Extract the signature from the header (format: sha256=hex_signature)
const receivedSignature = signature.replace('sha256=', '');
// Compare signatures using constant-time comparison
return crypto.timingSafeEqual(
Buffer.from(expectedSignature),
Buffer.from(receivedSignature)
);
}
// Example usage in Express.js
app.post('/webhooks/sweetspot', express.raw({ type: 'application/json' }), (req, res) => {
const signature = req.headers['x-webhook-signature'];
const timestamp = req.headers['x-webhook-timestamp'];
const eventType = req.headers['x-webhook-event-type'];
const eventId = req.headers['x-webhook-event-id'];
const webhookSecret = process.env.WEBHOOK_SECRET;
if (!verifyWebhookSignature(req.body, signature, webhookSecret, timestamp)) {
return res.status(401).send('Invalid signature');
}
// Check timestamp to prevent replay attacks (optional)
const currentTime = Math.floor(Date.now() / 1000);
const requestTime = parseInt(timestamp);
if (Math.abs(currentTime - requestTime) > 300) { // 5 minutes tolerance
return res.status(401).send('Request timestamp too old');
}
const event = JSON.parse(req.body);
// Process the webhook event
console.log('Received event:', eventType, eventId);
res.status(200).send('OK');
});Important: Always verify webhook signatures before processing events. Never trust webhook requests without verification, as they could be spoofed or tampered with. Store your webhook secret securely and never expose it in client-side code.
Best Practices
1. Always Verify Signatures
Never process webhook events without verifying the signature. This ensures the request is authentic and hasn't been tampered with.
2. Respond Quickly
Your webhook endpoint should respond with a 2xx status code as quickly as possible (ideally within 5 seconds). If you need to perform long-running operations, acknowledge the webhook first and process the event asynchronously.
3. Handle Duplicates
Webhooks may be delivered multiple times due to retries. Use the X-Webhook-Event-IDheader to deduplicate events and ensure idempotent processing.
4. Use HTTPS
Always use HTTPS endpoints for webhooks to ensure the payload is encrypted in transit. The API only acceptshttp:// or https:// URLs.
5. Test Your Endpoint
Use the test webhook endpoint to verify your webhook configuration and delivery before relying on it for production events.
6. Monitor Webhook Health
Monitor your webhook endpoint's response times and error rates. Ensure your endpoint is available and responding correctly to avoid missing events.