Manage DNS with the API
Manage DNS records over the REST API. Every request uses the base URL
https://api.zcp.zsoftly.ca/api and sends a Bearer token in the Authorization header. See
Authentication to create a token.
List Your Zones
Section titled “List Your Zones”curl -s "https://api.zcp.zsoftly.ca/api/dns/domains" \ -H "Authorization: Bearer your-token" \ -H "Accept: application/json" | jq '.data'import requests
BASE = "https://api.zcp.zsoftly.ca/api"TOKEN = "your-token"
resp = requests.get( f"{BASE}/dns/domains", headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},)for zone in resp.json()["data"]: print(zone["slug"], zone["name"], zone["status"])const BASE = 'https://api.zcp.zsoftly.ca/api';const TOKEN = 'your-token';
const res = await fetch(`${BASE}/dns/domains`, { headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },});const { data } = await res.json();for (const zone of data) { console.log(zone.slug, zone.name, zone.status);}package main
import ( "encoding/json" "fmt" "net/http")
func main() { const base = "https://api.zcp.zsoftly.ca/api" const token = "your-token"
req, _ := http.NewRequest("GET", base+"/dns/domains", nil) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close()
var env struct { Data []struct { Slug string `json:"slug"` Name string `json:"name"` Status bool `json:"status"` } `json:"data"` } json.NewDecoder(resp.Body).Decode(&env) for _, zone := range env.Data { fmt.Println(zone.Slug, zone.Name, zone.Status) }}Response:
{ "status": "Success", "message": "OK", "total": 1, "data": [{ "name": "example.com", "slug": "examplecom", "status": true }]}Show a Zone and Its Records
Section titled “Show a Zone and Its Records”Pass the zone slug. The response lists every record, including the SOA and NS records ZCP adds
for you.
curl -s "https://api.zcp.zsoftly.ca/api/dns/domains/examplecom" \ -H "Authorization: Bearer your-token" \ -H "Accept: application/json" | jq '.data.records'import requests
BASE = "https://api.zcp.zsoftly.ca/api"TOKEN = "your-token"
resp = requests.get( f"{BASE}/dns/domains/examplecom", headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},)for rec in resp.json()["data"]["records"]: print(rec["name"], rec["type"], rec["contents"], rec["ttl"])const BASE = 'https://api.zcp.zsoftly.ca/api';const TOKEN = 'your-token';
const res = await fetch(`${BASE}/dns/domains/examplecom`, { headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },});const { data } = await res.json();for (const rec of data.records) { console.log(rec.name, rec.type, rec.contents, rec.ttl);}package main
import ( "encoding/json" "fmt" "net/http")
func main() { const base = "https://api.zcp.zsoftly.ca/api" const token = "your-token"
req, _ := http.NewRequest("GET", base+"/dns/domains/examplecom", nil) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close()
var env struct { Data struct { Records []struct { Name string `json:"name"` Type string `json:"type"` Contents []string `json:"contents"` TTL int `json:"ttl"` } `json:"records"` } `json:"data"` } json.NewDecoder(resp.Body).Decode(&env) for _, rec := range env.Data.Records { fmt.Println(rec.Name, rec.Type, rec.Contents, rec.TTL) }}The API groups records by name and type and returns the values under contents. A name and type
hold several values, so contents carries one entry per value. See
Several values per name and type.
{ "name": "www.example.com.", "type": "A", "ttl": 14400, "contents": ["203.0.113.10"]}Add a Record
Section titled “Add a Record”POST to the zone’s records path. The name field is relative to the zone. Send www, not
www.example.com. Use @ for the zone root.
curl -s -X POST "https://api.zcp.zsoftly.ca/api/dns/domains/examplecom/records" \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "name": "www", "type": "A", "content": "203.0.113.10", "ttl": 14400 }'import requests
BASE = "https://api.zcp.zsoftly.ca/api"TOKEN = "your-token"
record = {"name": "www", "type": "A", "content": "203.0.113.10", "ttl": 14400}
resp = requests.post( f"{BASE}/dns/domains/examplecom/records", headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"}, json=record,)print(resp.json()["message"])const BASE = 'https://api.zcp.zsoftly.ca/api';const TOKEN = 'your-token';
const res = await fetch(`${BASE}/dns/domains/examplecom/records`, { method: 'POST', headers: { Authorization: `Bearer ${TOKEN}`, 'Content-Type': 'application/json', Accept: 'application/json', }, body: JSON.stringify({ name: 'www', type: 'A', content: '203.0.113.10', ttl: 14400 }),});console.log((await res.json()).message);package main
import ( "bytes" "encoding/json" "fmt" "net/http")
func main() { const base = "https://api.zcp.zsoftly.ca/api" const token = "your-token"
body := []byte(`{"name":"www","type":"A","content":"203.0.113.10","ttl":14400}`)
req, _ := http.NewRequest("POST", base+"/dns/domains/examplecom/records", bytes.NewReader(body)) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Content-Type", "application/json") req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close()
var env struct { Message string `json:"message"` } json.NewDecoder(resp.Body).Decode(&env) fmt.Println(env.Message)}Response:
{ "status": "Success", "message": "Domain record created successfully." }There is no update endpoint. To change a record, delete it and create it again with the new value.
MX Records
Section titled “MX Records”An MX record needs a priority field alongside content. Send the mail server in content
and the preference number in priority.
curl -s -X POST "https://api.zcp.zsoftly.ca/api/dns/domains/examplecom/records" \ -H "Authorization: Bearer your-token" \ -H "Content-Type: application/json" \ -H "Accept: application/json" \ -d '{ "name": "@", "type": "MX", "content": "mail.example.com.", "priority": 10, "ttl": 3600 }'The record then resolves as 10 mail.example.com.. Omitting priority on an MX record fails.
Delete a Record
Section titled “Delete a Record”DELETE the zone’s records path with name, type, and content query parameters. Here name
is the fully qualified record name with a trailing dot. content must match one record value
exactly and must be URL encoded.
Each request deletes one value, not the whole record set. Repeat the request for every value you
want to remove. For MX, include the priority and target together in content, for example
0 mail.example.ca.. For TXT and CAA, include the DNS quotes in content, then URL encode the
complete value. For example, use "v=spf1 -all" for TXT and 0 issue "letsencrypt.org" for
CAA.
Use zcp dns record-delete when you want the CLI to read the existing values and issue one delete
request for each one.
curl -s -X DELETE --get \ "https://api.zcp.zsoftly.ca/api/dns/domains/examplecom/records" \ --data-urlencode "name=www.example.com." \ --data-urlencode "type=A" \ --data-urlencode "content=203.0.113.10" \ -H "Authorization: Bearer your-token" \ -H "Accept: application/json"import requests
BASE = "https://api.zcp.zsoftly.ca/api"TOKEN = "your-token"
resp = requests.delete( f"{BASE}/dns/domains/examplecom/records", headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"}, params={"name": "www.example.com.", "type": "A", "content": "203.0.113.10"},)print(resp.json()["message"])const BASE = 'https://api.zcp.zsoftly.ca/api';const TOKEN = 'your-token';
const url = new URL(`${BASE}/dns/domains/examplecom/records`);url.search = new URLSearchParams({ name: 'www.example.com.', type: 'A', content: '203.0.113.10',}).toString();
const res = await fetch(url, { method: 'DELETE', headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },});console.log((await res.json()).message);package main
import ( "encoding/json" "fmt" "net/http" "net/url")
func main() { const base = "https://api.zcp.zsoftly.ca/api" const token = "your-token"
q := url.Values{ "name": {"www.example.com."}, "type": {"A"}, "content": {"203.0.113.10"}, } endpoint := base + "/dns/domains/examplecom/records?" + q.Encode()
req, _ := http.NewRequest("DELETE", endpoint, nil) req.Header.Set("Authorization", "Bearer "+token) req.Header.Set("Accept", "application/json")
resp, err := http.DefaultClient.Do(req) if err != nil { panic(err) } defer resp.Body.Close()
var env struct { Message string `json:"message"` } json.NewDecoder(resp.Body).Decode(&env) fmt.Println(env.Message)}Response:
{ "status": "Success", "message": "Domain record deleted successfully." }Full API Reference
Section titled “Full API Reference”The complete interactive reference is the Swagger UI: Open the Cloud Platform API.
See also: DNS Overview, Domains, DNS Records, Worked examples, Manage DNS with the CLI, Troubleshooting, API Quickstart