GANDI

LiveDNS API

Table of Contents

Introduction

LiveDNS is Gandi's upcoming DNS platform, a completely new service that offers its own API and its own nameservers.

The new platform offers powerful features to manage DNS Zone templates that you can integrate into your own workflow. Features include bulk record management, association with multiple domains, versioning and rollback.

This document describes the RESTful HTTP API, including a simple example to get you started.

Warning: beta!

API methods and resources are not fully stabilized and may yet change.

The new nameservers at ns{1,2,3}.gandi.net may experience availability and performance issues.

Getting started

Requirements

  • A Gandi API token
  • An HTTP client

Quick example

This example will show you how to create a Zone file to point the "www.example.com" and "example.com" addresses to the same IPV4 address and then associate your new Zone file with the domain.

To keep things simple and universal, the snippets use curl from the command line to make HTTP requests to the LiveDNS API. You can of course use any other tool to make the equivalent requests.

Step 1 - Get your API key

Start by retrieving your API Key from the "Security" section in new Account admin panel to be able to make authenticated requests to the API.

Then make sure you replace "XXX" with your API Key in all the following examples.

Step 2 - Create your Zone file

Make a POST request to the /zones endpoint to create your Zone file.

You only need to set the name property to something that makes sense for you and let the platform use the default values for the rest (you can change them later if you want).

Example:

$ curl -D- -X POST -H "Content-Type: application/json" \
             -H 'X-Api-Key: XXX' \
             -d '{"name": "example.com Zone"}' \
             https://dns.beta.gandi.net/api/v5/zones

HTTP/1.1 201 Created
Server: nginx
Date: Mon, 28 Dec 2015 13:23:56 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 27
Connection: keep-alive
Location: https://dns.beta.gandi.net/api/v5/zones/93cc9312-a214-408b-a75b-9d4172984746

{"message": "Zone Created"}

Note that the URI of the Zone file you have just created is available in the Location: header and that it includes the resource's uuid, which you can parse in a script.

Throughout these examples, the -D- flag is passed to curl to write the HTTP response headers to STDOUT.

Step 3 - Create the DNS records

The LiveDNS API is pretty flexible and allows you to create DNS records in a few different ways. In this example, you'll use a single PUT request to the /zones/<uuid>/records endpoint to create two DNS records, described as JSON objects.

Example:

$ curl -D- -X POST -H "Content-Type: application/json" \
        -H 'X-Api-Key: XXX' \
        -d '{"rrset_name": "www",
             "rrset_type": "A",
             "rrset_ttl": 3600,
             "rrset_values": ["192.168.0.1"]}' \
        https://dns.beta.gandi.net/api/v5/zones/93cc9312-a214-408b-a75b-9d4172984746/records


HTTP/1.1 201 Created
Server: nginx
Date: Mon, 28 Dec 2015 13:55:43 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 34
Connection: keep-alive
Location: https://dns.beta.gandi.net/api/v5/zones/93cc9312-a214-408b-a75b-9d4172984746/records/www/A

{"message": "Zone Record Created"}

Now your zone file contains two A records that point www and @ to the same IP address, with TTL values of 3600 seconds (1 hour).


You can also overwrite the whole zone using text/plain data (following the a limited subset of the RFC 1035 master file format):

$ curl -D- -XPUT -H "Content-Type: text/plain" \
    -H"X-Api-Key: $APIKEY" \
    --data-binary @- \
    https://dns.beta.gandi.net/api/v5/zones/93cc9312-a214-408b-a75b-9d4172984746/records \
    << EOF
www IN A 192.168.0.1
    IN A 192.168.0.2
@   IN MX 10 spool.mail.gandi.net.
EOF

Step 4 - Associate the domain

Now it's time to associate your domain, example.com, with this Zone file. In this example you'll use the /zones/<uuid>/domains/<domain> endpoint, as it offers the simplest possible code snippet, but you can find different ways to accomplish this in the API reference.

Example:

curl -D- -X POST -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                https://dns.beta.gandi.net/api/v5/zones/93cc9312-a214-408b-a75b-9d4172984746/domains/example.com

HTTP/1.1 201 Created
Server: nginx
Date: Mon, 28 Dec 2015 18:06:04 GMT
Content-Type: application/json; charset=UTF-8
Content-Length: 29
Connection: keep-alive
Location: https://dns.beta.gandi.net/api/v5/domains/example.com

{"message": "Domain Created"}

Step 5 - Change your nameservers

And with that you're ready to go. If you change the nameservers at your domain registrar (Gandi or another service), this new zone will be live for the whole Internet to see. Before you do this, make sure you copy all the records from your current DNS service.

