Scripting with the NameCheap API

I manage a large number of domains that are registered through NameCheap. I’ve mentioned before that I’m a big fan of NameCheap. They have the best registration prices, a clean easy interface, and their support is always helpful. But recently I felt like I needed to put some better controls in place to manage and monitor my domain renewals. What I wanted was a Python script that would run daily, check all my domain expirations, and post any alerts or warning to a Slack channel. After poking around NameCheap’s website for a few minutes I found that they expose an API for customers to use. Perfect, I could now start scripting with the NameCheap API.

Setting up the NameCheap API

NameCheap-API-1Before I could do any scripting I need to enable the API in my account. Login to your NameCheap account, from the left hand navigation select Tools from under Profile. On the Tools page scroll to the bottom and find NameCheap API Access, click Manage. On this page you need to change the API Access to On. NameCheap Support will have to manually approve your request. The request should take 1 – 2 days. I ended up waiting about a week, then I contact Support and they expedited the request for me. Once your request is approved you need to complete 2 things in the NameCheap API Access page.

API Key – Generate an API Key, you’ll need this later in your script.

Whitelisted IPs – You need to add all of the IP addresses that will be accessing the API. I added two of my servers where I will run the script, and my laptop’s Internet IP address.

NameCheap API AccessAccessing the NameCheap API

Now that you’ve whitelisted your IP addresses and created an API key, you’re ready to start to start accessing the API. NameCheap has full documentation on their API available, so that’s a good place to start. NameCheap’s API gives you access to do almost everything you can do from their website. A lot of customers use this to create custom scripts and tools for registering and managing domains. Another consideration of this API is that it returns responses in an XML format. I would have prefered JSON, but I’ll discuss that below.

NameCheap Sandbox

One important thing to consider, if you’re going to be creating complex scripts or registering domains with your script, NameCheap has a Sandbox environment for testing your scripts against. Use this environment instead of testing your scripts against their production environment. Just register for an account in their Sandbox environment and use it in place of your production credentials.

API Requests

The API requests basically look like this:

https://api.namecheap.com/xml.response?ApiUser=apiexample&ApiKey=56b4c87ef4fd49cb96d915c0db68194&UserName=apiexample&Command=namecheap.domains.getList&ClientIp=192.168.1.109

ParameterExampleDescription
Service URLhttps://api.namecheap.com/xml.response?The base API service address.
ApiUserApiUser=apiexampleThis is your NameCheap username. This is your NameCheap username.
ApiKeyApiKey=56b4c87ef4fd49cb96d915c0db68194This is your API Key that you created earlier.
UserNameUserName=apiexampleSame as ApiUser, this is your NameCheap username.
Commandnamecheap.domains.getListThis is the API Method you are invoking. All of the available Methods are listed in the NameCheap Documentation.
ClientIpClientIp=192.168.1.109This is the IP address of the client that is making the request, your server’s IP address.

NameCheap Python Scripting

As I mentioned earlier I want a script that will run weekly, iterate through all of my domains and flag any that have an expiration coming up. I’ll then post a message in my Slack channel to notify me. NameCheap’s getList command will pull all my domains with their expiration dates, so that will cover my requirement. I’m going to use the Slack module I wrote about in an earlier article to handle the Slack integration.

As I mentioned earlier, the API response is in XML. While I was researching this I stumbled on a GitHub project for a Python client to the NameCheap API. The PyNamecheap project by Bemmu is pretty nice Python class that handles all the necessary XML parsing. So if you’re planning to use Python, there’s no need to reinvent the wheel here. I Imported the PyNamecheap Api class into my script.

To pull back a list of my domains I used the following code:

from namecheap import Api, ApiError

CLIENT_IP = "127.0.0.1"
NAME_CHEAP_USER = "user123"
NAME_CHEAP_KEY = "785443xxxxxxxxxxxx39d00351e"

api = Api(NAME_CHEAP_USER, NAME_CHEAP_KEY, NAME_CHEAP_USER, CLIENT_IP, sandbox = False, debug = False)

domainlist = api.domains_getList()

api.domains_getList() will return an iterable of dictionary objects. Each domain will have a dictionary object, and that object will contain the domain properties. To interrogate each domain, I can use the following code:

for k in domainlist:
    print "Domain: ", k['Name']
    print "Expiration: ", k['Expires']

I can then look at each expiration date and create a Slack message. After setting up cron job to run weekly, I now can get a weekly update on upcoming expirations.

My NameCheap Monitoring Script

import os
import json
import requests
import subprocess
import sys
import socket
import xml.etree.ElementTree as ET
import time
import datetime


print "Starting Domain Management Script on %s" % socket.gethostname()

#######    Header     ########################################################### 
sys.path.append('/opt/agcloud/scripts/modules')

from slack import slacktest, slack_message
from namecheap import Api, ApiError
from datetime import date

TODAY = date.today()
CLIENT_IP = "127.0.0.1"
NAME_CHEAP_USER = "user123"
NAME_CHEAP_KEY = "785443xxxxxxxxxxxx39d00351e"
OK_COUNT = 0
WARN_COUNT = 0
CRITICAL_COUNT = 0
MESSAGE = "------ Domain Report ------ \n"

##################################################################################


api = Api(NAME_CHEAP_USER, NAME_CHEAP_KEY, NAME_CHEAP_USER, CLIENT_IP, sandbox = False, debug = False)
domainlist = api.domains_getList()

for k in domainlist:
    print "Domain: ", k['Name']
    expire_date = datetime.datetime.strptime(k['Expires'], '%m/%d/%Y').date()
    days_to_expire = abs(expire_date - TODAY)
    print "Days until expire: ", days_to_expire.days
    
    if days_to_expire.days < 110:
    CRITICAL_COUNT += 1
    MESSAGE = MESSAGE + k['Name'] + " is expiring on " + str(expire_date) + "\n"
    else:
  if days_to_expire.days < 250:
    WARN_COUNT += 1
  else:
    OK_COUNT += 1

    print "---------------------"

MESSAGE = MESSAGE + "Domains Expiring in more than 250 days: " + str(OK_COUNT) + "\n"
MESSAGE = MESSAGE + "Domains Expiring in less than 250 days: " + str(WARN_COUNT) + "\n"
MESSAGE = MESSAGE + "Domains Expiring in less than 110 days: " + str(CRITICAL_COUNT) + "\n"
MESSAGE = MESSAGE + "----------------------------------"

print MESSAGE

slack_message("#platform", MESSAGE)

print "Ending Domain Management Script on %s" % socket.gethostname()

 

I’m an avid Technologist, while I do work on architecting solutions that span from the desktop to the data center, my passion is Web Infrastructure.
We will be happy to hear your thoughts

      Leave a reply