Domain API¶
Introduction¶
The Gandi Domain API provides a set of remote requests to manage your domains.
Connecting to the API server¶
The Gandi Domain API is provided through a set of XML-RPC calls:
>>> 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);
?>
> 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.
Note
the Domain API does not use HTTP authentication. It uses a custom authentication mechanism based on the API key.
Domain Creation¶
Steps to create a domain¶
- Choose a Domain name
- Choose or create contacts
- Create the domain
Choose a domain name¶
First, you’ll need to check the domain availability via the
domain.available()
method:
>>> import time
>>> domain = 'mydomain.net'
>>> result = api.domain.available(apikey, [domain])
>>> result
{'mydomain.net': 'pending'}
>>> while result[domain] == 'pending':
time.sleep(0.7)
result = api.domain.available(apikey, [domain])
>>> result
{'mydomain.net': 'unavailable'}
<?php
$domain = "mydomain.net";
$domain_api = XML_RPC2_Client::create(
'https://rpc.gandi.net/xmlrpc/',
array( 'prefix' => 'domain.' )
);
$result = $domain_api->available($apikey, array($domain));
print_r($result);
/*
Array
(
[mydomain.net] => pending
)
*/
while ( $result[$domain] == 'pending') {
usleep(700000);
$result = $domain_api->available($apikey, array($domain));
}
print_r($result);
/*
Array
(
[mydomain.net] => unavailable
)
*/
?>
> var domain = 'mydomain.net'
> var callback = function(error, value) {
... if ( value[domain] == 'pending' ) {
... console.log('result is not yet ready')
... setTimeout(function() {
... api.methodCall('domain.available', [apikey, [domain]],
... callback)
... }, 700)
... }
... else {
... console.dir(value)
... }
... }
> api.methodCall('domain.available', [apikey, [domain]], callback)
use Time::HiRes qw();
my $domain = 'mydomain.net';
my $result = $api->call( 'domain.available', $apikey, [$domain] );
print Data::Dumper->Dump( [$result] );
#$VAR1 = {
# 'mydomain.net' => 'pending'
#};
$api->call( 'domain.available', $apikey, [$domain] );
$result = $api->call( 'domain.available', $apikey, [$domain] );
while ($result->{$domain} eq 'pending') {
Time::HiRes::sleep(0.7);
$result = $api->call( 'domain.available', $apikey, [$domain] );
}
print Data::Dumper->Dump( [$result] );
#$VAR1 = {
# 'mydomain.net' => 'unavailable'
#};
domain = 'mydomain.net'
print server.call("domain.available", apikey, [domain])
{"mydomain.net"=>"pending"}
server.call("domain.available", apikey, [domain])
while result[domain] == 'pending' do
sleep 0.7
result = server.call("domain.available", apikey, [domain])
end
print result
{"mydomain.net"=>"unavailable"}
Note
the available method is asynchronous. You have to call it again if the result is not ready.
Choose or create contacts¶
You’ll need to associate your domain to an owner and 3 specific contacts: the
admin, billing and technical contacts.
You can choose existing contacts or, if needed, you can create new contacts,
using the contact.create()
(see Contact API).
Before creating your domain you can also check domain/contacts association
rules with the contact.can_associate_domain()
method (see How-to check domain/contact association).
Use the contact.update()
to correct missing or incorrect contact
attributes.
>>> association_spec = {
... 'domain': 'mydomain.fr',
... 'owner': True,
... 'admin': True}
>>> api.contact.can_associate_domain(apikey, 'FLN123-GANDI',
... association_spec)
True
>>> api.contact.can_associate_domain(apikey, 'FLN123-GANDI',
... association_spec)
[{'error': 'EC_INVALIDPARAM1+!EC_ENUMIN',
'field': 'birth_country',
'field_type': 'Enum',
'reason': 'BirthCountryIso: not in list ...
},... ]
<?php
$contact_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'contact.'));
$association_spec = array(
'domain' => 'mydomain.fr',
'owner' => true,
'admin' => true );
print_r( $contact_api->can_associate_domain($apikey, 'FLN123-GANDI',
$association_spec) );
// 1
// OR
print_r( $contact_api->can_associate_domain($apikey, 'FLN123-GANDI',
$association_spec) )
/*
[{'error': 'EC_INVALIDPARAM1+!EC_ENUMIN',
'field': 'birth_country',
'field_type': 'Enum',
'reason': 'BirthCountryIso: not in list ...
},... ]
*/
?>
> var association_spec = {
... domain: 'mydomain.fr',
... owner: true,
... admin: true}
> api.methodCall('contact.can_associate_domain',
... [apikey, 'FLN123-GANDI', association_spec],
... function (error, value) {
... console.dir(value)
... })
my $association_spec = {
'domain' => 'mydomain.fr',
'owner' => True,
'admin' => True
};
my $result = $api->call( 'contact.can_associate_domain', $apikey,
'FLN123-GANDI', $association_spec );
print $result;
True
$result = $api->call( 'contact.can_associate_domain', $apikey,
'FLN123-GANDI', $association_spec );
print $result;
[{'error': 'EC_INVALIDPARAM1+!EC_ENUMIN',
'field': 'birth_country',
'field_type': 'Enum',
'reason': 'BirthCountryIso: not in list ...'
} #,...
]
association_spec = {
'domain' => 'mydomain.fr',
'owner'=> true,
'admin'=> true
}
print server.call("contact.can_associate_domain", apikey, 'FLN123-GANDI',
association_spec)
True
print server.call("contact.can_associate_domain", apikey, 'FLN123-GANDI',
association_spec)
[{'error': 'EC_INVALIDPARAM1+!EC_ENUMIN',
'field': 'birth_country',
'field_type': 'Enum',
'reason': 'BirthCountryIso: not in list ...'
}, #...
]
Create the domain¶
To create your domain use domain.create()
>>> domain_spec = {
... 'owner': 'FLN123-GANDI',
... 'admin': 'FLN123-GANDI',
... 'bill': 'FLN123-GANDI',
... 'tech': 'FLN123-GANDI',
... 'nameservers': ['a.dns.gandi-ote.net', 'b.dns.gandi-ote.net',
... 'c.dns.gandi-ote.net'],
... 'duration': 1}
>>> op = api.domain.create(apikey, 'mydomain.net', domain_spec)
<?php
$domain_spec = array(
'owner' => 'FLN123-GANDI',
'admin' => 'FLN123-GANDI',
'bill' => 'FLN123-GANDI',
'tech' =>'FLN123-GANDI',
'nameservers' => array('a.dns.gandi-ote.net', 'b.dns.gandi-ote.net',
'c.dns.gandi-ote.net'),
'duration' => 1);
$op = $domain_api->__call('create', array($apikey, 'mydomain.net',
$domain_spec));
?>
Note
$domain_api->__call(“create”,…) calls the rpc method domain.create()
see bug #13963 : RPC method named create can’t be called by client.
> var domain_spec = {
... owner: 'FLN123-GANDI',
... admin: 'FLN123-GANDI',
... bill: 'FLN123-GANDI',
... tech: 'FLN123-GANDI',
... nameservers: ['a.dns.gandi-ote.net', 'b.dns.gandi-ote.net',
... 'c.dns.gandi-ote.net'],
... duration: 1
... }
> api.methodCall('domain.create', [apikey, 'mydomain.net', domain_spec],
... function (error, value) {
... console.dir(value)
... })
my $domain_spec = {
owner => 'FLN123-GANDI',
admin => 'FLN123-GANDI',
bill => 'FLN123-GANDI',
tech => 'FLN123-GANDI',
nameservers => ['a.dns.gandi-ote.net', 'b.dns.gandi-ote.net',
'c.dns.gandi-ote.net'],
duration => 1,
};
my $op = $api->call( 'domain.create', $apikey, 'mydomain.net',
$domain_spec);
domain_spec = {
'owner' => 'FLN123-GANDI',
'admin' => 'FLN123-GANDI',
'bill' => 'FLN123-GANDI',
'tech' => 'FLN123-GANDI',
'nameservers' => ['a.dns.gandi-ote.net', 'b.dns.gandi-ote.net',
'c.dns.gandi-ote.net'],
'duration' => 1}
op = server.call("domain.create", apikey, 'mydomain.net', domain_spec)
domain.create()
takes the domain name as the first argument and
the domain specification as its second argument.
The domain specification provides the owner, admin, tech and bill contacts,
the nameservers and the duration (in years) of your domain.
When you ask for a domain creation, the domain will not be immediately
available. You can track the process state by calling operation.info()
.
>>> op = api.operation.info(apikey, op['id'])
>>> op['step']
'BILL'
>>> op = api.operation.info(apikey, op['id'])
>>> op['step']
'DONE'
<?php
$op = $operation_api->info($apikey, $op['id'])
echo $op['step']
//'BILL'
// and later...
$op = $operation_api->info($apikey, $op['id'])
echo $op['step']
//'DONE'
?>
Note
XML_RPC2 works with ‘prefix’ in order to represent object notation.
> client.methodCall( 'operation.info', [apikey, op['id']],
... function(err, value) {
... console.log(value.step)
... // output 'BILL'
... // but later, will print 'DONE'
... })
my $operation = $api->call( 'operation.info', $apikey, $op->{'id'} );
print $operation->{'step'};
'BILL'
$operation = $api->call( 'operation.info', $apikey, $op->{'id'} );
print $operation->{'step'};
'DONE'
op = server.call("operation.info", apikey, op{'id'})
print op['step']
'BILL'
op = server.call("operation.info", apikey, op{'id'})
print op['step']
'DONE'
Domain Management¶
Get Information¶
To get information, you can use the list, count, and info methods on the domain namespace.
>>> api.domain.info(apikey, 'mydomain.net')
{'authinfo': 'xxx',
'contacts': {'admin': {'handle': 'FLN123-GANDI', 'id': 12345},
'bill': {'handle': 'FLN123-GANDI', 'id': 12345},
'tech': {'handle': 'FLN123-GANDI', 'id': 12345},
'admin': {'handle': 'FLN123-GANDI', 'id': 12345},
'owner': {'handle': 'FLN123-GANDI', 'id': 12345},
'reseller': {'handle': 'FLN123-GANDI', 'id': 12345},
},
'tld': 'com',
'date_created': <DateTime '20110304T16:48:17' at 8d1072c>,
'date_updated': <DateTime '20110506T15:34:17' at 8d1072c>,
'date_registry_end': <DateTime '20120304T16:48:17' at 8d1072c>,
'fqdn': 'mydomain.net',
'id': 123,
'nameservers': ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
'status': ['TransferProhibited'],
'tags': ['a', 'b', 'c'],
'zone_id': 42}
<?php
print_r($domain_api->info($apikey, 'mydomain.net'));
/*
Array
(
[status] => Array
(
[0] => clientTransferProhibited
)
[zone_id] => 42
[contacts] => Array
(
[owner] => Array
(
[handle] => FLN123-GANDI
[id] => 12345
)
[admin] => Array
(
[handle] => FLN123-GANDI
[id] => 12345
)
[bill] => Array
(
[handle] => FLN123-GANDI
[id] => 12345
)
[tech] => Array
(
[handle] => FLN123-GANDI
[id] => 12345
)
[reseller] =>
)
[date_updated] => stdClass Object
(
[scalar] => 20110902T18:27:34
[timestamp] => 1314980854
[xmlrpc_type] => datetime
)
[date_registry_end] => stdClass Object
(
[scalar] => 20120902T16:27:33
[timestamp] => 1346596053
[xmlrpc_type] => datetime
)
[tags] => Array
(
)
[fqdn] => mydomain.net
[nameservers] => Array
(
[0] => a.dns.gandi.net
[1] => b.dns.gandi.net
[2] => c.dns.gandi.net
)
[authinfo] => xxx
[tld] => com
[date_created] => stdClass Object
(
[scalar] => 20110902T16:27:34
[timestamp] => 1314973654
[xmlrpc_type] => datetime
)
[id] => 123
)
*/
Note
XML_RPC2 works with a ‘prefix’ in order to bind to namespace. The ‘prefix’ isn’t editable, so you have to instanciante a client by namespace
> api.methodCall('domain.info', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
{ status: [ 'clientTransferProhibited' ],
zone_id: 42,
contacts:
{ owner: { handle: 'FLN123-GANDI', id: 1002336 },
admin: { handle: 'FLN123-GANDI', id: 1002336 },
bill: { handle: 'FLN123-GANDI', id: 1002336 },
tech: { handle: 'FLN123-GANDI', id: 1002336 },
reseller: '' },
date_updated: Fri, 02 Sep 2011 16:27:34 GMT,
date_registry_end: Sun, 02 Sep 2012 14:27:33 GMT,
tags: [],
fqdn: 'mydomain.net',
nameservers: [ 'a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net' ],
authinfo: 'A3SB9$9j8u',
tld: 'com',
date_created: Fri, 02 Sep 2011 14:27:34 GMT,
id: 2049696 }
my $result = $api->call( 'domain.info', $apikey, 'mydomain.net' );
print Data::Dumper->Dump( [$result] );
#$VAR1 = { 'authinfo' => 'xxx',
#'contacts' => {'admin' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# 'bill' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# 'tech' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# 'admin' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# 'owner' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# 'reseller' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
# },
# 'tld' => 'com',
# 'date_created' => '20110304T16:48:17',
# 'date_updated' => '20110506T15:34:17',
# 'date_registry_end' => '20120304T16:48:17',
# 'fqdn' => 'mydomain.net',
# 'id' => 123,
# 'nameservers' => ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
# 'status' => ['TransferProhibited'],
# 'tags' => ['a', 'b', 'c'],
# 'zoneid' => 42};
print server.call("domain.info", apikey, 'mydomain.net')
{'authinfo' => 'xxx',
'contacts' => {'admin' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
'bill' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
'tech' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
'admin' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
'owner' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
'reseller' => {'handle' => 'FLN123-GANDI', 'id' => 12345},
},
'tld' => 'com',
'date_created' => #<XMLRPC::DateTime:0x00000001f58970 @year=2011,
... @month=3, @day=4, @hour=16, @min=48, @sec=17>,
'date_updated' => #<XMLRPC::DateTime:0x00000001f58970 @year=2011,
... @month=5, @day=6, @hour=15, @min=34, @sec=17>,
'date_registry_end' => #<XMLRPC::DateTime:0x00000001f58970 @year=2012,
... @month=3, @day=4, @hour=16, @min=48, @sec=17>,
'fqdn' => 'mydomain.net',
'id' => 123,
'nameservers' => ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
'status' => ['TransferProhibited'],
'tags' => ['a', 'b', 'c'],
'zone_id' => 42}
You can use the following domain namespaces if you need to retrieve more data:
For each namespace, the info/list/count methods are available.
Getting domain host information:
>>> api.domain.host.list(apikey, 'mydomain.net')
>>> api.domain.host.count(apikey, 'mydomain.net')
>>> api.domain.host.info(apikey, 'www.mydomain.net')
<?php
$domain_host_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.host.'));
$domain_host_api->list($apikey, 'mydomain.net');
$domain_host_api->count($apikey, 'mydomain.net');
$domain_host_api->info($apikey, 'mydomain.net');
?>
> api.methodCall('domain.host.list', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.host.count', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.host.info', [apikey, 'www.mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.host.list', $apikey, 'mydomain.net' );
$api->call( 'domain.host.count', $apikey, 'mydomain.net' );
$api->call( 'domain.host.info', $apikey, 'www.mydomain.net' );
server.call("domain.host.list", apikey, 'mydomain.net')
server.call("domain.host.count", apikey, 'mydomain.net')
server.call("domain.host.info", apikey, 'www.mydomain.net')
Getting domain web redirection information:
>>> api.domain.webredir.list(apikey, 'mydomain.net')
>>> api.domain.webredir.count(apikey, 'mydomain.net')
>>> api.domain.webredir.info(apikey, 'mydomain.net')
<?php
$domain_webredir_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.webredir.'));
$domain_webredir_api->list($apikey, 'mydomain.net');
$domain_webredir_api->count($apikey, 'mydomain.net');
$domain_webredir_api->info($apikey, 'mydomain.net');
?>
> api.methodCall('domain.webredir.list', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.webredir.count', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.webredir.info', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.webredir.list', $apikey, 'mydomain.net' );
$api->call( 'domain.webredir.count', $apikey, 'mydomain.net' );
$api->call( 'domain.webredir.info', $apikey, 'mydomain.net' );
server.call("domain.webredir.list", apikey, 'mydomain.net')
server.call("domain.webredir.count", apikey, 'mydomain.net')
server.call("domain.webredir.info", apikey, 'mydomain.net')
Getting domain mailbox information:
>>> api.domain.mailbox.list(apikey, 'mydomain.net')
[{'login': 'admin'}]
>>> api.domain.mailbox.count(apikey, 'mydomain.net')
1
>>> api.domain.mailbox.info(apikey, 'mydomain.net', 'admin')
<?php
$domain_mailbox_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.mailbox.'));
$domain_mailbox_api->list($apikey, 'mydomain.net');
/*
Array ( [login] => 'admin' )
*/
$domain_mailbox_api->count($apikey, 'mydomain.net');
/*
1
*/
$domain_mailbox_api->info($apikey, 'mydomain.net');
?>
> api.methodCall('domain.mailbox.list', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
[{'login': 'admin'}]
> api.methodCall('domain.mailbox.count', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
1
> api.methodCall('domain.mailbox.info', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... }])
$api->call( 'api.domain.mailbox.list', $apikey, 'mydomain.net' );
[{'login' => 'admin'}]
$api->call( 'domain.mailbox.count', $apikey, 'mydomain.net' );
1
$api->call( 'domain.mailbox.info', $apikey, 'mydomain.net', 'admin' );
server.call("domain.mailbox.list", apikey, 'mydomain.net')
[{'login' => 'admin'}]
server.call("domain.mailbox.count", apikey, 'mydomain.net')
1
server.call("domain.mailbox.info", apikey, 'mydomain.net', 'admin')
Getting domain forwarding information:
>>> api.domain.forward.count(apikey, 'mydomain.net')
1
>>> api.domain.forward.list(apikey, 'mydomain.net')
[{'destinations': ['stephanie@example.com'], 'source': 'admin'}]
<?php
$domain_webredir_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.forward.'));
$domain_forward_api->count($apikey, 'mydomain.net');
//1
$domain_forward_api->list($apikey, 'mydomain.net');
/*
Array
(
Array
(
[destinations] => Array('stephanie@example.com')
[source] => 'admin'
)
)
*/
?>
> api.methodCall('domain.forward.count', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
1
> api.methodCall('api.domain.forward.list', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
[{destinations: ['stephanie@example.com'], source: 'admin'}]
my $result = $api->call( 'domain.forward.count', $apikey, 'mydomain.net' );
print $result;
1
$result = $api->call( 'domain.forward.list', $apikey, 'mydomain.net' );
print Data::Dumper->Dump( [$result] );
#[{'destinations' => ['stephanie@example.com'], 'source' => 'admin'}]
server.call("domain.forward.count", apikey, 'mydomain.net')
1
server.call("domain.forward.list", apikey, 'mydomain.net')
[{'destinations' => ['stephanie@example.com'], 'source' => 'admin'}]
Update a domain¶
The following attributes can be set/updated:
For each attribute you can perform the following actions.
Updating domain contacts:
>>> contacts_spec = {
... 'admin': 'FLN123-GANDI',
... 'tech': 'FLN123-GANDI',
... 'bill': 'FLN123-GANDI'}
>>> api.domain.contacts.set(apikey, 'mydomain.net', contacts_spec)
<?php
$domain_contacts_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.contacts.'));
contacts_spec = array(
'admin' => 'FLN123-GANDI',
'tech' => 'FLN123-GANDI',
'bill'=> 'FLN123-GANDI'
);
$domain_contacts_api->set($apikey, 'mydomain.net', $contacts_spec);
?>
> contacts_spec = {
... 'admin': 'FLN123-GANDI',
... 'tech': 'FLN123-GANDI',
... 'bill': 'FLN123-GANDI'}
> api.methodCall('domain.contacts.set',
... [apikey, 'mydomain.net', contacts_spec],
... function (error, value) {
... console.dir(value)
... })
my $contacts_spec = {
admin => 'FLN123-GANDI',
tech => 'FLN123-GANDI',
bill => 'FLN123-GANDI'
};
$api->call( 'domain.contacts.set', $apikey, 'mydomain.net', $contacts_spec);
contacts_spec = {
'admin' => 'FLN123-GANDI',
'tech' => 'FLN123-GANDI',
'bill' => 'FLN123-GANDI'}
server.call("domain.contacts.set", apikey, 'mydomain.net', contacts_spec)
(Un)Setting the lock transfer on your domain:
>>> api.domain.status.lock(apikey, 'mydomain.net')
>>> api.domain.status.unlock(apikey, 'mydomain.net')
<?php
$domain_status_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.status.'));
$domain_status_api->lock($apikey, 'mydomain.net');
$domain_status_api->unlock($apikey, 'mydomain.net');
?>
> api.methodCall('domain.status.lock', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.status.unlock', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.status.lock', $apikey, 'mydomain.net' );
$api->call( 'domain.status.unlock', $apikey, 'mydomain.net' );
server.call("domain.status.lock", apikey, 'mydomain.net')
server.call("domain.status.unlock", apikey, 'mydomain.net')
Updating the domain nameservers:
>>> api.domain.nameservers.set(apikey, 'mydomain.net', \
['a.dns.mydomain.net', 'b.dns.mydomain.net', 'c.dns.mydomain.net'])
<?php
$domain_nameservers_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.nameservers.'));
$domain_nameservers_api->set($apikey, 'mydomain.net',
array('a.dns.mydomain.net', 'b.dns.mydomain.net', 'c.dns.mydomain.net'));
?>
> api.methodCall('domain.nameservers.set', 'mydomain.net',
['a.dns.mydomain.net', 'b.dns.mydomain.net', 'c.dns.mydomain.net'])
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.nameservers.set', $apikey, 'mydomain.net',
['a.dns.mydomain.net', 'b.dns.mydomain.net', 'c.dns.mydomain.net'] );
server.call("domain.nameservers.set", apikey, 'mydomain.net',
['a.dns.mydomain.net', 'b.dns.mydomain.net', 'c.dns.mydomain.net'])
The following domain namespaces are available:
For each namespace, the create/delete/set/update methods are available.
Managing domain host:
>>> api.domain.host.create(apikey, 'dns1.mydomain.net', ['1.2.3.4'])
>>> api.domain.host.delete(apikey, 'dns1.mydomain.net')
$domain_host_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.host.'));
<?php
$domain_host_api->create($apikey, 'dns1.mydomain.net', array('1.2.3.4'));
$domain_host_api->delete($apikey, 'dns1.mydomain.net');
?>
> api.methodCall('domain.host.create', [apikey, 'dns1.mydomain.net',
... ['1.2.3.4']],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.host.delete', [apikey, 'dns1.mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.host.create', $apikey, 'dns1.mydomain.net', ['1.2.3.4'] );
$api->call( 'domain.host.delete', $apikey, 'dns1.mydomain.net' );
server.call("domain.host.create", apikey, 'dns1.mydomain.net', ['1.2.3.4'])
server.call("domain.host.delete", apikey, 'dns1.mydomain.net')
Managing domain web redirections. For example, redirecting your domain only to www:
>>> webredir_specs = {
... 'host': '',
... 'url': "http://www.mydomain.net"}
>>> api.domain.webredir.create(apikey, "mydomain.net", webredir_specs)
{'host': '',
'url': 'http://www.mydomain.net',
'type': 'http302'}
<?php
webredir_specs = array(
'host' => '',
'url' => "http://www.mydomain.net"
);
print_r($domain_webredir_api->__call('create',
array($apikey, "mydomain.net", $webredir_specs)));
/*
Array
(
[host]: '',
[url]: 'http://www.mydomain.net',
[type]: 'http302'
)
*/
?>
> var webredir_specs = {
... 'host' : '',
... 'url' : "http://www.mydomain.net"}
... }
> api.methodCall('domain.webredir.create',
... [apikey,"mydomain.net", webredir_specs],
... function (error, value) {
... console.dir(value)
... })
{host: '',
url: 'http://www.mydomain.net',
type: 'http302'}
$webredir_specs = {
'host' => '',
'url' => "http://www.mydomain.net",
};
my $result = $api->call( 'domain.webredir.create', $apikey,
'mydomain.net', $webredir_specs );
print Data::Dumper->Dump( [$result] );
#$VAR1 = {'host' => '',
# 'url' => 'http://www.mydomain.net',
# 'type' => 'http302'
#};
webredir_specs = {
'host' => '',
'url' => "http://www.mydomain.net"
}
server.call("domain.webredir.create", apikey,
"mydomain.net",webredir_specs)
{'host' => '',
'url' => 'http://www.mydomain.net',
'type' => 'http302'}
Note
The type defaults to http302
if not specified
Managing domain mailboxes:
>>> api.domain.mailbox.create(apikey, 'mydomain.net', 'admin',
... {'password': 'xxxxxx'})
>>> api.domain.mailbox.alias.set(apikey, 'mydomain.net', 'admin', ['stephanie'])
>>> api.domain.mailbox.delete(apikey, 'mydomain.net', 'admin')
<?php
$domain_mailbox_api->__call('create', array($apikey, 'mydomain.net', 'admin',
... array('password' => 'xxxxxx')));
$domain_mailbox_api->mailbox.aliases.set($apikey, 'mydomain.net', 'admin',
... array('stephanie'));
$domain_mailbox_api->mailbox.delete($apikey, 'mydomain.net', 'admin');
?>
> api.methodCall('domain.mailbox.create', [apikey, 'mydomain.net',
... 'admin', {'password' : 'xxxxxx'}],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.mailbox.aliases.set',
... [apikey, 'mydomain.net', 'admin', ['stephanie']],
... function (error, value) {
... console.dir(value)
... })
> api.methodCall('domain.mailbox.aliases.delete',
... [apikey, 'mydomain.net', 'admin'],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.mailbox.create', $apikey, 'mydomain.net', 'admin',
{'password' : 'xxxxxx'} );
$api->call( 'domain.mailbox.aliases.set', $apikey, 'mydomain.net', 'admin',
['stephanie'] );
$api->call( 'domain.mailbox.delete', $apikey, 'mydomain.net', 'admin' );
server.call("domain.mailbox.create", apikey, 'mydomain.net', 'admin',
{'password' => 'xxxxxx'})
server.call("domain.mailbox.aliases.set", apikey, 'mydomain.net', 'admin',
['stephanie'])
server.call("domain.mailbox.delete", apikey, 'mydomain.net', 'admin')
Managing domain forwards:
>>> api.domain.forward.create(apikey, 'mydomain.net', 'admin',
... {'destinations': ['stephanie@example.com']})
{'destinations': ['stephanie@example.com'], 'source': 'admin'}
>>> api.domain.forward.update(apikey, 'mydomain.net', 'admin',
... {'destinations': ['stephanie@example.com', 'steph@example.com']})
{'destinations': ['stephanie@example.com', 'steph@example.com'], 'source': 'admin'}
>>> api.domain.forward.delete(apikey, 'mydomain.net', 'admin')
True
<?php
print_r($domain_forward_api->__call('create',
array($apikey, 'mydomain.net', 'admin',
array('destinations'=> array('stephanie@example.com')))));
/*
Array
(
[destinations] => Array ( 'stephanie@example.com' )
[source] => 'admin'
)
*/
print_r($domain_forward_api->update($apikey, 'mydomain.com', 'admin',
array('destinations'=> array('stephanie@example.com', 'steph@example.com'))));
/*
Array
(
[destinations] => Array( 'stephanie@example.com', 'steph@example.com'),
[source]: 'admin'
)
*/
print_r($domain_api->forward.delete($apikey, 'mydomain.com', 'admin'));
// true
?>
> api.methodCall('domain.forward.create', [apikey, 'mydomain.net', 'admin',
... {'destinations': ['stephanie@example.com']}],
... function (error, value) {
... console.dir(value)
... })
{destinations: ['stephanie@example.com'], source: 'admin'}
> api.methodCall('domain.forward.create', [apikey, 'mydomain.net', 'admin',
... {'destinations': ['stephanie@example.com', 'steph@example.com']}],
... function (error, value) {
... console.dir(value)
... })
{destinations: ['stephanie@example.com', 'steph@example.com'], source: 'admin'}
> api.methodCall('domain.forward.update', [ apikey, 'mydomain.net',
... ['admin', {destinations: ['stephanie@example.com', 'steph@example.com']}],
... function (error, value) {
... console.dir(value)
... })
{destinations: ['stephanie@example.com', 'steph@example.com'], source: 'toto'}
> api.methodCall('domain.forward.delete', [ apikey, 'mydomain.net', 'admin' ] )
True
$api->call( 'domain.forward.create', $apikey, 'mydomain.net', 'admin',
{'destinations' => ['stephanie@example.com']} );
{'destinations' => ['stephanie@example.com'], 'source' => 'admin'}
$result = $api->call( 'domain.forward.update', $apikey, 'mydomain.net',
'admin', {'destinations' => ['stephanie@example.com', 'steph@example.com']} );
{'destinations' => ['stephanie@example.com', 'steph@example.com'], 'source' => 'admin'}
$api->call( 'domain.available', $apikey, 'mydomain.net', 'admin' );
True
server.call("domain.forward.create", apikey, 'mydomain.net', 'admin',
{'destinations' => ['stephanie@example.com']})
{'destinations' => ['stephanie@example.com'], 'source': 'admin'}
server.call("domain.forward.update", apikey, 'mydomain.net', 'admin',
{'destinations' => ['stephanie@example.com', 'steph@example.com']})
{'destinations' => ['stephanie@example.com', 'steph@example.com'],
... 'source' => 'admin'}
server.call("domain.forward.delete", apikey, 'mydomain.net', 'admin')
True
This method allows to reset a domain authinfo code at the registry:
>>> api.domain.reset_authinfo(apikey, 'mydomain.net')
Domain Processing¶
Renew a domain¶
>>> renew_spec = {
... 'duration': 1,
... 'current_year': 2011}
>>> api.domain.renew(apikey, 'mydomain.net', renew_spec)
<?php
$renew_spec = array(
'duration'=> 1,
'current_year'=> 2011);
$domain_api->renew($apikey, 'mydomain.net', $renew_spec);
?>
> renew_spec = {
... 'duration': 1,
... 'current_year': 2011}
> api.methodCall('domain.renew', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$renew_spec = {
'duration' => 1,
'current_year' => 2011
};
$api->call( 'domain.renew', $apikey, 'mydomain.net', $renew_spec );
renew_spec = {
'duration' => 1,
'current_year' => 2011}
server.call("domain.renew", apikey, 'mydomain.net', renew_spec)
Note
The current_year parameter means the current expiration date of the domain.
Transfer a domain to Gandi¶
Transfer workflow¶
Check Transfer availability¶
In order to check if a domain is available for Transfer you may want to use the api.domain.transferin.available method.
The values this method returns can be quite different one from another when querying several domains and we will explain them here.
This method raises an Exception when it encounters specific cases which prevent a Transfer from occuring:
- transfer_availability_error if the command is called with a domain which TLD is - or will be soon - discontinued
- transfer_availability_eoi when the TLD is still in the Expression of Interest phase
- transfer_availability_error if the domain contains a SLD we do not support or does not exist (ie: gandi.org.com)
- transfer_availability_error if called with an IDN domain on a TLD which do not support IDN
- reserved_corporate if called by a User without a Corporate Account on a TLD requiring a Corporate Account
- domain_is_restorable if the domain is currently in the restore period
- transfer_prohibited if the API could query the registry and the statuses of the domain currently prevent any Transfer
When the API can not query the registry - for a variety of reasons - we have chosen to return True. You can then try to launch the transfer and see if it succeeds.
When the API manages to query the registry it will return a dictionnary with data about the domain, in this case you may be quite sure about the domain transferability.
Note
api.domain.transferin.available is not a method to validate the authinfo code. The only way to really validate an authinfo code is to start the transfer.
Proceed to a new Transfer¶
>>> transfer_spec = {
... 'owner': 'FLN123-GANDI',
... 'admin': 'FLN123-GANDI',
... 'tech': 'FLN123-GANDI',
... 'bill': 'FLN123-GANDI',
... 'nameservers': ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
... 'authinfo': 'xxx',
... 'duration': 1}
>>> api.domain.transferin.proceed(apikey, 'mydomain.net', transfer_spec)
<?php
$domain_transferin_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.transferin.'));
$transfer_spec = array(
'owner' => 'FLN123-GANDI',
'admin' => 'FLN123-GANDI',
'tech' => 'FLN123-GANDI',
'bill' => 'FLN123-GANDI',
'nameservers' => array('a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'),
'authinfo' => 'xxx',
'duration' => 1)
$domain_transferin_api->proceed($apikey, 'mydomain.net', transfer_spec);
?>
> var transfer_spec = {
> owner: 'FLN123-GANDI',
> admin: 'FLN123-GANDI',
> tech: 'FLN123-GANDI',
> bill: 'FLN123-GANDI',
> nameservers: ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
> authinfo: 'xxx',
> duration: 1}
> api.methodCall('domain.transferin.proceed', [apikey, 'mydomain.net',
... transfer_spec],
... function (error, value) {
... console.dir(value)
... })
$transfer_spec = {
owner => 'FLN123-GANDI',
admin => 'FLN123-GANDI',
tech => 'FLN123-GANDI',
bill => 'FLN123-GANDI',
nameservers => ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
authinfo => 'xxx',
duration => 1
};
$api->call( 'domain.transferin.proceed', $apikey, 'mydomain.net', $transfer_spec );
transfer_spec = {
'owner' => 'FLN123-GANDI',
'admin' => 'FLN123-GANDI',
'tech' => 'FLN123-GANDI',
'bill' => 'FLN123-GANDI',
'nameservers' => ['a.dns.gandi.net', 'b.dns.gandi.net', 'c.dns.gandi.net'],
'authinfo' => 'xxx',
'duration' => 1}
server.call("domain.transferin.proceed", apikey, 'mydomain.net', transfer_spec)
Send Transfer confirmation mails again¶
If you have requested a Transfer but see that the email address to which the confirmation email has been sent is wrong, for example the owner of a non-GTLD domain has an expired email address declared on the WHOIS record, you will be able to restart a domain transfer operation once the WHOIS records have been updated by calling the domain.transferin.resend_foa API method.
>>> api.domain.transferin.resend_foa(apikey, 'mydomain.net')
Note
Due to registry limitations, you can create a transfer operation in OTE, but the command will fail at the registry.
Update a bad authinfo code¶
Let’s say that you made an error when entering the authinfo code of a Transfer operation and that the Transfer was rejected by the registrar. You can call this method to update the authinfo and restart the Transfer by calling the domain.transferin.update_authinfo API method.
>>> api.domain.transferin.update_authinfo(apikey, 'mydomain.net', 'new_auth')
Note
This method will restart and update the latest Transfer operation in error for the given domain with your handle as source of the operation.
Restore a domain¶
>>> restore_spec = {
... 'duration': 1}
>>> api.domain.restore(apikey, 'mydomain.net', restore_spec)
<?php
$restore_spec = array(
'duration'=> 1);
$domain_api->restore($apikey, 'mydomain.net', $restore_spec);
?>
> restore_spec = {
... 'duration': 1}
> api.methodCall('domain.restore', [apikey, 'mydomain.net'],
... function (error, value) {
... console.dir(value)
... })
$restore_spec = {
'duration' => 1
};
$api->call( 'domain.restore', $apikey, 'mydomain.net', $restore_spec );
restore_spec = {
'duration' => 1}
server.call("domain.restore", apikey, 'mydomain.net', restore_spec)
Note
Due to registry limitations, you can create a restore operation in OTE, but the command will fail at the registry.
TLD¶
List all TLDs available in API¶
>>> api.domain.tld.list(apikey)
<?php
$domain_api = XML_RPC2_Client::create($api_uri, array('prefix' => 'domain.tld.'));
$domain_api->list($apikey);
?>
> api.methodCall('domain.tld.list', [apikey],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.tld.list', $apikey );
server.call("domain.tld.list", apikey)
List all TLDs by region, available in API¶
>>> api.domain.tld.region(apikey)
<?php
$domain_api = XML_RPC2_Client::create($api_uri,
array('prefix' => 'domain.tld.'));
$domain_api->region($apikey);
?>
> api.methodCall('domain.tld.region', [apikey],
... function (error, value) {
... console.dir(value)
... })
$api->call( 'domain.tld.region', $apikey );
server.call("domain.tld.region", apikey)
Domain price list¶
In order to get a more precise pricing of multiple fqdn and process, the domain.price.list()
method has been added. However this is an async method which can respond a pending availability, in which case you have to repeat the call until full result is ready. Here’s a sample python call and result :
>>> api.domain.price.list(api_key, {'tlds': ['testdomain.net'], 'action': ['create', 'renew']})
[{'available': 'pending', 'current_phase': 'golive', 'errors': [], 'extension': 'testdomain.net', 'idn_lang': True, 'name': 'net', 'phases': [{'date_end': None, 'date_start': <DateTime '19990521T00:00:00' at 7f0090110290>, 'date_start_gandi': <DateTime '19990521T00:00:00' at 7f00901102d8>,'phase': 'golive'}], 'prices': [], 'provided': False, 'region': 'generic', 'subdomains': [], 'visibility': 'all'}]
>>> api.domain.price.list(api_key, {'tlds': ['testdomain.net'], 'action': ['create', 'renew']})
[{'available': 'unavailable', 'provided': False, 'phases': [{'phase': 'golive', 'date_end': None, 'date_start': <DateTime '19990521T00:00:00' at 7f07a5e14ef0>, 'date_start_gandi': <DateTime '19990521T00:00:00' at 7f07a5e14fc8>}], 'errors': [], 'name': 'net', 'extension': 'testdomain.net', 'region': 'generic', 'visibility': 'all', 'subdomains': [], 'idn_lang': True, 'prices': [{'action': {'name': 'renew', 'param': {}}, 'product': {'type': 'domain', 'description': '.net'}, 'taxes': {'rate': 17.0, 'type': 'service', 'name': 'vat'}, 'unit_price': [{'max_duration': 9, 'special_op': False, 'duration_unit': 'y', 'price': 17.0, 'price_type': None, 'min_duration': 1, 'currency': 'EUR', 'grid': 'A', 'id': 655514}]}], 'current_phase': 'golive'}]