Keep in mind, however, that this change will impact all your DNS settings for the domain, and that usage of the platform's nameservers is not recommended during the Beta.

  • ns1.gandi.net
  • ns2.gandi.net
  • ns3.gandi.net

Reference

API Endpoint

The LiveDNS API is currently available at:

https://dns.beta.gandi.net/api/v5/

Resources

Zone

  • uuid
  • name
  • primary_ns
  • apex_alias
  • email
  • serial
  • refresh
  • retry
  • expire
  • minimum

ZoneRecord

  • rrset_name
  • rrset_type (from RecordType)
  • rrset_ttl
  • rrset_values (list of values)

RecordType

One of A, AAAA, CNAME, MX, NS, TXT, WKS, SRV, LOC, SPF, SSHFP, DNAME.

Domain

  • fqdn
  • zone_uuid

Snapshot

  • serial
  • zone_uuid
  • change_time
  • zone_data

Usage

Work with Zones

Managing Zones

  • List

    GET /zones:

    curl -H 'X-Api-Key: XXX' https://dns.beta.gandi.net/api/v5/zones
    

    return:

    [{"retry": 3600,
      "uuid": "<UUID>",
      "minimum": 10800,
      "refresh": 10800,
      "expire": 604800,
      "serial": 1432798405,
      "user_uuid": "<USER_UUID>",
      "email": "hostmaster.gandi.net.",
      "primary_ns": "a.dns.gandi.net.",
      "name": "<NAME>"}]
    

    count number is in headers:

    X-Total-Count: 1
    
  • Create a zone with name NAME

    POST /zones:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"name": "<NAME>"}' \
                 https://dns.beta.gandi.net/api/v5/zones
    

    return:

    {"message": "Zone Created"}
    

    location is in headers:

    Location: /zones/<UUID>
    
  • Info for zone UUID

    GET /zones/<UUID>:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>
    

    return:

    {"retry": 3600,
     "uuid": "<UUID>",
     "minimum": 10800,
     "refresh": 10800,
     "expire": 604800,
     "serial": 1432798405,
     "user_uuid": "<USER_UUID>",
     "email": "hostmaster.gandi.net.",
     "primary_ns": "a.dns.gandi.net.",
     "name": "<NAME>"}
    
  • Update zone UUID

    PATCH /zones/<UUID>:

    curl -X PATCH -H "Content-Type: application/json" \
                  -H 'X-Api-Key: XXX' \
                  -d '{"name": "<NAME>"}' \
                  https://dns.beta.gandi.net/api/v5/zones/<UUID>
    

    return:

    {"message": "Request Accepted"}
    
  • Delete zone UUID

    DELETE /zones/<UUID>:

    curl -X DELETE -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/zones/<UUID>
    
  • Get domains attached to zone UUID

    GET /zones/<UUID>/domains:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/domains
    

    return:

    [{"fqdn": "<DOMAIN>"}]
    

    count number is in headers:

    X-Total-Count: 1
    
  • Attach a domain to zone UUID

    POST /zones/<UUID>/domains/<DOMAIN>:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 https://dns.beta.gandi.net/api/v5/zones/<UUID>/domains/<DOMAIN>
    

    return:

    {"message": "Domain Created"}
    

    location is in headers:

    Location: /domains/<DOMAIN>
    

