by Martin J Levy.

Using the CloudFlare API via Python

Very early on in the company’s history we decided that everything that CloudFlare does on behalf of its customer-base should be controllable via an API. In fact, when you login to the CloudFlare control panel, you’re really just making API calls to our backend services. Over time that API has matured and improved. We are now on v4 of that API.

The current CloudFlare API is documented here and it’s used by both the CloudFlare control panel and directly by umpteen customers every minute of every day. The new API is designed with a clean naming structure and consistent data representation for data. It’s also extensible.

This blog entry introduces python-cloudflare, a Python wrapper providing full access to the CloudFlare v4 API.

An example

Let’s get right into the thick-of-it with the simplest coding example available to show python-cloudflare in action. This example lists all your domains (zones) and also checks some basic features for each zone.

#!/usr/bin/env python
import CloudFlare
def main():
    cf = CloudFlare.CloudFlare()
    zones = cf.zones.get(params={'per_page':50})
    for zone in zones:
        zone_name = zone['name']
        zone_id = zone['id']
        settings_ipv6 = cf.zones.settings.ipv6.get(zone_id)
        ipv6_on = settings_ipv6['value']
        print zone_id, ipv6_on, zone_name
if __name__ == '__main__':

The structure of the CloudFlare class matches the API documentation. The CloudFlare.zones.get() method returns information about the zones as per the list zones documentation. The same for CloudFlare.zones.settings.ipv6.get() and its documentation.

Data is passed into the methods via standard Python structures and they are returned in Python structures that match the API documentation. That means if you see an API call in the documentation, then you can translate it into the Python code in a one-to-one manner.

For example, take a look at the WAF list rules API call.


This codes into method with the zone_id as the first argument, the package_id as the second argument and the optional parameters passed last (or if there aren’t any; then just drop the third argument for the call). Because this is a GET call there’s a .get() as part of the method name.

    r = cf.zones.firewall.waf.packages.rules.get(zone_id, package_id, params=params)

Here’s the much simpler Create DNS record API call.


This would be coded into the Python method with the zone_id as the first argument and the required parameters passed as data. Because this is a POST call there’s a .post() as part of the method name.

    r =, data=dns_record)

Here’s an example of that Create DNS record call in action. In this code, we add two records to an existing zone. We also show how the error is handled (in classic Python style).

    zone_name = ''
        r = cf.zones.get(params={'name': zone_name})
    except CloudFlare.CloudFlareAPIError as e:
        exit('/zones.get %s - %d %s' % (zone_name, e, e))
    except Exception as e:
        exit('/zones.get %s - %s' % (zone_name, e))
   zone_id = r['id']
   # DNS records to create
    dns_records = [
        {'name':'foo', 'type':'A',    'content':''}
        {'name':'foo', 'type':'AAAA', 'content':'2001:d8b::100:100'},
    for dns_record in dns_records:
            r =, data=dns_record)
        except CloudFlare.CloudFlareAPIError as e:
            exit('/ %s - %d %s' % (record['name'], e, e))

There’s a whole folder of example code available on the GitHub repository.

All on GitHub for anyone to use

As we stated above (and as CloudFlare has done many times before) we have placed this code up on GitHub for anyone to download and use. We welcome contributions and will review any pull requests. To install it, just clone it and follow the README instructions. For those that just want to get going right now; here’s the tl;dr install:

$ git clone
$ cd python-cloudflare
$ ./ build
$ sudo ./ install

But wait; there’s more!

Not only do you get the python API calls, you also get a fully functioning CLI (command line interface) that allows quick creation of scripts that interface with CloudFlare.

From the CLI command you can call any of the CloudFlare API calls. The command responds with the returned JSON data. If you want to filter the results you possibly also want to install the highly-versatile jq command. Here’s a command to check the nameservers for a specific domain hosted on CloudFlare and then process it via jq.

$ cli4 /zones | jq -c '.[]|{"name_servers":.name_servers}'

The CLI command will convert on-the-fly zone names into zone identifiers. For example; if you want to check the DNSSEC status on a zone your operate on CloudFlare; then use this command.

$ cli4 /zones/ | jq '{"status":.status,"ds":.ds}'
  "status": "active",
  "ds": " 3600 IN DS 2371 13 2 00000000000000000000000000000 ..."

You can issue GET PUT POST PATCH or DELETE calls into the API. You can pass data into a CloudFlare API call with the CLI command. All documented via the and wiki examples in GitHub.

Here’s a useful command for customers that need to flush their cache files.

$ cli4 --delete purge_everything=true /zones/

See how the commands arguments match the purge_cache API documentation.


Finally, here’s an example of turning on DNSSEC via the API.

$ cli4 --patch status=active /zones/ | jq -c '{"status":.status}'

There are plenty more examples available within the GitHub repo.

CloudFlare API via other languages also available

Python isn’t the only language you can use to interact with CloudFlare’s API. If you’re a Go, or Node.js user, we also have client libraries you can use to interact with CloudFlare on our GitHub. Find them here Go client and here Node.js client. Want to write something in a different language? Feel free to do that. The API spec is online and ready for you to code up.

If you like what you read here today and are interested in joining one of CloudFlare’s software teams, then checkout our Join Our Team page.

Tagged with API
comments powered by Disqus