Test Webhook Endpoints
Before relying on webhooks in production, test them to ensure proper configuration and endpoint functionality. DNSRadar provides a testing endpoint that sends a fake event to your webhook.
Testing a Webhook
Send a POST request to /webhooks/{uuid}/test:
curl -X POST https://api.dnsradar.dev/webhooks/wh_abc123/test \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'const response = await fetch('https://api.dnsradar.dev/webhooks/wh_abc123/test', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/webhooks/wh_abc123/test',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/webhooks/wh_abc123/test')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/webhooks/wh_abc123/test", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/webhooks/wh_abc123/test');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/webhooks/wh_abc123/test"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/webhooks/wh_abc123/test",
content
);The API immediately returns HTTP 202 Accepted, and the test payload is sent to your webhook asynchronously.
Test Payload
The test endpoint sends a sample DNS change event:
{
"uuid": "req_test_abc123...",
"webhook_uuid": "wh_test_abc123...",
"created": "2026-01-08T10:35:22Z",
"event": {
"event_uuid": "evt_test_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
}
}
Test Identifiers: Test events use UUIDs prefixed with _test_ to help you distinguish them from real events.
Rate Limits
To prevent abuse, the test endpoint has strict rate limits:
- 5 requests per minute per webhook
- 20 requests per hour per webhook
Rate Limiting: Exceeding these limits returns HTTP 429 Too Many Requests. Space out your tests appropriately.
Response Codes
| Status | Meaning |
|---|---|
| 202 Accepted | Test payload queued for delivery |
| 401 Unauthorized | Invalid API key |
| 404 Not Found | Webhook doesn't exist |
| 429 Too Many Requests | Rate limit exceeded |
Testing Checklist
Before deploying webhooks to production:
- Webhook endpoint is accessible from the internet
- HTTPS is configured properly (valid SSL certificate)
- Authentication headers are validated
- Endpoint returns 2xx status codes for successful processing
- Endpoint responds within 30 seconds
- Error handling is implemented
- Rate limiting won't cause issues
- Payload validation is working
- Test event was received successfully
Common Testing Issues
Endpoint Not Receiving Test Events
Possible causes:
- Firewall blocking requests
- Incorrect URL
- Server not running
- HTTPS certificate issues
Solution:
# Test endpoint accessibility
curl -X POST https://your-endpoint.com/webhooks/dnsradar \
-H "Content-Type: application/json" \
-d '{"test": "data"}'
Endpoint Returns Errors
Check:
- Authentication header validation
- Payload structure expectations
- Server logs for errors
Debug:
app.post('/webhooks/dnsradar', (req, res) => {
// Log everything during debugging
console.log('Headers:', req.headers)
console.log('Body:', req.body)
console.log('Method:', req.method)
// Return detailed error info
try {
processWebhook(req.body)
res.status(200).send('OK')
} catch (error) {
console.error('Error:', error)
res.status(500).json({
error: error.message,
stack: error.stack
})
}
})
Testing Tools
cURL
# Test your endpoint directly
curl -X POST https://your-app.com/webhooks/dnsradar \
-H "X-Webhook-Secret: your-secret" \
-H "Content-Type: application/json" \
-d '{
"event_uuid": "evt_test_manual",
"monitor_uuid": "mon_test_manual",
"domain": "test.com",
"record_type": "A",
"new_state": "MISMATCH",
"occurred": "2026-01-08T12:00:00Z"
}'
Webhook.site
Use webhook.site to inspect webhook payloads:
curl -X POST https://api.dnsradar.dev/webhooks \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
}'const response = await fetch('https://api.dnsradar.dev/webhooks', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/webhooks',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/webhooks')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/webhooks", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/webhooks');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/webhooks"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{
"url": "https://webhook.site/YOUR-UNIQUE-URL",
"method": "POST"
};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/webhooks",
content
);Then test it:
curl -X POST https://api.dnsradar.dev/webhooks/wh_abc123/test \
-H "X-API-Key: YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{}'const response = await fetch('https://api.dnsradar.dev/webhooks/wh_abc123/test', {
method: 'POST',
headers: {
"X-API-Key": "YOUR_API_KEY",
"Content-Type": "application/json"
},
body: JSON.stringify({})
});
const data = await response.json();import requests
response = requests.post(
'https://api.dnsradar.dev/webhooks/wh_abc123/test',
headers={
'X-API-Key': 'YOUR_API_KEY',
'Content-Type': 'application/json'
},
json={}
)require 'net/http'
require 'json'
uri = URI('https://api.dnsradar.dev/webhooks/wh_abc123/test')
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri)
request['X-API-Key'] = 'YOUR_API_KEY'
request['Content-Type'] = 'application/json'
request.body = {}.to_json
response = http.request(request)package main
import (
"bytes"
"encoding/json"
"net/http"
)
data := {}
jsonData, _ := json.Marshal(data)
req, _ := http.NewRequest("POST", "https://api.dnsradar.dev/webhooks/wh_abc123/test", bytes.NewBuffer(jsonData))
req.Header.Set("X-API-Key", "YOUR_API_KEY")
req.Header.Set("Content-Type", "application/json")
client := &http.Client{}
response, _ := client.Do(req)<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.dnsradar.dev/webhooks/wh_abc123/test');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
$headers = [
'X-API-Key: YOUR_API_KEY',
'Content-Type: application/json'
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$data = json_encode({});
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($ch);
curl_close($ch);import java.net.http.*;
import java.net.URI;
HttpClient client = HttpClient.newHttpClient();
String json = """{}""";
HttpRequest request = HttpRequest.newBuilder()
.uri(URI.create("https://api.dnsradar.dev/webhooks/wh_abc123/test"))
.header("X-API-Key", "YOUR_API_KEY")
.header("Content-Type", "application/json")
.method("POST", HttpRequest.BodyPublishers.ofString(json))
.build();
HttpResponse<String> response = client.send(request,
HttpResponse.BodyHandlers.ofString());using System.Net.Http;
using System.Text;
using System.Text.Json;
var client = new HttpClient();
client.DefaultRequestHeaders.Add("X-API-Key", "YOUR_API_KEY");
var data = new
{};
var json = JsonSerializer.Serialize(data);
var content = new StringContent(json, Encoding.UTF8, "application/json");
var response = await client.PostAsync(
"https://api.dnsradar.dev/webhooks/wh_abc123/test",
content
);Visit webhook.site to see the payload.
Ngrok
Test local endpoints:
# Expose local server
ngrok http 3000
# Use ngrok URL in webhook
curl -X POST https://api.dnsradar.dev/webhooks \
-H "X-API-Key: $API_KEY" \
-d '{"url": "https://abc123.ngrok.io/webhooks/dnsradar", "method": "POST"}'