Cloudflare API purge cache by URL example

Cloudflare API purge cache by URL example banner

Cloudflare is a great free tool that offers static asset caching out of the box. You can also cache dynamic pages with it, which is quite handy.

Caching things is nice, but invalidating the cache is not a fun business. 

There is this popular quote:

There are only two hard things in Computer Science: cache invalidation and naming things.
-- Phil Karlton

I've done a little experiment with Cloudflare. I've configured caching in my blog. The post you are reading right now is cached in CF, currently with a TTL (Time to live) of 1 day.

After configuring the cache, a question immediately arose in my mind. If I update an article I'll need to wait for the cache to expire before the modifications become visible to the public, which is not ideal. I want immediate updates, but then I also want caching

So what is the solution? Simple - invalidate the cache each time the blog post is updated. Thankfully, Cloudflare offers free API, which allows you to do just that - purge cached content by URL. The documentation is not quite clear, and the method I've used is not documented 🤔, but it works, trust me.

What is Purge Cache in CloudFlare?

Cache purge in Cloudflare is a process used to remove specific cached content from Cloudflare's servers before its natural expiration time.

Cache purging using the Cloudflare web interface

To access the Purge Cache functionally, navigate to your CloudFlare Dashboard -> Select your website -> Caching -> Configuration.

The page should look something like this:

cloudflare caching menu

Now, you have two options here.

  1. Custom purge
    Which on the Free and Pro plan offers purge by URL only. The other methods are reserved for Enterprise users (currently $200/mo).
    cloudflare custom purge modal
  2. Purge everything - which clears all cache, including static files.

    I would avoid this functionality since purging everything would mean that your webserver will need to serve the previously cached content again.

Purge cache by URL using Cloudflare API

As I mentioned before, Cloudflare offers APIs for almost everything, including controlling your cache.

To use the API, you'll need to get the endpoint, which you can find under the Purge Cache section. Click on the API button near Help.

Cloudflare zone API endpoint

Then, you need to generate credentials to use this endpoint. I would suggest using the Bearer Auth method, which is the easiest to setup. To create a Bearer Auth navigate to Profile (upper right) -> API Tokens -> Create new Token -> Create Custom token (on the bottom)

  1. Fill token name
  2. In the permissions section choose -> Zone -> Cache Purge -> Purge
  3. In the zone resources section choose -> Include -> Specific zone -> your website
  4. If you want to can add Client IP address filtering and expiration date, but I left mine empty.

create bearer auth token for cloudflare cache purge API

Then after your token is created you'll get your Bearer token and curl command to test it.

curl -X GET "https://api.cloudflare.com/client/v4/user/tokens/verify" \
     -H "Authorization: Bearer xxxxxxxx" \
     -H "Content-Type:application/json"

which should output

{
  "result": {
    "id": "xxxxxx",
    "status": "active"
  },
  "success": true,
  "errors": [],
  "messages": [
    {
      "code": 10000,
      "message": "This API Token is valid and active",
      "type": null
    }
  ]
}

Good job! We are now ready to purge our cache via the API.

Cloudflare API cache purge by URL example

Here is a curl example for cache purging using the API.

curl --request POST \
  --url https://api.cloudflare.com/client/v4/zones/__identifier_here__/purge_cache \
  --header "Authorization: Bearer __bearer_token_here__" \
  --header 'Content-Type: application/json' \
  --data '{
  "files": [
    "https://yarnaudov.com/cloudflare-api-purge-cache-by-url-example.html"
  ]
}'

and if everything is correct (token, identifier and URL) you should get

{"success":true,"errors":[],"messages":[],"result":{"id":"xxxxxxxx"}}

Here are some more examples of different languages.

PHP curl

<?php

$curl = curl_init();

curl_setopt_array($curl, array(
  CURLOPT_URL => 'https://api.cloudflare.com/client/v4/zones/xxxxxx/purge_cache',
  CURLOPT_RETURNTRANSFER => true,
  CURLOPT_ENCODING => '',
  CURLOPT_MAXREDIRS => 10,
  CURLOPT_TIMEOUT => 0,
  CURLOPT_FOLLOWLOCATION => true,
  CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
  CURLOPT_CUSTOMREQUEST => 'POST',
  CURLOPT_POSTFIELDS =>'{
    "files": [
        "https://yarnaudov.com/cloudflare-api-purge-cache-by-url-example.html"
    ]
}',
  CURLOPT_HTTPHEADER => array(
    'Content-Type: application/json',
    'Authorization: Bearer xxxxx'
  ),
));

$response = curl_exec($curl);

curl_close($curl);
echo $response;

Node Axios

const axios = require('axios');
let data = JSON.stringify({
  "files": [
    "https://yarnaudov.com/cloudflare-api-purge-cache-by-url-example.html"
  ]
});

let config = {
  method: 'post',
  maxBodyLength: Infinity,
  url: 'https://api.cloudflare.com/client/v4/zones/xxxx/purge_cache',
  headers: { 
    'Content-Type': 'application/json', 
    'Authorization': 'Bearer xxx'
  },
  data : data
};

axios.request(config)
.then((response) => {
  console.log(JSON.stringify(response.data));
})
.catch((error) => {
  console.log(error);
});

Golang

package main

import (
  "fmt"
  "strings"
  "net/http"
  "io/ioutil"
)

func main() {

  url := "https://api.cloudflare.com/client/v4/zones/xxxx/purge_cache"
  method := "POST"

  payload := strings.NewReader(`{
    "files": [
        "https://yarnaudov.com/cloudflare-api-purge-cache-by-url-example.html"
    ]
}`)

  client := &http.Client {
  }
  req, err := http.NewRequest(method, url, payload)

  if err != nil {
    fmt.Println(err)
    return
  }
  req.Header.Add("Content-Type", "application/json")
  req.Header.Add("Authorization", "Bearer xxx")

  res, err := client.Do(req)
  if err != nil {
    fmt.Println(err)
    return
  }
  defer res.Body.Close()

  body, err := ioutil.ReadAll(res.Body)
  if err != nil {
    fmt.Println(err)
    return
  }
  fmt.Println(string(body))
}

Python

import http.client
import json

conn = http.client.HTTPSConnection("api.cloudflare.com")
payload = json.dumps({
  "files": [
    "https://yarnaudov.com/cloudflare-api-purge-cache-by-url-example.html"
  ]
})
headers = {
  'Content-Type': 'application/json',
  'Authorization': 'Bearer xxxxx'
}
conn.request("POST", "/client/v4/zones/xxxx/purge_cache", payload, headers)
res = conn.getresponse()
data = res.read()
print(data.decode("utf-8"))

Note that these examples are copied directly from Postman code generator. They are not so elegant, but they will work.

And that's it! Now you know how to purge cache via the API.