DNS API Code Examples
Production-ready code examples for integrating with WAYSCloud DNS API.
Python SDK
Complete DNS Client
import requests
from typing import List, Dict, Optional
class WAYSCloudDNS:
"""Complete Python SDK for WAYSCloud DNS API"""
def __init__(self, api_key: str):
self.api_key = api_key
self.base_url = "https://api.wayscloud.services/v1/dns"
self.headers = {
"Authorization": f"Bearer {api_key}",
"Content-Type": "application/json"
}
# Zone Management
def create_zone(self, domain: str, dnssec_enabled: bool = True,
default_ttl: int = 3600) -> Dict:
"""Create a new DNS zone"""
data = {
"domain": domain,
"dnssec_enabled": dnssec_enabled,
"default_ttl": default_ttl
}
response = requests.post(
f"{self.base_url}/zones",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def list_zones(self) -> Dict:
"""List all DNS zones"""
response = requests.get(
f"{self.base_url}/zones",
headers=self.headers
)
response.raise_for_status()
return response.json()
def get_zone(self, zone_id: str) -> Dict:
"""Get zone details"""
response = requests.get(
f"{self.base_url}/zones/{zone_id}",
headers=self.headers
)
response.raise_for_status()
return response.json()
def update_zone(self, zone_id: str, default_ttl: int) -> Dict:
"""Update zone settings"""
data = {"default_ttl": default_ttl}
response = requests.put(
f"{self.base_url}/zones/{zone_id}",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def delete_zone(self, zone_id: str) -> Dict:
"""Delete a DNS zone"""
response = requests.delete(
f"{self.base_url}/zones/{zone_id}",
headers=self.headers
)
response.raise_for_status()
return response.json()
# Record Management
def add_record(self, zone_id: str, record_type: str, name: str,
value: str, ttl: int = 3600, priority: Optional[int] = None) -> Dict:
"""Add a DNS record"""
data = {
"type": record_type,
"name": name,
"value": value,
"ttl": ttl
}
if priority is not None:
data["priority"] = priority
response = requests.post(
f"{self.base_url}/zones/{zone_id}/records",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def list_records(self, zone_id: str, record_type: Optional[str] = None,
name: Optional[str] = None) -> Dict:
"""List all records in a zone"""
params = {}
if record_type:
params['type'] = record_type
if name:
params['name'] = name
response = requests.get(
f"{self.base_url}/zones/{zone_id}/records",
headers=self.headers,
params=params
)
response.raise_for_status()
return response.json()
def get_record(self, zone_id: str, record_id: str) -> Dict:
"""Get a specific record"""
response = requests.get(
f"{self.base_url}/zones/{zone_id}/records/{record_id}",
headers=self.headers
)
response.raise_for_status()
return response.json()
def update_record(self, zone_id: str, record_id: str,
value: Optional[str] = None, ttl: Optional[int] = None,
priority: Optional[int] = None) -> Dict:
"""Update an existing DNS record"""
data = {}
if value is not None:
data["value"] = value
if ttl is not None:
data["ttl"] = ttl
if priority is not None:
data["priority"] = priority
response = requests.put(
f"{self.base_url}/zones/{zone_id}/records/{record_id}",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def delete_record(self, zone_id: str, record_id: str) -> Dict:
"""Delete a DNS record"""
response = requests.delete(
f"{self.base_url}/zones/{zone_id}/records/{record_id}",
headers=self.headers
)
response.raise_for_status()
return response.json()
# Batch Operations
def batch_create_records(self, zone_id: str, records: List[Dict]) -> Dict:
"""Create multiple records at once"""
data = {"records": records}
response = requests.post(
f"{self.base_url}/zones/{zone_id}/records/batch",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def batch_delete_records(self, zone_id: str, record_ids: List[str]) -> Dict:
"""Delete multiple records at once"""
data = {"record_ids": record_ids}
response = requests.delete(
f"{self.base_url}/zones/{zone_id}/records/batch",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
# Zone Import/Export
def import_zone(self, zone_id: str, zone_file: str, replace: bool = False) -> Dict:
"""Import zone from BIND zone file"""
params = {"replace": replace}
response = requests.post(
f"{self.base_url}/zones/{zone_id}/import",
data=zone_file,
headers={**self.headers, "Content-Type": "text/plain"},
params=params
)
response.raise_for_status()
return response.json()
def export_zone(self, zone_id: str) -> str:
"""Export zone to BIND zone file format"""
response = requests.get(
f"{self.base_url}/zones/{zone_id}/export",
headers=self.headers
)
response.raise_for_status()
return response.text
# DNSSEC
def enable_dnssec(self, zone_id: str) -> Dict:
"""Enable DNSSEC for a zone"""
data = {"enabled": True}
response = requests.post(
f"{self.base_url}/zones/{zone_id}/dnssec",
json=data,
headers=self.headers
)
response.raise_for_status()
return response.json()
def get_dnssec(self, zone_id: str) -> Dict:
"""Get DNSSEC configuration and DS records"""
response = requests.get(
f"{self.base_url}/zones/{zone_id}/dnssec",
headers=self.headers
)
response.raise_for_status()
return response.json()
Usage Examples
import os
# Initialize client
api_key = os.getenv('WAYSCLOUD_DNS_API_KEY')
dns = WAYSCloudDNS(api_key)
# Create zone
zone = dns.create_zone("example.com", dnssec_enabled=True)
print(f"Zone created: {zone['zone_id']}")
print(f"Nameservers: {', '.join(zone['nameservers'])}")
# Add A record
record = dns.add_record(
zone_id=zone['zone_id'],
record_type="A",
name="www",
value="192.0.2.1",
ttl=3600
)
print(f"A record created: {record['record_id']}")
# Add MX record
mx_record = dns.add_record(
zone_id=zone['zone_id'],
record_type="MX",
name="@",
value="mail.example.com",
priority=10
)
print(f"MX record created: {mx_record['record_id']}")
# Add multiple records at once
records = [
{"type": "A", "name": "blog", "value": "192.0.2.2", "ttl": 3600},
{"type": "A", "name": "api", "value": "192.0.2.3", "ttl": 3600},
{"type": "TXT", "name": "@", "value": "v=spf1 include:_spf.google.com ~all"}
]
result = dns.batch_create_records(zone['zone_id'], records)
print(f"Created {result['created_count']} records")
# List all A records
a_records = dns.list_records(zone['zone_id'], record_type='A')
for rec in a_records['records']:
print(f"{rec['type']} {rec['name']} -> {rec['value']}")
# Update record
dns.update_record(
zone_id=zone['zone_id'],
record_id=record['record_id'],
value="192.0.2.100",
ttl=300
)
print("Record updated")
# Get DNSSEC DS records
dnssec = dns.get_dnssec(zone['zone_id'])
print("DS Records:")
for ds in dnssec['ds_records']:
print(f" Key Tag: {ds['key_tag']}")
print(f" Algorithm: {ds['algorithm']}")
print(f" Digest: {ds['digest']}")
# Export zone
zone_file = dns.export_zone(zone['zone_id'])
with open('zone-backup.txt', 'w') as f:
f.write(zone_file)
print("Zone exported to zone-backup.txt")
Node.js SDK
Complete DNS Client
const axios = require('axios');
class WAYSCloudDNS {
/**
* Complete Node.js SDK for WAYSCloud DNS API
*/
constructor(apiKey) {
this.apiKey = apiKey;
this.baseURL = 'https://api.wayscloud.services/v1/dns';
this.headers = {
'Authorization': `Bearer ${apiKey}`,
'Content-Type': 'application/json'
};
}
// Zone Management
async createZone(domain, dnssecEnabled = true, defaultTTL = 3600) {
const response = await axios.post(`${this.baseURL}/zones`, {
domain,
dnssec_enabled: dnssecEnabled,
default_ttl: defaultTTL
}, { headers: this.headers });
return response.data;
}
async listZones() {
const response = await axios.get(`${this.baseURL}/zones`, {
headers: this.headers
});
return response.data;
}
async getZone(zoneId) {
const response = await axios.get(`${this.baseURL}/zones/${zoneId}`, {
headers: this.headers
});
return response.data;
}
async updateZone(zoneId, defaultTTL) {
const response = await axios.put(`${this.baseURL}/zones/${zoneId}`, {
default_ttl: defaultTTL
}, { headers: this.headers });
return response.data;
}
async deleteZone(zoneId) {
const response = await axios.delete(`${this.baseURL}/zones/${zoneId}`, {
headers: this.headers
});
return response.data;
}
// Record Management
async addRecord(zoneId, type, name, value, ttl = 3600, priority = null) {
const data = { type, name, value, ttl };
if (priority !== null) {
data.priority = priority;
}
const response = await axios.post(
`${this.baseURL}/zones/${zoneId}/records`,
data,
{ headers: this.headers }
);
return response.data;
}
async listRecords(zoneId, type = null, name = null) {
const params = {};
if (type) params.type = type;
if (name) params.name = name;
const response = await axios.get(
`${this.baseURL}/zones/${zoneId}/records`,
{ headers: this.headers, params }
);
return response.data;
}
async getRecord(zoneId, recordId) {
const response = await axios.get(
`${this.baseURL}/zones/${zoneId}/records/${recordId}`,
{ headers: this.headers }
);
return response.data;
}
async updateRecord(zoneId, recordId, updates) {
const response = await axios.put(
`${this.baseURL}/zones/${zoneId}/records/${recordId}`,
updates,
{ headers: this.headers }
);
return response.data;
}
async deleteRecord(zoneId, recordId) {
const response = await axios.delete(
`${this.baseURL}/zones/${zoneId}/records/${recordId}`,
{ headers: this.headers }
);
return response.data;
}
// Batch Operations
async batchCreateRecords(zoneId, records) {
const response = await axios.post(
`${this.baseURL}/zones/${zoneId}/records/batch`,
{ records },
{ headers: this.headers }
);
return response.data;
}
async batchDeleteRecords(zoneId, recordIds) {
const response = await axios.delete(
`${this.baseURL}/zones/${zoneId}/records/batch`,
{ data: { record_ids: recordIds }, headers: this.headers }
);
return response.data;
}
// Zone Import/Export
async importZone(zoneId, zoneFile, replace = false) {
const response = await axios.post(
`${this.baseURL}/zones/${zoneId}/import`,
zoneFile,
{
headers: { ...this.headers, 'Content-Type': 'text/plain' },
params: { replace }
}
);
return response.data;
}
async exportZone(zoneId) {
const response = await axios.get(
`${this.baseURL}/zones/${zoneId}/export`,
{ headers: this.headers }
);
return response.data;
}
// DNSSEC
async enableDNSSEC(zoneId) {
const response = await axios.post(
`${this.baseURL}/zones/${zoneId}/dnssec`,
{ enabled: true },
{ headers: this.headers }
);
return response.data;
}
async getDNSSEC(zoneId) {
const response = await axios.get(
`${this.baseURL}/zones/${zoneId}/dnssec`,
{ headers: this.headers }
);
return response.data;
}
}
module.exports = WAYSCloudDNS;
Usage Examples
const WAYSCloudDNS = require('./wayscloud-dns');
async function main() {
// Initialize client
const apiKey = process.env.WAYSCLOUD_DNS_API_KEY;
const dns = new WAYSCloudDNS(apiKey);
// Create zone
const zone = await dns.createZone('example.com', true, 3600);
console.log(`Zone created: ${zone.zone_id}`);
console.log(`Nameservers: ${zone.nameservers.join(', ')}`);
// Add A record
const record = await dns.addRecord(zone.zone_id, 'A', 'www', '192.0.2.1');
console.log(`A record created: ${record.record_id}`);
// Add MX record
const mxRecord = await dns.addRecord(
zone.zone_id, 'MX', '@', 'mail.example.com', 3600, 10
);
console.log(`MX record created: ${mxRecord.record_id}`);
// Add multiple records at once
const records = [
{ type: 'A', name: 'blog', value: '192.0.2.2', ttl: 3600 },
{ type: 'A', name: 'api', value: '192.0.2.3', ttl: 3600 },
{ type: 'TXT', name: '@', value: 'v=spf1 include:_spf.google.com ~all' }
];
const result = await dns.batchCreateRecords(zone.zone_id, records);
console.log(`Created ${result.created_count} records`);
// List all A records
const aRecords = await dns.listRecords(zone.zone_id, 'A');
aRecords.records.forEach(rec => {
console.log(`${rec.type} ${rec.name} -> ${rec.value}`);
});
// Update record
await dns.updateRecord(zone.zone_id, record.record_id, {
value: '192.0.2.100',
ttl: 300
});
console.log('Record updated');
// Get DNSSEC DS records
const dnssec = await dns.getDNSSEC(zone.zone_id);
console.log('DS Records:');
dnssec.ds_records.forEach(ds => {
console.log(` Key Tag: ${ds.key_tag}`);
console.log(` Algorithm: ${ds.algorithm}`);
console.log(` Digest: ${ds.digest}`);
});
// Export zone
const zoneFile = await dns.exportZone(zone.zone_id);
const fs = require('fs');
fs.writeFileSync('zone-backup.txt', zoneFile);
console.log('Zone exported to zone-backup.txt');
}
main().catch(console.error);
Error Handling
Python
import requests
from requests.exceptions import HTTPError, RequestException
def safe_dns_operation(func):
"""Decorator for handling DNS API errors"""
def wrapper(*args, **kwargs):
try:
return func(*args, **kwargs)
except HTTPError as e:
if e.response.status_code == 429:
print("Rate limit exceeded. Retry after 60 seconds.")
elif e.response.status_code == 404:
print("Resource not found.")
else:
error_data = e.response.json()
print(f"Error: {error_data.get('error', {}).get('message', 'Unknown error')}")
raise
except RequestException as e:
print(f"Request failed: {e}")
raise
return wrapper
@safe_dns_operation
def create_record_safely(dns, zone_id, *args, **kwargs):
return dns.add_record(zone_id, *args, **kwargs)
JavaScript
async function safeDNSOperation(func) {
try {
return await func();
} catch (error) {
if (error.response) {
const status = error.response.status;
if (status === 429) {
console.error('Rate limit exceeded. Retry after 60 seconds.');
} else if (status === 404) {
console.error('Resource not found.');
} else {
const errorData = error.response.data;
console.error(`Error: ${errorData.error?.message || 'Unknown error'}`);
}
} else {
console.error(`Request failed: ${error.message}`);
}
throw error;
}
}
// Usage
await safeDNSOperation(async () => {
return await dns.addRecord(zoneId, 'A', 'www', '192.0.2.1');
});
Next Steps
- Record Types - Complete record type reference
- Advanced Use Cases - Production patterns
- Bulk Operations - Batch operations