iloveQR
    Plans and pricesFAQAPI
    Register
    iloveQR

    Create, customize, and track QR codes from one simple workspace.

    • QR Types
    • Dynamic QR
    • Static QR
    • Analytics
    • Templates
    • Bulk Builder
    • Custom Domains
    • API
    • About us
    • Pricing
    • Contact
    • FAQ
    • Help Center
    • Privacy Policy
    • Terms and Conditions
    • Cookies Policy
    • GDPR
    • Report Abuse

    © 2026 iloveQR. All rights reserved.

    API Documentation
    API Docs
    Getting Started
    IntroductionQuick StartAuthentication
    Authentication
    QR Codes
    Bulk Operations
    Analytics
    Webhooks
    SetupEventsSecurity

    Quick Links

    Get API KeyStart Free Trial
    Webhooks

    Webhooks

    Receive real-time notifications when events occur in your organization. Webhooks allow you to build reactive integrations that respond immediately to QR code scans and other events.

    Real-time

    Get notified instantly when events occur, no polling required

    Secure

    HMAC signatures verify that webhooks come from iloveQR

    Reliable

    Automatic retries with exponential backoff for failed deliveries

    Setting Up Webhooks

    Configure webhooks through the dashboard or API to start receiving events.

    1

    Create a webhook endpoint

    Set up an HTTPS endpoint on your server to receive webhook payloads.

    2

    Register the webhook

    Add your endpoint URL and select which events to subscribe to.

    3

    Verify signatures

    Implement signature verification to ensure payloads are authentic.

    Register Webhook
    curl -X POST \
      "https://api.iloveqr.com/api/v1/organizations/org_abc123/webhooks" \
      -H "X-API-Key: YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "https://your-server.com/webhooks/iloveqr",
        "events": ["qr.scanned", "qr.created", "qr.updated"],
        "secret": "your_webhook_secret"
      }'

    Webhook Events

    Subscribe to the events you need. Each event type has a specific payload structure.

    QR Code Events

    qr.createdA new QR code was created
    qr.updatedA QR code was updated
    qr.deletedA QR code was deleted
    qr.scannedA QR code was scanned
    qr.archivedA QR code was archived
    qr.restoredA QR code was restored from archive

    Subscription Events

    subscription.createdA new subscription was created
    subscription.updatedA subscription was updated
    subscription.cancelledA subscription was cancelled
    subscription.payment_succeededA payment was successful
    subscription.payment_failedA payment failed

    Team Events

    member.joinedA member joined the organization
    member.leftA member left the organization
    member.role_changedA member's role was changed

    Webhook Payload

    All webhook payloads follow a consistent structure with event metadata and data.

    Example: qr.scanned Event
    {
      "id": "evt_1a2b3c4d5e6f",
      "event": "qr.scanned",
      "createdAt": "2024-01-15T14:30:00Z",
      "organizationId": "org_abc123",
      "data": {
        "qrCodeId": "qr_xyz789",
        "qrCodeName": "Product Landing Page",
        "shortCode": "xyz789",
        "destinationUrl": "https://example.com/product",
        "scan": {
          "id": "scan_123abc",
          "timestamp": "2024-01-15T14:30:00Z",
          "location": {
            "country": "US",
            "city": "New York",
            "latitude": 40.7128,
            "longitude": -74.0060
          },
          "device": {
            "type": "mobile",
            "os": "iOS",
            "browser": "Safari"
          },
          "isUnique": true
        }
      }
    }
    Example: qr.created Event
    {
      "id": "evt_7g8h9i0j1k2l",
      "event": "qr.created",
      "createdAt": "2024-01-15T10:00:00Z",
      "organizationId": "org_abc123",
      "data": {
        "qrCode": {
          "id": "qr_newcode",
          "type": "URL",
          "name": "New Campaign QR",
          "shortUrl": "https://ilqr.co/newcode",
          "destinationUrl": "https://example.com/campaign",
          "createdBy": "user_abc123"
        }
      }
    }

    Verifying Webhooks

    Always verify webhook signatures to ensure the payload came from iloveQR and wasn't tampered with in transit.

    Signature Header

    Each webhook request includes an X-Webhook-Signature header containing an HMAC-SHA256 signature of the request body.

    Node.js Verification Example
    const crypto = require('crypto');
    
    function verifyWebhookSignature(payload, signature, secret) {
      const expectedSignature = crypto
        .createHmac('sha256', secret)
        .update(payload)
        .digest('hex');
    
      return crypto.timingSafeEqual(
        Buffer.from(signature),
        Buffer.from(expectedSignature)
      );
    }
    
    // In your webhook handler
    app.post('/webhooks/iloveqr', (req, res) => {
      const signature = req.headers['x-webhook-signature'];
      const payload = JSON.stringify(req.body);
    
      if (!verifyWebhookSignature(payload, signature, WEBHOOK_SECRET)) {
        return res.status(401).send('Invalid signature');
      }
    
      // Process the webhook
      const event = req.body;
      console.log('Received event:', event.event);
    
      res.status(200).send('OK');
    });
    Python Verification Example
    import hmac
    import hashlib
    
    def verify_webhook_signature(payload: bytes, signature: str, secret: str) -> bool:
        expected = hmac.new(
            secret.encode(),
            payload,
            hashlib.sha256
        ).hexdigest()
        return hmac.compare_digest(signature, expected)
    
    # In your Flask handler
    @app.route('/webhooks/iloveqr', methods=['POST'])
    def handle_webhook():
        signature = request.headers.get('X-Webhook-Signature')
        payload = request.get_data()
    
        if not verify_webhook_signature(payload, signature, WEBHOOK_SECRET):
            return 'Invalid signature', 401
    
        event = request.get_json()
        print(f"Received event: {event['event']}")
    
        return 'OK', 200

    Best Practices

    Respond quickly

    Return a 2xx response within 5 seconds. Process webhooks asynchronously if your handling takes longer.

    Handle duplicates

    Store the event ID and check for duplicates. Webhooks may be delivered more than once in rare cases.

    Use HTTPS

    Always use HTTPS endpoints. We don't deliver webhooks to HTTP URLs.

    Monitor failures

    Set up monitoring for webhook delivery failures. Check the webhook logs in the dashboard for debugging.

    Retry Policy

    If your endpoint returns an error or doesn't respond, we automatically retry delivery with exponential backoff:

    AttemptDelay
    1st retry1 minute
    2nd retry5 minutes
    3rd retry30 minutes
    4th retry2 hours
    5th retry (final)24 hours

    Note: After 5 failed attempts, the webhook is marked as failed and we stop retrying. You'll receive an email notification about the failure.

    Next Steps

    Ready to get started? Explore more resources: