Cloudflare API: getting started
Cloudflare have been around for a few years now. If you managed a domain, they provide a number of useful services such as DDoS protection and DNS management. Most of the services offered by Cloudflare can be accessed via a RESTful API.
Getting your API key
Once you've created an account, you can access your API key from the Cloudflare website. Go to the "My Settings" page, find the API key section and view your "Global API Key":
Key security
Anyone who has your API key can authenticate with Cloudflare. As a result you
should treat it like a password and keep it private! The examples in this post
assume the API key is being stored in a file called cloudflare-key
, note the
file is not world readable:
[alice@example ~]$ ls -l cloudflare-key
-rw-------. 1 alice alice 38 Nov 8 23:01 cloudflare-key
Making requests
All of the examples in this post use curl to make HTTP requests. This matches the Cloudflare documentation, however you could obviously use any HTTP tool or library when making API calls.
Zones
Most of the available API calls require a valid zone ID. You can get a zone ID using the list zones API call:
curl -s -X GET \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: $(cat cloudflare-key)" \
-H "Content-Type: application/json" \
https://api.cloudflare.com/client/v4/zones?name=example.com
The API should return a JSON document with the zone details, including the zone ID:
{
"errors": [],
"messages": [],
"result": [
{
"created_on": "2016-11-03T20:54:45.153731Z",
"development_mode": 0,
"id": "2aae6c35c94fcfb415dbe95f408b9ce9",
"meta": {
...
Note: passing the document through python -m json.tool
, should make the
response a little easier to read:
List records in a zone
Once you've got a zone ID, you can list all DNS records in the zone using the List DNS Records API call:
curl -s -X GET \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: $(cat cloudflare-key)" \
-H "Content-Type: application/json" \
https://api.cloudflare.com/client/v4/zones/2aae6c35c94fcfb415dbe95f408b9ce9/dns_records/
This should give output similar to the following:
{
"errors": [],
"messages": [],
"result": [
{
"content": "203.0.113.119",
"created_on": "2016-11-03T20:56:45.263431Z",
"id": "000bf354c14977ce5d30fbe238359b96",
"locked": false,
"meta": {
"auto_added": false
},
"modified_on": "2016-11-03T20:56:45.263431Z",
"name": "f-o.example.com",
"proxiable": true,
"proxied": false,
"ttl": 1,
"type": "A",
"zone_id": "2aae6c35c94fcfb415dbe95f408b9ce9",
"zone_name": "example.com"
},
...
You can also limit results to specific names or record types using a query string. For example:
curl -s -X GET \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: $(cat cloudflare-key)" \
-H "Content-Type: application/json" \
https://api.cloudflare.com/client/v4/zones/2aae6c35c94fcfb415dbe95f408b9ce9/dns_records/?type=A
Updating records
There is also an API call for updating DNS
records. Unlike the previous calls, this API uses
the http PUT
method, and requires a request body. This can be provided with
the --date
option:
curl -s -X PUT \
-H "X-Auth-Email: [email protected]" \
-H "X-Auth-Key: $(cat cloudflare-key)" \
-H "Content-Type: application/json" \
https://api.cloudflare.com/client/v4/zones/2aae6c35c94fcfb415dbe95f408b9ce9/dns_records/000bf354c14977ce5d30fbe238359b96 \
--data '{ "content": "203.0.113.120", "id": "000bf354c14977ce5d30fbe238359b96", "locked": false, "meta": {"auto_added": false }, "name": "f-o.example.com", "proxiable":true, "proxied": false, "ttl": 1, "type": "A"}'
If everything is successful the response should look something like the following:
{
"errors": [],
"messages": [],
"result": {
"content": "203.0.113.119",
"created_on": "2016-11-03T20:56:45.263431Z",
"id": "000bf354c14977ce5d30fbe238359b96",
"locked": false,
"meta": {
"auto_added": false
},
"created_on": "2016-11-04T19:58:43.323478Z",
"name": "f-o.example.com",
"proxiable": true,
"proxied": false,
"ttl": 1,
"type": "A",
"zone_id": "2aae6c35c94fcfb415dbe95f408b9ce9",
"zone_name": "example.com"
},
"success": true
}
Note: the example given in the Cloudflare
documentation uses all available record attributes
in the JSON request body. However you can currently get away with only
specifying the content
, name
and type
attributes.