Webhooks

Webhooks allow you to receive real-time notifications when events occur in MediLoop. Instead of polling the API, webhooks push data to your server as events happen.

Setting Up Webhooks

  1. Go to the Developer Portal
  2. Navigate to Webhooks settings
  3. Add your endpoint URL (must be HTTPS)
  4. Select the events you want to receive
  5. Copy your webhook signing secret

Webhook Payload

All webhook payloads follow this structure:

Webhook Payload Structure
json
{
  "id": "evt_1234567890",
  "event": "notification.delivered",
  "timestamp": "2024-01-15T10:00:05Z",
  "api_version": "2024-01-01",
  "data": {
    "notification_id": "notif-550e8400-e29b-41d4",
    "notification_number": "NOTIF-20240115-0001",
    "channel": "SMS",
    "status": "DELIVERED",
    "delivered_at": "2024-01-15T10:00:05Z"
  }
}

Available Events

EventDescription
notification.sentNotification sent to delivery provider
notification.deliveredNotification confirmed delivered
notification.failedNotification delivery failed
notification.bouncedEmail bounced
appointment.createdNew appointment booked
appointment.cancelledAppointment cancelled
appointment.rescheduledAppointment rescheduled
appointment.checked_inPatient checked in
lab.result_readyLab results available
lab.critical_valueCritical lab value detected
delivery.status_changedDelivery status updated

Verifying Webhook Signatures

All webhooks include a signature header to verify authenticity. Always verify signatures before processing webhook data.

Signature Verification (Python)
python
import hmac
import hashlib

def verify_webhook(payload: str, signature: str, secret: str) -> bool:
    """Verify webhook signature."""
    expected = hmac.new(
        secret.encode(),
        payload.encode(),
        hashlib.sha256
    ).hexdigest()
    
    return hmac.compare_digest(f"sha256={expected}", signature)

# In your webhook handler
@app.post("/webhooks/mediloop")
def handle_webhook(request):
    signature = request.headers.get("X-MediLoop-Signature")
    payload = request.body.decode()
    
    if not verify_webhook(payload, signature, WEBHOOK_SECRET):
        return Response(status=401)
    
    # Process the webhook
    data = json.loads(payload)
    handle_event(data["event"], data["data"])
    
    return Response(status=200)
Signature Verification (Node.js)
javascript
const crypto = require('crypto');

function verifyWebhook(payload, signature, secret) {
  const expected = crypto
    .createHmac('sha256', secret)
    .update(payload)
    .digest('hex');
  
  return crypto.timingSafeEqual(
    Buffer.from(`sha256=${expected}`),
    Buffer.from(signature)
  );
}

// Express handler
app.post('/webhooks/mediloop', (req, res) => {
  const signature = req.headers['x-mediloop-signature'];
  const payload = JSON.stringify(req.body);
  
  if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
    return res.status(401).send('Invalid signature');
  }
  
  // Process the webhook
  handleEvent(req.body.event, req.body.data);
  
  res.status(200).send('OK');
});

Responding to Webhooks

Your endpoint must respond within 30 seconds with a 2xx status code:

  • 200 OK - Webhook received and processed
  • 202 Accepted - Webhook received, will process asynchronously
  • Any other status code triggers a retry

Retry Policy

If your endpoint fails to respond or returns an error, we retry with exponential backoff:

AttemptDelay
1Immediate
21 minute
35 minutes
430 minutes
52 hours
68 hours

After 6 failed attempts, the webhook is marked as failed and no further retries are attempted.

Best Practices

  • Respond quickly - Return 200 immediately, process asynchronously
  • Handle duplicates - Use the event ID to deduplicate
  • Verify signatures - Always verify before processing
  • Use HTTPS - Webhook URLs must use HTTPS
  • Log events - Keep logs for debugging
  • Handle all events - Gracefully ignore unknown event types

Testing Webhooks

You can test webhooks in the Developer Portal:

  1. Go to Webhooks settings
  2. Click "Send test event"
  3. Select an event type
  4. View the delivery status and response

In sandbox mode, webhooks are delivered immediately after API calls to help with testing.