Overview

Introduction

Gandi provides remotes APIs using the XML-RPC protocol making it easy to build third party applications to manage your Gandi resources (domains, contacts, hosting, etc).

This documentation is a complete reference to the Gandi API v3.0.

Warning

There will be no future developments on this API, as we are moving to our new REST api, which is documented at https://api.gandi.net

XML-RPC Interface

Endpoint: https://rpc.gandi.net/xmlrpc/

For your safety all connections to rpc.gandi.net must be issued over HTTPS. The certificate fingerprints are the following:

SHA1: 0F:38:EF:70:09:BC:F2:A3:B2:AC:9C:9E:65:40:BA:99:DE:C6:16:A1
SHA1: 0F:38:EF:70:09:BC:F2:A3:B2:AC:9C:9E:65:40:BA:99:DE:C6:16:A1_SHA256

Note

The previous URL https://rpc.gandi.net/xmlrpc/2.0/ is now obsolete.

Client

>>> import xmlrpc.client
>>> api = xmlrpc.client.ServerProxy('https://rpc.gandi.net/xmlrpc/')
>>>
>>> apikey = 'my 24-character API key'
>>>
>>> # Now you can call API methods.
>>> # You must authenticate yourself by passing
>>> # the API key as the first method's argument
>>> version = api.version.info(apikey)

Note

In Python, use the xmlrpcclient module from the standard library.

<?php
// Library installed from PEAR
require_once 'XML/RPC2/Client.php';

// The first step is to connect to the API
$version_api = XML_RPC2_Client::create(
    'https://rpc.gandi.net/xmlrpc/',
    array( 'prefix' => 'version.', 'sslverify' => True )
);

// Warning !
// PEAR::XML_RPC2 checks the SSL certificate with Curl
// Curl has its own CA bundle so you may :
// * disable the 'sslverify' option: leads to security issue
// * enable the 'sslverify' option (default) and add the Gandi
// SSL certificate to the Curl bundle: best choice for security
// See: https://curl.haxx.se/docs/sslcerts.html

$apikey = 'my 24-character API key';

// Now you can call API method
// You must authenticate yourself by passing the API key
// as the first method's argument
$result = $version_api->info($apikey);

// Warning !
// PEAR::XML_RPC2 has known bugs on methods calls
// See https://pear.php.net/bugs/bug.php?id=13963
// You may use this call instead of the above one :
// $result = $version_api->__call("info", $apikey);

// dump the result
print_r($result);
?>

Note

In PHP 5, use the XML_RPC2 package from pear.

XML_RPC2 works with ‘prefix’ in order to bind to namespace. The ‘prefix’ isn’t editable, so you have to instanciante a client by namespace.

> var xmlrpc = require('xmlrpc')
> var api = xmlrpc.createSecureClient({
...  host: 'rpc.gandi.net',
...  port: 443,
...  path: '/xmlrpc/'
... })
>
> var apikey = 'my 24-character API key'
>
> // Now you can call API methods.
> // You must authenticate yourself by passing the API key
> // as the first method's argument
> api.methodCall('version.info', [apikey], function (error, value) {
...  console.dir(value)
... })

Note

With NodeJS, use the npm xmlrpc package.

use XML::RPC;

my $api = XML::RPC->new('https://rpc.gandi.net/xmlrpc/');

my $apikey = 'my 24-character API key';

# Now you can call API methods.
# You must authenticate yourself by passing the API key
# as the first method's argument
my $version = $api->call( 'version.info', $apikey );

Note

With perl, use the cpan xml::rpc package.

require 'xmlrpc/client'

server = XMLRPC::Client.new2('https://rpc.gandi.net/xmlrpc/')

apikey = 'my 24-character API key'

# Now you can call API methods.
# You must authenticate yourself by passing the API key
# as the first method's argument
version = server.call("version.info", apikey)

Note

With ruby, use the xmlrpc/client module from the standard library. Ruby does not support gzip by default, the ZlibParserDecorator is used to enabled with Ruby >1.9.

For older ruby version, neither set the http_header_extra nor the parser.

Note

To avoid RuntimeError with ruby >= 1.9, add:

XMLRPC::Config.module_eval {
    remove_const(:ENABLE_NIL_PARSER)
    const_set(:ENABLE_NIL_PARSER, true)
}
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#include <xmlrpc.h>
#include <xmlrpc_client.h>

#define CLIENT_NAME             "Documentation Client"
#define CLIENT_VERSION          "0.1"
#define CLIENT_USERAGENT        CLIENT_NAME "/" CLIENT_VERSION

#define SERVER_URL              "https://rpc.gandi.net/xmlrpc/"

int     client_connect(xmlrpc_env *);
void    client_check_fault(xmlrpc_env *);

