
# Integrate DNSRadar with Zapier

[Zapier](https://zapier.com) is a workflow automation platform that connects to thousands of apps. By integrating DNSRadar with Zapier, you can automate responses to DNS changes with powerful multi-step workflows called "Zaps".

## Architecture Overview

The integration works through webhooks:

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

## Setting Up the Integration

### Step 1: Create a Zapier Webhook

In your Zapier account:

1. Create a new Zap
2. Search for and select **Webhooks by Zapier** as the trigger app
3. Choose **Catch Hook** as the trigger event
4. Click Continue
5. Copy the **Custom Webhook URL** (e.g., `https://hooks.zapier.com/hooks/catch/123456/abcdef/`)
6. Leave the Zapier editor open to test the webhook

### Step 2: Create DNSRadar Webhook

Create a webhook in DNSRadar pointing to your Zapier webhook:

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

url: https://hooks.zapier.com/hooks/catch/123456/abcdef/
  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 send a sample payload to Zapier:

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

Return to Zapier and click **Test trigger** to see if the webhook was received. You should see the sample data appear in Zapier.

## Understanding the Webhook Payload

DNSRadar sends this payload to Zapier:

```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
  }
}
```

### Payload Structure

| Field | Description |
|-------|-------------|
| `uuid` | Unique webhook request identifier |
| `webhook_uuid` | The webhook that sent this request |
| `created` | When the webhook request was created (ISO 8601) |
| `event` | The DNS change event details (nested object) |

### Event Object Fields

All DNS change data is nested within the `event` object:

| Field | Description |
|-------|-------------|
| `event_uuid` | Unique event identifier |
| `monitor_uuid` | Monitor that detected the change |
| `domain` | Domain name (e.g., "piedpiper.com") |
| `subdomain` | Subdomain (e.g., "www") |
| `record_type` | DNS record type (A, AAAA, CNAME, MX, TXT, SPF, DMARC) |
| `expected_value` | Expected DNS values (array) |
| `previous_value` | Previous DNS values (array) |
| `current_value` | Current DNS values (array) |
| `old_state` | Previous monitor state |
| `new_state` | Current monitor state |
| `occurred` | When the DNS change occurred (ISO 8601) |
| `incidence_count` | Total incident count for this monitor |

Access these values in Zapier using the field picker. For nested event fields, use `Event` prefix in Zapier (e.g., `Event Domain`, `Event New State`).

## Example Zaps

### 1. Slack Notification

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

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Slack - Send Channel Message

**Slack message configuration**:
- **Channel**: #dns-alerts
- **Message Text**:
```
DNS Alert: {{event__domain}}.{{event__subdomain}}

Record Type: {{event__record_type}}
Expected: {{event__expected_value}}
Current: {{event__current_value}}
State: {{event__new_state}}

Time: {{event__occurred}}
Event ID: {{event__event_uuid}}
Request ID: {{uuid}}
```

**Optional**: Add a **Filter** step between trigger and action:
- **Field**: Event New State
- **Condition**: Exactly matches
- **Value**: `MISMATCH`

### 2. Gmail Email Notification

**Goal**: Send email alerts for DNS changes

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Gmail - Send Email

**Email configuration**:
- **To**: ops-team@company.com
- **Subject**: `DNS Change Alert - {{event__domain}}`
- **Body**:
```
A DNS change has been detected:

Domain: {{event__domain}}.{{event__subdomain}}
Record Type: {{event__record_type}}

Expected Value: {{event__expected_value}}
Previous Value: {{event__previous_value}}
Current Value: {{event__current_value}}

State: {{event__old_state}} → {{event__new_state}}
Incident Count: {{event__incidence_count}}
Occurred: {{event__occurred}}

Event ID: {{event__event_uuid}}
Monitor ID: {{event__monitor_uuid}}
Request ID: {{uuid}}
```

### 3. Google Sheets Logging

**Goal**: Track all DNS changes in a spreadsheet

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Google Sheets - Create Spreadsheet Row

**Spreadsheet columns**:
- Request UUID: `{{uuid}}`
- Webhook UUID: `{{webhook_uuid}}`
- Created: `{{created}}`
- Event UUID: `{{event__event_uuid}}`
- Monitor UUID: `{{event__monitor_uuid}}`
- Domain: `{{event__domain}}`
- Subdomain: `{{event__subdomain}}`
- Record Type: `{{event__record_type}}`
- Expected Value: `{{event__expected_value}}`
- Current Value: `{{event__current_value}}`
- Old State: `{{event__old_state}}`
- New State: `{{event__new_state}}`
- Occurred: `{{event__occurred}}`
- Incident Count: `{{event__incidence_count}}`

### 4. Jira Ticket Creation

**Goal**: Create Jira tickets for DNS changes

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Filter**: Only continue if Event New State is `MISMATCH`
3. **Action**: Jira - Create Issue

**Jira issue configuration**:
- **Project**: DNS-OPS
- **Issue Type**: Task
- **Summary**: `DNS Change - {{event__domain}}.{{event__subdomain}}`
- **Description**:
```
Domain: {{event__domain}}.{{event__subdomain}}
Record Type: {{event__record_type}}

Previous Value: {{event__previous_value}}
Current Value: {{event__current_value}}

State Change: {{event__old_state}} → {{event__new_state}}
Occurred: {{event__occurred}}

Event UUID: {{event__event_uuid}}
Monitor UUID: {{event__monitor_uuid}}
Request ID: {{uuid}}
```
- **Priority**: High (for `MISMATCH`)

### 5. PagerDuty Incident

**Goal**: Create PagerDuty incidents for critical DNS issues

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Filter**: Only continue if Event New State is `MISMATCH`
3. **Action**: PagerDuty - Create Incident

**PagerDuty configuration**:
- **Service**: Your DNS on-call service
- **Title**: `DNS Mismatch: {{event__domain}}.{{event__subdomain}}`
- **Urgency**: High
- **Body**:
```
Domain: {{event__domain}}.{{event__subdomain}}
Record Type: {{event__record_type}}
Expected: {{event__expected_value}}
Current: {{event__current_value}}
State: {{event__new_state}}
Event: {{event__event_uuid}}
Request: {{uuid}}
```

### 6. Microsoft Teams Notification

**Goal**: Alert team in Microsoft Teams

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Microsoft Teams - Send Channel Message

**Teams message**:
- **Team**: Operations
- **Channel**: DNS Monitoring
- **Message**:
```
**DNS Alert Detected**

**Domain**: {{event__domain}}.{{event__subdomain}}
**Record Type**: {{event__record_type}}
**State**: {{event__old_state}} → {{event__new_state}}

**Expected**: {{event__expected_value}}
**Current**: {{event__current_value}}

**Time**: {{event__occurred}}
**Event ID**: {{event__event_uuid}}
**Request ID**: {{uuid}}
```

### 7. Trello Card Creation

**Goal**: Track DNS changes as Trello cards

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Trello - Create Card

**Trello card configuration**:
- **Board**: DNS Operations
- **List**: New Alerts
- **Card Name**: `DNS Change - {{event__domain}}.{{event__subdomain}}`
- **Description**:
```
Record Type: {{event__record_type}}
State: {{event__old_state}} → {{event__new_state}}

Expected: {{event__expected_value}}
Current: {{event__current_value}}

Occurred: {{event__occurred}}
Event: {{event__event_uuid}}
Request: {{uuid}}
```
- **Labels**: Based on Event New State (use Formatter to map states to label names)

### 8. Discord Notification

**Goal**: Send alerts to Discord server

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Action**: Discord - Send Channel Message

**Discord message**:
- **Channel**: dns-alerts
- **Message Text**:
```
:warning: **DNS Change Detected**

**Domain**: {{event__domain}}.{{event__subdomain}}
**Type**: {{event__record_type}}
**Status**: {{event__new_state}}

**Expected**: `{{event__expected_value}}`
**Current**: `{{event__current_value}}`

**Time**: {{event__occurred}}
**Event ID**: {{event__event_uuid}}
```

## Advanced Patterns

### Multi-Path Workflows

Route events based on severity using Paths:

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Paths by Zapier**:
   - **Path A** (Critical): Event New State = `MISMATCH`
     - Send to PagerDuty
     - Send to Slack
   - **Path B** (Warning): Event New State = `NOT_FOUND`
     - Send to Email
     - Create Jira ticket
   - **Path C** (Info): Event New State = `TIMEOUT`
     - Log to Google Sheets

### Adding Context with Formatter

Transform data before sending:

**Example**: Format domain display name
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Formatter by Zapier**: Text - Replace
   - **Input**: `{{event__domain}}.{{event__subdomain}}`
   - **Find**: Empty subdomain text
   - **Replace**: Clean format
3. **Action**: Send notification with formatted domain

**Example**: Create custom message based on state
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Formatter by Zapier**: Utilities - Lookup Table
   - **Lookup Value**: `{{event__new_state}}`
   - **Lookup Table**:
     - `MISMATCH` → Critical DNS mismatch detected
     - `NOT_FOUND` → DNS record not found
     - `TIMEOUT` → DNS query timeout
     - `VALID` → DNS record restored to valid state
3. **Action**: Use formatted message

### Combining Multiple Actions

Send to multiple channels for critical events:

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Filter**: Event New State = `MISMATCH`
3. **Action 1**: Slack - Send message
4. **Action 2**: PagerDuty - Create incident
5. **Action 3**: Gmail - Send email
6. **Action 4**: Google Sheets - Log event

### Delay and Digest Pattern

Batch alerts to prevent notification fatigue:

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Append Entry and Schedule Digest by Zapier**:
   - **Digest Key**: dns-alerts-hourly
   - **Schedule**: Every 1 hour
3. When digest fires, send summary to Slack with all events

### Using Storage for Deduplication

Track recent alerts to avoid duplicates:

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Storage by Zapier**: Get Value
   - **Key**: `alert-{{event__monitor_uuid}}`
3. **Filter**: Only continue if storage value is empty or old
4. **Action**: Send alert
5. **Storage by Zapier**: Set Value
   - **Key**: `alert-{{event__monitor_uuid}}`
   - **Value**: `{{event__occurred}}`

## Webhook Security and Validation

### Understanding DNSRadar Webhook Signatures

DNSRadar signs webhook requests using HMAC SHA256 for security:

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

url: https://hooks.zapier.com/hooks/catch/123456/abcdef/
  method: POST
  secret: your-secure-webhook-secret
  groups: ["production-dns"]
```

DNSRadar includes these security headers:
- `X-DNSRadar-Signature`: HMAC SHA256 signature of the request body
- `X-Webhook-Timestamp`: UTC timestamp to prevent replay attacks

### Validating Signatures in Zapier

Use **Code by Zapier** to verify the webhook signature:

**Zap Setup**:
1. **Trigger**: Webhooks by Zapier - Catch Hook
2. **Code by Zapier**: Run Python

```python
import hmac
import hashlib
import json
from datetime import datetime, timezone

# Get headers and body
signature = input_data.get('headers', {}).get('X-Dnsradar-Signature', '')
timestamp = input_data.get('headers', {}).get('X-Webhook-Timestamp', '')
secret = 'your-secure-webhook-secret'

# Verify timestamp (prevent replay attacks - within 5 minutes)
try:
    event_time = datetime.fromisoformat(timestamp.replace('Z', '+00:00'))
    now = datetime.now(timezone.utc)

    if (now - event_time).total_seconds() > 300:
        raise Exception('Webhook request too old')
except:
    raise Exception('Invalid timestamp')

# Verify signature
body = json.dumps(input_data).encode('utf-8')
expected_signature = hmac.new(
    secret.encode('utf-8'),
    body,
    hashlib.sha256
).hexdigest()

if not hmac.compare_digest(signature, expected_signature):
    raise Exception('Invalid webhook signature')

# Return data if validation passes
return input_data
```

3. Continue with actions

### Optional: Custom Headers

You can still add custom headers for additional authentication layers:

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

url: https://hooks.zapier.com/hooks/catch/123456/abcdef/
  method: POST
  secret: your-secure-webhook-secret
  headers:
    X-DNSRadar-Source: production
  groups: ["production-dns"]
```

## Working with Arrays

DNSRadar sends `expected_value`, `previous_value`, and `current_value` as arrays within the event object. Handle them in Zapier:

### Display Array Values

Use Formatter to join arrays:

1. **Formatter by Zapier**: Text - Join
   - **Input**: `{{event__expected_value}}`
   - **Separator**: `, `
   - **Output**: Use in subsequent steps

### Compare Array Values

Use Code by Zapier for complex comparisons:

```python
event = input_data.get('event', {})
expected = event.get('expected_value', [])
current = event.get('current_value', [])

if set(expected) == set(current):
    result = "Match"
else:
    result = "Mismatch"

return {'comparison': result, 'details': f"Expected: {expected}, Got: {current}"}
```

## Troubleshooting

### Webhook Not Triggering

Check these items:
1. Zapier webhook URL is correct in DNSRadar
2. Webhook is enabled in DNSRadar
3. Zap is turned ON (not paused)
4. Check Zapier's Zap History for errors

### Test Your Webhook

From DNSRadar, send a test event:

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

Check Zapier's Zap History to see if it was received.

### Missing Data in Zapier

If fields aren't appearing:
1. Send a test webhook from DNSRadar
2. In Zapier, click "Retest trigger" to refresh sample data
3. Verify the field names match the webhook payload
4. Check if the field contains data in the sample

### Zap Not Continuing

Common causes:
1. **Filter blocking execution**: Check filter conditions
2. **Required field empty**: Ensure all required action fields have data
3. **Authentication failed**: Reconnect the app account
4. **Rate limits**: Check if you've hit API rate limits

### View Zap History

Check execution logs:
1. Open your Zap
2. Click "Zap History" tab
3. Review recent runs for errors
4. Click individual runs to see detailed logs

### Debug with Formatter

Add a Formatter step to inspect data:

1. **Formatter by Zapier**: Utilities - Line Item to Text
   - **Input**: All webhook data
2. **Email by Zapier**: Send yourself the formatted output
3. Review what data is actually being received

## Best Practices

### Security

Implement webhook signature validation:
1. Always provide a `secret` when creating webhooks
2. Add signature validation using Code by Zapier
3. Verify timestamps to prevent replay attacks
4. Store webhook secrets in environment variables or secure storage

### Error Handling

Set up error notifications:
1. In Zap settings, enable "Send Zap error emails"
2. Create a separate error-handling Zap
3. Use try-catch in Code steps

### Testing

Before going live:
1. Test with DNSRadar webhook test endpoint
2. Verify all actions complete successfully
3. Check that notifications arrive correctly
4. Validate formatting and data accuracy

### Performance

Optimize your Zaps:
1. Use Filters early to avoid unnecessary actions
2. Consider digest patterns for high-volume events
3. Use multi-step Zaps instead of multiple single-step Zaps
4. Monitor task usage to stay within plan limits


## Next Steps

- [Configure Webhooks](/docs/configure-webhooks)
- [Test Webhooks](/docs/test-webhooks)
- [View Webhook Request History](/docs/webhook-requests)
- [N8n Integration](/docs/n8n-integration) (alternative automation platform)

## External Resources

- [Zapier Documentation](https://zapier.com/help)
- [Webhooks by Zapier](https://zapier.com/apps/webhook/integrations)
- [Zapier Community](https://community.zapier.com)
- [Zapier Templates](https://zapier.com/apps/webhooks/integrations)
