
# Integrate DNSRadar with N8N

[n8n](https://n8n.io) is an open-source workflow automation tool that connects to hundreds of services. By integrating DNSRadar with n8n, you can automate responses to DNS changes with complex workflows.

## Architecture Overview

The integration works through webhooks:

1. DNSRadar detects a DNS change
2. DNSRadar sends webhook to n8n
3. n8n workflow processes the event
4. n8n triggers downstream actions (notifications, tickets, API calls, etc.)

## Setting Up the Integration

### Step 1: Create an n8n Webhook

In your n8n workflow:

1. Add a **Webhook** node as the trigger
2. Set **HTTP Method** to `POST`
3. Set **Path** to something memorable like `dnsradar-events`
4. Set **Authentication** to `None` (DNSRadar uses HMAC signatures instead)
5. Copy the **Production URL** (e.g., `https://your-n8n.app/webhook/dnsradar-events`)

### Step 2: Create DNSRadar Webhook

Create a webhook in DNSRadar pointing to your n8n workflow:

```
POST https://api.dnsradar.dev/webhooks

url: https://your-n8n.app/webhook/dnsradar-events
  method: POST
  secret: your-secure-webhook-secret
  groups: ["production-dns"]
```

DNSRadar will use the `secret` to sign each request with HMAC SHA256, sending the signature in the `X-DNSRadar-Signature` header along with a `X-Webhook-Timestamp` header to prevent replay attacks.

### Step 3: Test the Integration

Test your webhook to verify n8n receives the payload:

```
POST https://api.dnsradar.dev/webhooks/wh_abc123/test
```

Check n8n to see if the webhook was received and the workflow triggered.

## Understanding the Webhook Payload

DNSRadar sends this payload to n8n:

```json
{
  "uuid": "req_abc123...",
  "webhook_uuid": "wh_abc123...",
  "created": "2026-01-08T10:35:22Z",
  "event": {
    "event_uuid": "evt_xyz789",
    "monitor_uuid": "mon_abc123",
    "domain": "piedpiper.com",
    "subdomain": "www",
    "record_type": "A",
    "expected_value": ["1.2.3.4"],
    "previous_value": ["1.2.3.4"],
    "current_value": ["5.6.7.8"],
    "old_state": "VALID",
    "new_state": "MISMATCH",
    "occurred": "2026-01-08T10:35:22Z",
    "incidence_count": 1
  }
}
```

Access these values in n8n using expressions like `{{ $json.event.domain }}` or `{{ $json.event.new_state }}`.

## Example Workflows

### 1. Slack Notification

**Goal**: Send Slack message when DNS changes

**Workflow**:
1. **Webhook** (Trigger) - Receives DNSRadar event
2. **IF** node - Filter for `MISMATCH` state: `{{ $json.event.new_state === "MISMATCH" }}`
3. **Slack** node - Send message

**Slack message template**:
```
DNS Alert: {{ $json.event.domain }}{{ $json.event.subdomain ? '.' + $json.event.subdomain : '' }}

Record Type: {{ $json.event.record_type }}
Expected: {{ $json.event.expected_value.join(', ') }}
Current: {{ $json.event.current_value.join(', ') }}
State: {{ $json.event.new_state }}

Time: {{ $json.event.occurred }}
```

### 2. Create PagerDuty Incident

**Goal**: Escalate critical DNS mismatches

**Workflow**:
1. **Webhook** (Trigger)
2. **IF** node - Check if critical: `{{ $json.event.new_state === "MISMATCH" && $json.event.domain.includes('api.') }}`
3. **PagerDuty** node - Create incident

**PagerDuty configuration**:
- **Action**: Create Incident
- **Title**: `DNS Mismatch: {{ $json.event.domain }}`
- **Service**: Your on-call service
- **Urgency**: High
- **Body**: Include all event details

### 3. Create Jira Ticket

**Goal**: Track DNS changes as tickets

**Workflow**:
1. **Webhook** (Trigger)
2. **Jira** node - Create issue

**Jira issue**:
```
Summary: DNS Change - {{ $json.event.domain }}
Description:
Domain: {{ $json.event.domain }}{{ $json.event.subdomain ? '.' + $json.event.subdomain : '' }}
Record Type: {{ $json.event.record_type }}
Previous Value: {{ $json.event.previous_value.join(', ') }}
Current Value: {{ $json.event.current_value.join(', ') }}
State Change: {{ $json.event.old_state }} → {{ $json.event.new_state }}
Occurred: {{ $json.event.occurred }}

Event UUID: {{ $json.event_uuid }}
Monitor UUID: {{ $json.monitor_uuid }}

Issue Type: Task
Project: DNS-OPS
Priority: {{ $json.event.new_state === "MISMATCH" ? "High" : "Medium" }}
```

### 4. Email Notification with Details

**Goal**: Send formatted email to team

**Workflow**:
1. **Webhook** (Trigger)
2. **Send Email** node

**Email template**:
```
Subject: DNS Change Alert - {{ $json.event.domain }}

Body:
A DNS change has been detected:

Domain: {{ $json.event.domain }}{{ $json.event.subdomain ? '.' + $json.event.subdomain : '' }}
Record Type: {{ $json.event.record_type }}

Expected Value: {{ $json.event.expected_value.join(', ') }}
Previous Value: {{ $json.event.previous_value.join(', ') }}
Current Value: {{ $json.event.current_value.join(', ') }}

State: {{ $json.event.old_state }} → {{ $json.event.new_state }}
Incident Count: {{ $json.event.incidence_count }}
Occurred: {{ $json.occurred }}

Event ID: {{ $json.event_uuid }}
Monitor ID: {{ $json.monitor_uuid }}
```

### 5. Multi-Channel Alerting

**Goal**: Notify multiple channels based on severity

**Workflow**:
1. **Webhook** (Trigger)
2. **Switch** node - Route by state:
   - `MISMATCH` → Send to PagerDuty + Slack
   - `NOT_FOUND` → Send to Email + Jira
   - `TIMEOUT` → Send to Slack only
   - Default → Log to database


## Advanced Patterns

### Conditional Routing

Route events based on properties:

```javascript
// Switch node expression
{{ $json.event.domain.split('.')[0] }}

// Cases:
// "api" → Critical path (PagerDuty)
// "www" → Standard path (Slack)
// "dev" → Low priority (Email only)
```


## Security Best Practices

### Validate Webhook Signatures

Add a **Code** node after the webhook trigger to verify the HMAC signature:

```javascript
// JavaScript code in n8n Code node
const crypto = require('crypto');

const signature = $input.item.headers['x-dnsradar-signature'];
const timestamp = $input.item.headers['x-webhook-timestamp'];
const secret = 'your-secure-webhook-secret'; // Store in n8n environment variable

// Verify timestamp (prevent replay attacks)
const eventTime = new Date(timestamp);
const now = new Date();
const maxAge = 5 * 60 * 1000; // 5 minutes

if (now - eventTime > maxAge) {
  throw new Error('Webhook request too old');
}

// Verify signature
const body = JSON.stringify($input.item.json);
const expectedSignature = crypto
  .createHmac('sha256', secret)
  .update(body)
  .digest('hex');

if (signature !== expectedSignature) {
  throw new Error('Invalid webhook signature');
}

// Return the event data if validation passes
return $input.item.json;
```


## Troubleshooting

### Webhook Not Triggering

Check:
1. n8n webhook URL is correct in DNSRadar
2. Webhook is active in DNSRadar
3. n8n workflow is activated
4. Webhook secret is configured correctly
5. n8n is accessible from the internet via HTTPS
6. Signature validation (if implemented) is not rejecting requests

### Test in n8n

Use n8n's **Listening** mode:
1. Open workflow
2. Click webhook node
3. Click "Listen for Test Event"
4. Send test from DNSRadar
5. Verify payload appears in n8n


### Debug Payload

Add a **Function** node after webhook:

```javascript
// Log full payload
console.log('DNSRadar event:', $input.all())

// Transform if needed
return $input.all()
```

## Integration Templates

### Copy-Paste Ready Workflow

```json
{
  "nodes": [
    {
      "parameters": {
        "path": "dnsradar-events",
        "responseMode": "responseNode",
        "options": {}
      },
      "name": "DNSRadar Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [250, 300]
    },
    {
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json.event.new_state}}",
              "value2": "MISMATCH"
            }
          ]
        }
      },
      "name": "Filter Mismatches",
      "type": "n8n-nodes-base.if",
      "position": [450, 300]
    },
    {
      "parameters": {
        "message": "DNS Mismatch: {{$json.event.domain}}\nExpected: {{$json.event.expected_value}}\nCurrent: {{$json.event.current_value}}"
      },
      "name": "Send Slack Alert",
      "type": "n8n-nodes-base.slack",
      "position": [650, 300]
    }
  ]
}
```

## Next Steps

- [Configure Webhooks](/docs/configure-webhooks)
- [Test Webhooks](/docs/test-webhooks)
- [View Webhook Request History](/docs/webhook-requests)

## External Resources

- [n8n Documentation](https://docs.n8n.io)
- [n8n Webhook Node](https://docs.n8n.io/integrations/builtin/core-nodes/n8n-nodes-base.webhook/)
- [n8n Community](https://community.n8n.io)
