Building a reliable calendar synchronization layer is deceptive. It looks like simple REST API calls until you encounter Google Calendar push notifications firing duplicate events out of order, Microsoft Graph rate-limiting your tenant at 50 requests per second, and network drops during checkout.
The Principle of Idempotency in Booking APIs
In distributed systems, the network is inherently unreliable. When a client application submits a booking request and the connection drops before receiving the HTTP 200 response, the client must safely retry without double-booking or double-charging.
SetSoon requires an Idempotency-Key header on all state-mutating requests (`POST /api/v1/bookings`):
curl -X POST https://api.setsoon.com/api/v1/bookings \
-H "Authorization: Bearer ss_test_xxx" \
-H "Idempotency-Key: 7b84c8a1-5d92-4f77-9ef1-1c50e457f920" \
-H "Content-Type: application/json" \
-d '{
"service_id": "srv_consult_demo",
"customer_id": "cus_928174",
"slot_start": "2026-10-15T14:00:00Z"
}'
When SetSoon receives an idempotent request, it hashes the key alongside the authenticated tenant ID:
- If the key has never been seen, execution proceeds normally, and the final response payload and HTTP status code are cached with a 24-hour TTL.
- If an identical key is received while the first execution is still in-flight, SetSoon returns HTTP 409 Concurrent Lock.
- If an identical key is received after completion, SetSoon serves the cached response without re-executing booking actions or triggering duplicate email notifications.
Verifying Webhook Signatures with HMAC-SHA256
When SetSoon delivers booking lifecycle events (`booking.created`, `booking.rescheduled`, `booking.cancelled`) to your endpoint, your server must verify the payload authenticity before taking action:
const crypto = require('crypto');
function verifySetSoonWebhook(req, secret) {
const signature = req.headers['x-setsoon-signature'];
const timestamp = req.headers['x-setsoon-timestamp'];
const payload = req.rawBody;
// Prevent replay attacks (reject if older than 5 minutes)
if (Math.abs(Date.now() / 1000 - parseInt(timestamp)) > 300) {
throw new Error('Webhook timestamp outside tolerance window');
}
const expectedSignature = crypto
.createHmac('sha256', secret)
.update(`${timestamp}.${payload}`)
.digest('hex');
return crypto.timingSafeEqual(
Buffer.from(signature),
Buffer.from(expectedSignature)
);
}
Exponential Backoff and Dead-Letter Queues
If your endpoint returns an HTTP 5xx error or times out, SetSoon does not simply drop the event. It enters an automated retry cascade using truncated exponential backoff:
Retries are scheduled at 5s, 30s, 5m, 30m, 2h, and 24h. If all 6 attempts fail, the event is moved to a dead-letter queue, accessible for manual replay via the SetSoon Developer Console or via API (`POST /api/v1/developer/deliveries/{id}/retry`).