Managing Records

  • List zone UUID records

    GET /zones/<UUID>/records:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    

    return:

    [{"rrset_type": "<TYPE>",
      "rrset_ttl": 10800,
      "rrset_name": "<NAME>",
      "rrset_values": ["<VALUE>"]}]
    

    count number is in headers:

    X-Total-Count: 1
    
  • Retrieve a text version of the zone

    GET /zones/<UUID>/records:

    curl -H 'X-Api-Key: XXX' -H 'Accept: text/plain' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    

    return:

    @ 10800 IN SOA ns1.gandi.net. hostmaster.gandi.net. 1444327484 10800 3600 604800 10800
    @ 10800 IN NS ns1.gandi.net.
    @ 10800 IN NS ns2.gandi.net.
    @ 10800 IN NS ns3.gandi.net.
    @ 86400 IN TXT "I am a TXT record"
    
  • Add a record "NAME" with type "TYPE" to the zone UUID

    POST /zones/<UUID>/records:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_name": "<NAME>",
                      "rrset_type": "<TYPE>",
                      "rrset_ttl": 10800,
                      "rrset_values": ["<VALUE>"]}'
                 https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    

    POST /zones/<UUID>/records/<NAME>:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_type": "<TYPE>",
                      "rrset_ttl": 10800,
                      "rrset_values": ["<VALUE>"]}' \
                 https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>
    

    POST /zones/<UUID>/records/<NAME>/<TYPE>:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_ttl": 10800,
                      "rrset_values": ["<VALUE>"]}' \
                 https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>/<TYPE>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>/<TYPE>
    
  • Change all zone UUID records (application/json)

    PUT /zones/<UUID>/records:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"items": [{"rrset_name": "<NAME1>",
                                "rrset_type": "<TYPE1>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE1>"]},
                               {"rrset_name": "<NAME2>",
                                "rrset_type": "<TYPE2>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE2>"]}]}' \
                https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    
  • Change all zone UUID records (text/plain)

    PUT /zones/<UUID>/records:

    curl -X PUT -H "Content-Type: text/plain" \
                -H 'X-Api-Key: XXX' \
                -d '<NAME1> [<TTL>] IN <TYPE1> <VALUE1>\n...' \
                https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records
    
  • Change all "NAME" records from the zone UUID

    PUT /zones/<UUID>/records/<NAME>:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"items": [{"rrset_type": "<TYPE1>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE1>"]},
                               {"rrset_type": "<TYPE2>",
                                "rrset_ttl": 10800,
                                "rrset_values":["<VALUE2>"]}]}' \
                https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>
    
  • Change the "NAME"/"TYPE" record from the zone UUID

    PUT /zones/<UUID>/records/<NAME>/<TYPE>:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"rrset_ttl": 10800,
                     "rrset_values": ["<VALUE>"]}' \
                https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>/<TYPE>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>/<TYPE>
    
  • List all records with name "NAME" in the zone UUID

    GET /zones/<UUID>/records/<NAME>:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>
    

    return:

    [{"rrset_type": "<TYPE>",
      "rrset_ttl": 10800,
      "rrset_name": "<NAME>",
      "rrset_values": ["<VALUE>"]}]
    
  • List all records with name "NAME" and type "TYPE" in the zone UUID

    GET /zones/<UUID>/records/<NAME>/<TYPE>:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>/<TYPE>
    

    return:

    {"rrset_type": "<TYPE>",
     "rrset_ttl": 10800,
     "rrset_name": "<NAME>",
     "rrset_values": ["<VALUE>"]}
    
  • Remove the record "NAME" with type "TYPE" from the zone UUID

    DELETE /zones/<UUID>/records/<NAME>/<TYPE>:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>/<TYPE>
    
  • Remove all records "NAME" from the zone UUID

    DELETE /zones/<UUID>/records/<NAME>:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/zones/<UUID>/records/<NAME>
    
  • Remove all records from the zone UUID

    DELETE /zones/<UUID>/records:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/zones/<UUID>/records
    

Using Snapshots

  • List snapshots for zone UUID

    GET /zones/<UUID>/snapshots:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/zones/<UUID>/snapshots
    

    return:

    [{"zone_data": [{"rrset_type": "<TYPE>",
                     "rrset_ttl": 10800,
                     "rrset_name": "<NAME>",
                     "rrset_values": ["<VALUE>"]}],
      "zone_uuid": "<UUID>",
      "serial": 1432798544,
      "user_uuid": "<USER_UUID>",
      "change_time": "2015-05-28T09:50:20Z"}]
    
  • Create a new snapshot for zone UUID

    POST /zones/<UUID>/snapshots:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX'
                 https://dns.beta.gandi.net/api/v5/zones/<UUID>/snapshots
    

    return:

    {"message": "Zone Snapshot Created"}
    

