Primary DNS API v1

This documentation describes the legacy DNS API. It is recommended that new users use DNS API v2.

Our Primary DNS service can be manually configured through the Customer Control Panel For many applications, you may want to script additions, updates and deletions of primary DNS resource records. This can be done using our API. For example, you could use the Primary DNS API to:

  • implement DNS-based failover for your site;
  • implement a dynamic DNS system;
  • use DNS to redirect to a holding page during site maintenance.


In order to use the API, you must set a password in the control panel interface for your domain that you wish to manage, using the DNS API option.

Note that this API uses separate, per-domain credentials. API keys for DNS API v2 cannot be used with this API.

Making requests

Requests to the API take the form of an HTTP request containing a number of HTTP parameters. These are documented below. HTTP requests should be made to:


IPv4 and IPv6 only versions of this service are also available:

  • (IPv4-only)
  • (IPv6-only)

These IP-version specific URLs are useful when using the DYNAMIC_IP parameter to construct a Dynamic DNS service.

The request can be made using either a GET request, with parameters in the query string, or a POST request, with parameters specified in an application/x-www-form-urlencoded request body. However, we would always recommend POST, as otherwise your domain API password will appear unencrypted in the URL of the request.

HTTP parameters

Required. The domain name you are updating the zonefile for, e.g.
Required. The password set in the control panel for the domain.
Required. An API command. Commands take the form of a verb followed by a zone file entry as appropriate. This parameter can be repeated to perform multiple commands in a single transaction.
Optional. The suffix to be appended to the hostname given in commands. By default, this will be your domain name. Specifying a value of . allows you to provide fully qualified hostnames in your commands.


All the commands in the request parameter are processed in order. The commands allowed are as follows.


The ADD command requests that an entry be added to the zone file. This command can take any of the following forms:

ADD host ttl type data
ADD host ttl MX mx_priority data
ADD host ttl SRV srv_priority srv_weight srv_port data

For example:

ADD www 86400 A

If successful, the response will contain ADD followed by the entry. Otherwise, the response will contain NADD followed by the entry and a reason that the update didn't succeed. For example:

NADD www 86400 A; Can't have multiple identical records


The DELETE command requests that an entry be removed from the zone. Valid syntax for this command is

DELETE host ttl type data
DELETE host ttl MX mx_priority data
DELETE host ttl SRV srv_priority srv_weight srv_port data

For example:

DELETE www 86400 A

The response will contain DELETE followed by the entry in the event of success, and NDELETE followed by the entry and a reason in the event of failure.


The LIST command takes no arguments, and requests a list of all the entries in the zone. For example:

@ 86400 NS
@ 86400 MX 10
@ 86400 A
@ 86400 NS
@ 86400 NS


The REPLACE command takes a new record as argument, and replaces all existing records, if any, for the same host and type (and, if relevant, MX priority) with the new record provided. This is the easiest way to implement Dynamic DNS using the API.

For example:

REPLACE www 300 A

This will delete all existing A records for "www" and replace them with the provided record.

You can also substitute the IP address for DYNAMIC_IP, and the service will use the client's IP address.



You'll need to make sure you are connecting to the API over the correct IP version for this to work. Use or, for IPv4 or IPv6 records respectively.

Note that the REPLACE command potentially replaces multiple records with a single record. If this is an issue, you should use combinations of DELETE and ADD commands instead.


Each HTTP request is treated as an atomic transaction, meaning that either all commands succeed or none of them do, and that there is no danger of the DNS zone being updated with the result of only some of the commands being applied. This means that, with the exception of ANAME records, you can safely change a record by putting a DELETE followed by an ADD into the same HTTP request.

If a transaction is aborted because a later command fails, then the response will include positive acknowledgements of the earlier commands, but their results will not be committed. You can check the overall status of the request using the HTTP response code which will be 200 in the event of success, and a 4xx code in the event of a failure.

Note that when an ANAME record is deleted, any A and AAAA records that it has generated will be removed immediately, but it may be a number of minutes before records are generated for any new ANAME records that it is replaced with.


We update our DNS servers every minute, so changes should generally be visible on our servers within a minute or so. The DNS system relies heavily on caching, so requests made via other DNS servers may take much longer to take effect. You can control this using the TTL field on records.

Sample code


API updates can be made using the curl command line utility:

curl --data "domain=MY_DOMAIN&password=MY_PASSWORD&command=LIST" \


wget -q -O- '--post-data=domain=MY_DOMAIN;password=MY_PASSWORD;command=ADD wibble 300 TXT foobar;command=LIST'

As the second example demonstrates, you can use either ampersand & or semicolon ; to separate parameters. Send more than one command by using multiple command= parameters.


#!/usr/bin/perl -w

use WWW::Mechanize;

my $domain = '';
my $password = 'this-is-actually-a-secret';
my $url = '';

my $mech = new WWW::Mechanize;
print "Zone\n\n";

        { domain => $domain, password => $password, command => 'LIST' }
print $mech->content();


#!/usr/bin/env python3

import urllib.request
import urllib.parse

yourDomain = ""

yourDomainAPIPass = "password"

url = ''

values = {'domain'  : yourDomain,
          'password' : yourDomainAPIPass,
          'command'  : 'LIST' }

data = urllib.parse.urlencode(values).encode('utf-8')
req = urllib.request.Request(url, data)
response = urllib.request.urlopen(req)
responseContents ="utf-8")


We have published a hook for dehydrated which uses the DNS API to answer ACME challenges.

One of our customers has written a script to synchronize zone data to our servers.