← Back to docs

dns-api-guide

Language: EN | EN | SV

📘 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:

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

Error Messages

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

Common errors:

Rate Limiting

Security

Best Practices

Do:

Don't:

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