int
main(int argc, char **argv)
{
        xmlrpc_env      env;
        xmlrpc_value    *apikey, *rv;

        client_connect(&env);

        apikey = xmlrpc_build_value(&env, "(s)", "my 24-character API key");
        rv = xmlrpc_client_call_params(&env, SERVER_URL, "version.info", apikey);
        client_check_fault(&env);

        xmlrpc_DECREF(rv);
        xmlrpc_DECREF(apikey);

        xmlrpc_env_clean(&env);
        xmlrpc_client_cleanup();

        return (0);
}

int
client_connect(xmlrpc_env *env)
{
        struct xmlrpc_clientparms clientp;
        struct xmlrpc_curl_xportparms curlp;

        curlp.network_interface = NULL;         /* use curl's default */
        curlp.ssl_verifypeer = 1;               /* Gandi API CA must be present */
        curlp.ssl_verifyhost = 2;
        curlp.user_agent = CLIENT_USERAGENT;    /* XML-RPC requirement */

        clientp.transport = "curl";
        clientp.transportparmsP = &curlp;
        clientp.transportparm_size = XMLRPC_CXPSIZE(user_agent);

        xmlrpc_env_init(env);
        xmlrpc_client_init2(env, XMLRPC_CLIENT_NO_FLAGS, CLIENT_NAME,
            CLIENT_VERSION, &clientp, XMLRPC_CPSIZE(transportparm_size));
        client_check_fault(env);

        return (1);
}

void
client_check_fault(xmlrpc_env *env)
{
        if (env->fault_occurred) {
                fprintf(stderr, "XML-RPC Fault: %s (%d)\n", env->fault_string,
                    env->fault_code);
                exit(1);
        }
}

Note

With C, use the xmlrpc-c library.

Stateless

The Gandi API does not maintain sessions. In other words a call does not depend on previous calls but only on its arguments. It only provides descriptions of objects.

Authentication

Every call to the Gandi API requires authentication. That is why all our methods take a unique Gandi API Key as first argument. If you don’t have it already, you can retrieve your API key on your API Key Page.

>>> api.version.info(apikey)
<?php
print_r($api_version->info($apikey))

// See bug : https://pear.php.net/bugs/bug.php?id=13963
// In case of problem, use : print_r($api_version->_call("info", $apikey))
?>
> api.methodCall('version.info', [apikey], function (error, value) {
...  console.dir(value)
... })
my $info = $api->call( 'version.info', $apikey );
info = server.call('version.info', apikey)
xmlrpc_value *info;

info = xmlrpc_client_call_params(&env, SERVER_URL, "version.info", apikey);

Note

Store your API key in a safe place.

Rate limit

A maximum of 30 calls per 2 seconds are permitted with the same Gandi API Key.

Introspection

The Gandi API supports the XML introspection API:

>>> api = xmlrpc.client.ServerProxy(API_URI)
>>> api.system.listMethods()
['catalog.list', 'contact.balance', 'contact.can_associate', ...]
>>> api.system.methodHelp('domain.list')
domain.list(apikey, [opts=nil])
List domains associated to the contact represented by **apikey**.
>>> api.system.methodSignature('domain.list')
[['struct', 'string', 'array']]

OT&E System

Endpoint: https://rpc.ote.gandi.net/xmlrpc/

Alongside the production API, Gandi provides an Operational Test and Evaluation (OT&E) platform.

Its certificate fingerprints are

SHA1: 9A:8D:66:CE:FE:AC:00:68:8D:25:B9:90:ED:99:AD:42:7C:B9:C9:88
SHA1: 9A:8D:66:CE:FE:AC:00:68:8D:25:B9:90:ED:99:AD:42:7C:B9:C9:88_SHA256

The Gandi OTE Platform is almost similar to the production one. The differences are:

  • You won’t receive email notification of your commands status
  • All calls are executed in the Registries OT&E Systems
  • The Transfer process is not available

For example, if you create a domain via OT&E it will be created but only on the test server of the Registry.

Note

Due to some Registry limitation, not all TLDs are available in Gandi OT&E System.

Versioning and Release Policy

When a new version of the API code is ready to be released, Gandi will install it on the Gandi OTE Platform. Customers can connect to this API and test/validate/update their application code reflecting the changes in the Gandi API, which will be outlined in the changelog.

Gandi will post information about a new version reaching OT&E on various communication mediums.

After a specified amount of time, the release on OT&E will be moved on the Gandi production API and the documentation will be made available on the Gandi API doc page.

Gandi will announce this change.

API versions follow a simple pattern: 3.x.y with y being a minor version mainly for internal purpose and x a ‘major’ version which indicates a major change in the API (such as signature change or other incompatibility). The first number is a historical number for Gandi, in this case it denotes the third rewrite of our information system.