📘 DNS API User Guide

📘 DNS API User Guide

Overview

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.

Getting Started

Obtain API Key

Contact your administrator to get an API key. The key is personal and should be kept secret.

Basic Usage

All API calls:

  • Use HTTPS (encrypted)

  • Require authentication

  • Return JSON

  • Follow REST principles

Base URL: <https://tools.tornevall.net/api>

Authentication

Bearer Token (recommended)

curl https://tools.tornevall.net/api/dns/zones \ -H "Authorization: Bearer YOUR_API_KEY"

X-API-Key Header

curl https://tools.tornevall.net/api/dns/zones \ -H "X-API-Key: YOUR_API_KEY"

Query Parameter (not recommended)

curl https://tools.tornevall.net/api/dns/zones?api_key=YOUR_API_KEY

Fetch Zones

List all your zones

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

Fetch specific zone

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" } ] }

Manage DNS Records

Add Record

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."] } }

Delete Record

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

Update Record

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

Bulk Operations

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} ] }'

Record Types

A Record (IPv4)

{ "domain": "www.example.com", "type": "A", "target": "192.0.2.1", "ttl": 3600 }

AAAA Record (IPv6)

{ "domain": "www.example.com", "type": "AAAA", "target": "2001:db8::1", "ttl": 3600 }

CNAME Record

{ "domain": "blog.example.com", "type": "CNAME", "target": "example.com.", "ttl": 3600 }

NOTE: Target must end with a period!

MX Record

{ "domain": "example.com", "type": "MX", "target": "10 mail.example.com.", "ttl": 3600 }

TXT Record

{ "domain": "example.com", "type": "TXT", "target": "v=spf1 include:_spf.google.com ~all", "ttl": 3600 }

NS Record

{ "domain": "subdomain.example.com", "type": "NS", "target": "ns1.provider.com.", "ttl": 3600 }

Usage Examples

Bash Script: Update IP on Dynamic IP

#!/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"

Python: Automated DNS Management

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)

Node.js/JavaScript

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

<?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);

Error Handling

HTTP Status Codes

  • 200 OK: Success

  • 400 Bad Request: Invalid parameters

  • 401 Unauthorized: Invalid API key

  • 403 Forbidden: No permission for zone

  • 404 Not Found: Zone not found

  • 429 Too Many Requests: Rate limit reached

  • 500 Internal Server Error: Server error

Error Messages

{ "ok": false, "reason": "permission_denied", "message": "No permission for zone: example.com" }

Common errors:

  • unauthenticated: Invalid or missing API key

  • permission_denied: No access to zone

  • validation_failed: Invalid parameters

  • zone_not_found: Zone doesn't exist

Rate Limiting

  • 300 requests per minute per API key

  • Header X-RateLimit-Remaining shows remaining calls

  • On exceeded: HTTP 429 + Retry-After header

Security

Best Practices

Do:

  • Store API key in environment variables

  • Use HTTPS (always)

  • Implement retry logic with exponential backoff

  • Log API calls in your application

Don't:

  • Commit API key to Git

  • Share API key with others

  • Hardcode API key in source code

  • Expose API key in frontend JavaScript

Revoke Key

If API key has leaked:

  1. Contact administrator immediately

  2. Get key revoked

  3. Get new key

  4. Update all systems using the old key

Support


Version: 1.0
Last updated: 2026-02-16