Work with Domains

  • Add a domain "DOMAIN" to the zone UUID

    POST /domains:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"fqdn": "<DOMAIN>",
                      "zone_uuid": "<UUID>"}' \
                 https://dns.beta.gandi.net/api/v5/domains
    

    return:

    {"message": "Domain Created"}
    

    location is in headers:

    Location: /domains/<DOMAIN>
    
  • List domains

    GET /domains:

    curl -H 'X-Api-Key: XXX' https://dns.beta.gandi.net/api/v5/domains
    

    return:

    [{"fqdn": "<DOMAIN1>"},
     {"fqdn": "<DOMAIN2>"}]
    

    count number is in headers:

    X-Total-Count: 2
    
  • Info on domain "DOMAIN"

    GET /domains/<DOMAIN>:

    curl -H 'X-Api-Key: XXX' https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>
    

    return:

    {"zonedata": "/zones/<UUID>/records",
     "fqdn": "<DOMAIN>",
     "zone": "/zones/<UUID>"}
    
  • Change the zone associated to domain "DOMAIN"

    PATCH /domains/<DOMAIN>:

    curl -X PATCH -H "Content-Type: application/json" \
                  -H 'X-Api-Key: XXX' \
                  -d '{"zone_uuid": "<UUID>"}' \
                  https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>
    

    return:

    {"message": "Request Accepted"}
    
  • Get records for the zone associated to domain "DOMAIN"

    GET /domains/<DOMAIN>/records:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records
    

    return:

    [{"rrset_type": "<TYPE>",
      "rrset_ttl": 10800,
      "rrset_name": "<NAME>",
      "rrset_values": ["<VALUE>"]}]
    

    count number is in headers:

    X-Total-Count: 1
    
  • Get "NAME" records for the zone associated to domain "DOMAIN"

    GET /domains/<DOMAIN>/records/<NAME>:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>
    

    return:

    [{"rrset_type": "<TYPE>",
      "rrset_ttl": 10800,
      "rrset_name": "<NAME>",
      "rrset_values": ["<VALUE>"]}]
    

    count number is in headers:

    X-Total-Count: 1
    
  • Get "NAME" records of type "TYPE" for the zone associated to domain "DOMAIN"

    GET /domains/<DOMAIN>/records/<NAME>/<TYPE>:

    curl -H 'X-Api-Key: XXX' \
         https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>/<TYPE>
    

    return:

    {"rrset_type": "<TYPE>",
     "rrset_ttl": 10800,
     "rrset_name": "<NAME>",
     "rrset_values": ["<VALUE>"]}
    
  • Add a record "NAME" with type "TYPE" to the zone associated to domain "DOMAIN"

    POST /domains/<DOMAIN>/records:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_name": "<NAME>",
                      "rrset_type": "<TYPE>",
                      "rrset_ttl": 10800,
                      "rrset_values": ["<VALUE>"]}' \
                 https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records
    

    POST /domains/<DOMAIN>/records/<NAME>:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_type": "<TYPE>",
                      "rrset_ttl": 10800,
                      "rrset_values": ["<VALUE>"]}' \
                 https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>
    

    POST /domains/<DOMAIN>/records/<NAME>/<TYPE>:

    curl -X POST -H "Content-Type: application/json" \
                 -H 'X-Api-Key: XXX' \
                 -d '{"rrset_ttl": 10800,
                      "rrset_values":["<VALUE>"]}' \
                 https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>/<TYPE>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>/<TYPE>
    
  • Change all records from the zone associated with domain "DOMAIN"

    PUT /domains/<DOMAIN>/records:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"items": [{"rrset_name": "<NAME1>",
                                "rrset_type": "<TYPE1>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE1>"]},
                               {"rrset_name": "<NAME2>",
                                "rrset_type": "<TYPE2>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE2>"]}]}' \
                https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records
    
  • Change all "NAME" records from the zone associated with domain "DOMAIN"

    PUT /domains/<DOMAIN>/records/<NAME>:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"items": [{"rrset_type": "<TYPE1>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE1>"]},
                               {"rrset_type": "<TYPE2>",
                                "rrset_ttl": 10800,
                                "rrset_values": ["<VALUE2>"]}]}' \
                https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>
    
  • Change the "NAME"/"TYPE" record from the zone associated with domain "DOMAIN"

    PUT /domains/<DOMAIN>/records/<NAME>/<TYPE>:

    curl -X PUT -H "Content-Type: application/json" \
                -H 'X-Api-Key: XXX' \
                -d '{"rrset_ttl": 10800,
                     "rrset_values":["<VALUE>"]}' \
                https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>/<TYPE>
    

    return:

    {"message": "Zone Record Created"}
    

    location is in headers:

    Location: /zones/<UUID>/records/<NAME>/<TYPE>
    
  • Remove the record "NAME" with type "TYPE" from the zone associated to domain "DOMAIN"

    DELETE /domains/<DOMAIN>/records/<NAME>/<TYPE>:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>/<TYPE>
    
  • Remove the "NAME" records from the zone associated to domain "DOMAIN"

    DELETE /domains/<DOMAIN>/records/<NAME>:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records/<NAME>
    
  • Remove the records from the zone associated to domain "DOMAIN"

    DELETE /domains/<DOMAIN>/records:

    curl -X DELETE -H "Content-Type: application/json" \
                   -H 'X-Api-Key: XXX' \
                   https://dns.beta.gandi.net/api/v5/domains/<DOMAIN>/records