The DNS API allows you to manage DNS records programmatically via HTTP calls. You can use it from scripts, automation tools, or your own applications.
Contact your administrator to get an API key. The key is personal and should be kept secret.
All API calls:
Base URL: https://tools.tornevall.net/api
curl https://tools.tornevall.net/api/dns/zones \
-H "Authorization: Bearer YOUR_API_KEY"
curl https://tools.tornevall.net/api/dns/zones \
-H "X-API-Key: YOUR_API_KEY"
curl https://tools.tornevall.net/api/dns/zones?api_key=YOUR_API_KEY
GET /api/dns/zones
Example:
curl https://tools.tornevall.net/api/dns/zones \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"ok": true,
"count": 5,
"zones": [
{
"zone": "example.com",
"file": "example.com/example.com",
"key": "example.com"
},
{
"zone": "test.se",
"file": "test.se/test.se",
"key": "test.se"
}
],
"is_admin": false,
"access_type": "authenticated"
}
GET /api/dns/zones/{zone}
Example:
curl https://tools.tornevall.net/api/dns/zones/example.com \
-H "Authorization: Bearer YOUR_API_KEY"
Response:
{
"ok": true,
"zone": "example.com",
"method": "AXFR",
"record_count": 12,
"zoneData": [
{
"name": "example.com",
"type": "A",
"rdata": "192.0.2.1",
"ttl": 3600,
"class": "IN"
},
{
"name": "www.example.com",
"type": "A",
"rdata": "192.0.2.1",
"ttl": 3600,
"class": "IN"
}
]
}
POST /api/dns/records/add
Content-Type: application/json
{
"domain": "test.example.com",
"type": "A",
"target": "192.0.2.1",
"ttl": 3600
}
Example:
curl -X POST https://tools.tornevall.net/api/dns/records/add \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "test.example.com",
"type": "A",
"target": "192.0.2.1",
"ttl": 3600
}'
Response (success):
{
"ok": true,
"message": "✓ Update successful (via DnsDirect)",
"domain": "test.example.com",
"type": "A",
"target": "192.0.2.1",
"ttl": 3600
}
Response (error):
{
"ok": false,
"reason": "validation_failed",
"errors": {
"target": ["The target field is required."]
}
}
POST /api/dns/records/delete
Content-Type: application/json
{
"domain": "test.example.com",
"type": "A"
}
Example:
curl -X POST https://tools.tornevall.net/api/dns/records/delete \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "test.example.com",
"type": "A"
}'
Response:
{
"ok": true,
"message": "✓ Update successful (via DnsDirect)",
"domain": "test.example.com",
"type": "A"
}
POST /api/dns/records/update
Content-Type: application/json
{
"domain": "test.example.com",
"type": "A",
"old_target": "192.0.2.1",
"new_target": "192.0.2.100",
"ttl": 3600
}
Example:
curl -X POST https://tools.tornevall.net/api/dns/records/update \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"domain": "test.example.com",
"type": "A",
"old_target": "192.0.2.1",
"new_target": "192.0.2.100",
"ttl": 3600
}'
Add or delete multiple records at once:
POST /api/dns/records/bulk
Content-Type: application/json
{
"operations": [
{
"action": "ADD",
"domain": "test1.example.com",
"type": "A",
"target": "192.0.2.1",
"ttl": 300
},
{
"action": "DELETE",
"domain": "test2.example.com",
"type": "A"
}
]
}
Example:
curl -X POST https://tools.tornevall.net/api/dns/records/bulk \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"operations": [
{"action":"ADD","domain":"test1.example.com","type":"A","target":"192.0.2.1","ttl":300},
{"action":"ADD","domain":"test2.example.com","type":"A","target":"192.0.2.2","ttl":300}
]
}'
{
"domain": "www.example.com",
"type": "A",
"target": "192.0.2.1",
"ttl": 3600
}
{
"domain": "www.example.com",
"type": "AAAA",
"target": "2001:db8::1",
"ttl": 3600
}
{
"domain": "blog.example.com",
"type": "CNAME",
"target": "example.com.",
"ttl": 3600
}
NOTE: Target must end with a period!
{
"domain": "example.com",
"type": "MX",
"target": "10 mail.example.com.",
"ttl": 3600
}
{
"domain": "example.com",
"type": "TXT",
"target": "v=spf1 include:_spf.google.com ~all",
"ttl": 3600
}
{
"domain": "subdomain.example.com",
"type": "NS",
"target": "ns1.provider.com.",
"ttl": 3600
}
#!/bin/bash
API_KEY="your-api-key"
DOMAIN="home.example.com"
CURRENT_IP=$(curl -s ifconfig.me)
# Update A record
curl -X POST https://tools.tornevall.net/api/dns/records/add \
-H "Authorization: Bearer $API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"domain\": \"$DOMAIN\",
\"type\": \"A\",
\"target\": \"$CURRENT_IP\",
\"ttl\": 300
}"
echo "Updated $DOMAIN to $CURRENT_IP"
import requests
API_KEY = "your-api-key"
BASE_URL = "https://tools.tornevall.net/api"
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
# Add record
def add_record(domain, record_type, target, ttl=3600):
data = {
"domain": domain,
"type": record_type,
"target": target,
"ttl": ttl
}
response = requests.post(
f"{BASE_URL}/dns/records/add",
headers=headers,
json=data
)
return response.json()
# Delete record
def delete_record(domain, record_type):
data = {
"domain": domain,
"type": record_type
}
response = requests.post(
f"{BASE_URL}/dns/records/delete",
headers=headers,
json=data
)
return response.json()
# Usage
result = add_record("test.example.com", "A", "192.0.2.1")
print(result)
const API_KEY = 'your-api-key';
const BASE_URL = 'https://tools.tornevall.net/api';
async function addDnsRecord(domain, type, target, ttl = 3600) {
const response = await fetch(`${BASE_URL}/dns/records/add`, {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({ domain, type, target, ttl })
});
return await response.json();
}
// Usage
addDnsRecord('test.example.com', 'A', '192.0.2.1')
.then(result => console.log(result))
.catch(error => console.error(error));
<?php
$apiKey = 'your-api-key';
$baseUrl = 'https://tools.tornevall.net/api';
function addDnsRecord($domain, $type, $target, $ttl = 3600) {
global $apiKey, $baseUrl;
$data = [
'domain' => $domain,
'type' => $type,
'target' => $target,
'ttl' => $ttl
];
$ch = curl_init("$baseUrl/dns/records/add");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"Authorization: Bearer $apiKey",
'Content-Type: application/json'
]);
$response = curl_exec($ch);
curl_close($ch);
return json_decode($response, true);
}
// Usage
$result = addDnsRecord('test.example.com', 'A', '192.0.2.1');
var_dump($result);
{
"ok": false,
"reason": "permission_denied",
"message": "No permission for zone: example.com"
}
Common errors:
unauthenticated: Invalid or missing API keypermission_denied: No access to zonevalidation_failed: Invalid parameterszone_not_found: Zone doesn't existX-RateLimit-Remaining shows remaining callsRetry-After header✅ Do:
❌ Don't:
If API key has leaked:
Version: 1.0
Last updated: 2026-02-16