Cache Invalidation
Storyblok uses a Content Delivery Network (CDN) before the API to deliver your content as fast as possible. To have a high cache hit rate for published content, Storyblok appends a parameter called cv
, which stands for "cache version." This parameter is an integer that represents a Unix timestamp.
The most up-to-date cv
value of a space can be retrieved with an API call excluding the cv
parameter:
https://api.storyblok.com/v2/cdn/spaces/me/?token=YOUR_TOKEN
While any API endpoint can be used, it is recommended to use /v2/cdn/spaces/me/
for performance purposes (see Retrieve Current Space for further reference).
The API response will contain a cv
value that can be used in subsequent API requests to receive the latest version of the content. In order to handle cache invalidation, the cv
value needs to be stored in memory. Furthermore, it needs to be updated when certain criteria are met. For example, Storyblok's webhook events may be used to invalidate the cache whenever content is published, updated, or deleted.
When using one of the official Storyblok SDKs (which are based on the storyblok-js-client), cache invalidation is handled automatically.
Related Resources
Examples
curl "https://api.storyblok.com/v2/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// Using the Universal JavaScript Client:
// https://github.com/storyblok/storyblok-js-client
Storyblok.get('cdn/spaces/me', {})
.then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
$client = new \Storyblok\Client('YOUR_STORYBLOK_SPACE_ACCESS_TOKEN');
$client->get('/v1/spaces/me')->getBody();
require 'storyblok'
client = Storyblok::Client.new(oauth_token: 'YOUR_OAUTH_TOKEN')
client.space()
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v2/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt")
.asString();
var client = new RestClient("https://api.storyblok.com/v2/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation
let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v2/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.method = "GET"
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
import requests
url = "https://api.storyblok.com/v2/cdn/spaces/me"
querystring = {"token":"wANpEQEsMYGOwLxwXQ76Ggtt"}
payload = ""
headers = {}
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
print(response.text)
{
"space": {
"id": 123456,
"name": "Example Space",
"domain": "https://storyblok.com/",
"version": 1706094649
}
}
Use the cv attribute value as cv parameter for the subsequent requests:
curl "https://api.storyblok.com/v2/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// Using the Universal JavaScript Client:
// https://github.com/storyblok/storyblok-js-client
Storyblok.get('cdn/stories', {
"cv": "1541863983"
})
.then(response => {
console.log(response)
}).catch(error => {
console.log(error)
})
$client = new \Storyblok\Client('YOUR_STORYBLOK_SPACE_ACCESS_TOKEN');
$client->getStories([
"cv" => "1541863983"
])->getBody();
require 'storyblok'
client = Storyblok::Client.new(oauth_token: 'YOUR_OAUTH_TOKEN')
client.stories({:params => {
"cv" => "1541863983"
}})
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v2/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt")
.asString();
var client = new RestClient("https://api.storyblok.com/v2/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation
let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v2/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt")! as URL, cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.method = "GET"
let session = URLSession.shared
let dataTask = session.dataTask(with: request as URLRequest, completionHandler: { (data, response, error) -> Void in
if (error != nil) {
print(error)
} else {
let httpResponse = response as? HTTPURLResponse
print(httpResponse)
}
})
dataTask.resume()
import requests
url = "https://api.storyblok.com/v2/cdn/stories"
querystring = {"cv":"1541863983","token":"wANpEQEsMYGOwLxwXQ76Ggtt"}
payload = ""
headers = {}
response = requests.request("GET", url, data=payload, headers=headers, params=querystring)
print(response.text)