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.


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


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


>>> 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)


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

// 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(
    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


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)
... })


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 );


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)


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.


To avoid RuntimeError with ruby >= 1.9, add:

XMLRPC::Config.module_eval {
    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 SERVER_URL              "https://rpc.gandi.net/xmlrpc/"

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

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


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



        return (0);

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_client_init2(env, XMLRPC_CLIENT_NO_FLAGS, CLIENT_NAME,
            CLIENT_VERSION, &clientp, XMLRPC_CPSIZE(transportparm_size));

        return (1);

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


With C, use the xmlrpc-c library.


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.


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)

// 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);


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.


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.


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.