Skip to main content

Content Delivery API Reference

The Storyblok Content Delivery API is organized around REST. Our API has predictable, resource-oriented URLs, and uses HTTP response codes to indicate API errors. We use built-in HTTP features, like HTTP query parameters and HTTP verbs, which are understood by off-the-shelf HTTP clients. We support cross-origin resource sharing, allowing you to interact securely with our API from a client-side web application (though you should never expose your secret API key in any public website's client-side code, tokens found on the dashboard however are read only and therefore fine to use in a client-side code). JSON is returned by all API responses, including errors, although our API libraries convert responses to appropriate language-specific objects.

To make the API as explorable as possible, accounts have draft versions and published version of API tokens. To access the draft version of your content you can use the preview token, and for receiving published content you can use the public token. The preview token is able to also load the published content. To switch between those versions you can append the query parameter version=draft/published and using the appropriate token to perform a draft or published version call.

The requests in the right sidebar are designed to work as is. The sample requests are performed using a preview API token of a test space with demo content.

Edit this section on GitHub

API Libraries

Official libraries for the Storyblok Content Delivery API are available in several languages. Community-supported libraries are also available for additional languages.

Base URL

https://api.storyblok.com

Authentication

Authenticate your account by including your access token in API requests. You can manage your API tokens in the Dashboard of each space. In your Space Dashboard at app.storyblok.com you will be able to generate two types of tokens

  • Public: Allows access to your published content entries: version=published
  • Preview: Allows access to the draft and published content entries: version=draft and version=published

Public and Preview tokens are read only and do not allow you or others to write or delete entries in your space. The public token can be published. All tokens can be revoked at any point of time, you are able to create multiple tokens of the same type to grant access for specific use-cases. For CRUD operations you can have a look at the Management API documentation.

If you're using the Content Staging (eg. Release and Schedule) feature you can also create Public and Preview tokens for each staging environment.

Edit this section on GitHub

Example Request

// npm install storyblok-js-client
const StoryblokClient = require('storyblok-js-client')

// init with access token
const Storyblok = new StoryblokClient({
  accessToken: 'wANpEQEsMYGOwLxwXQ76Ggtt',
  cache: {
    clear: 'auto',
    type: 'memory'
  }
})

or use directly as parameter

curl "https://api.storyblok.com/v1/cdn/stories?token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "token": "wANpEQEsMYGOwLxwXQ76Ggtt"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories();
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?token=wANpEQEsMYGOwLxwXQ76Ggtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?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/v1/cdn/stories?token=wANpEQEsMYGOwLxwXQ76Ggtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"token":"wANpEQEsMYGOwLxwXQ76Ggtt"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

To perform a GET request with your token append the query parameter token with your preview or public token as shown in the example above.

Errors

Storyblok uses conventional HTTP response codes to indicate the success or failure of an API request. In general: Codes in the 2xx range indicate success. Codes in the 4xx range indicate an error that failed given the information provided (e.g., a required parameter was omitted, a charge failed, content entry was not published but version requested was set to published, etc.). Codes in the 5xx range indicate an error with Storyblok's servers (these are rare).

Some 4xx errors that could be handled programmatically (e.g., content entry was not found) include an error code that briefly explains the error reported.

Edit this section on GitHub

Http Status Code Summary

Code Description
200 - OK Everything worked as expected.
400 - Bad Request Wrong format was sent (eg. XML instead of JSON).
401 - Unauthorized No valid API key provided.
404 - Not Found The requested resource doesn't exist (perhaps due to not yet published content entries).
422 - Unprocessable Entity The request was unacceptable, often due to missing a required parameter.
429 - Too Many Requests Too many requests hit the API too quickly. We recommend an exponential backoff of your requests.
500, 502, 503, 504 - Server Errors Something went wrong on Storyblok's end. (These are rare.)

Rate Limit

The content delivery api has a rate limit of 50 requests per second for uncached request. The limit decreases if you use a higher page size than 25.

Edit this section on GitHub
Type of request Rate Limit
Cached requests from the CDN > 1000 per second
Single content item, datasources, ... 50 per second
Listings with page size below and with 25 50 per second
Listings with page size between 25 and 50 15 per second
Listings with page size between 50 and 75 10 per second
Listings with page size between 75 and 100 5 per second

Cache Invalidation

Storyblok uses a CDN in front of the API to deliver your content in the fastest way possible. If you're using the Storyblok Content Delivery API directly in your client application it is recommended to use a backend version number or the versions parameter provided by the /v1/cdn/spaces/me?token=access_token call.

  1. Request the resource /v1/cdn/spaces/me to get the space.version property
  2. Append the space.version to all your subsequent calls of the endpoint /v1/cdn/stories
  1. Generate a timestamp (once on a server, not on every request/client load)
  2. Append your timestmap to all your subsequent calls of the endpoint /v1/cdn/stories

Also server side applications application can use the space.version option. Storing the version string to a file and reusing this timestamp will guarantee you the latest version with optimal speed. You can either use the Storyblok Webhooks or Storyblok JavaScript Events to update your version file.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/spaces/me', {})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.space
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->get('spaces/me', ['token' => 'ask9soUkv02QqbZgmZdeDAtt'])->httpResponseBody;
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/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/v1/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/spaces/me"

querystring = {}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "space": {
    "name": "Space A",
    "domain": "http://example.storyblok.com",
    "version": 1541863983
  }
}

Use the timestamp as cv:

curl "https://api.storyblok.com/v1/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "cv": 1541863983
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories();
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/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/v1/cdn/stories?cv=1541863983&token=wANpEQEsMYGOwLxwXQ76Ggtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"cv":1541863983}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Pagination

All top-level API resources have support for bulk fetches via "list" API methods. For instance, you can list stories and datasource_entries. These list API methods share a common structure, taking these two parameters: page, per_page.

The default per_page is set to 25 entries per page. You can increase this number to receive up to 100 entries per page. To go through different pages you can utilize the page parameter. The page parameter is a numeric value and uses 1 as default.

To allow a calculation of how many pages are available you can access the Total response header that you will receive after you made your first request. Access it and divide it with your per_page parameter to receive the highest possible page, otherwise you will receive an empty array as result.

Query Parameter Description
page Default: 1. Increase this to receive the next page of content entries
per_page Default: 25, Max for Stories: 100, Max for Datasource Entries: 1000 . Defines the number of content entries you will receive per page
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?per_page=2&page=1&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "per_page": 2,
  "page": 1,
  "starts_with": "posts/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(per_page: 2, page: 1, starts_with: 'posts/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['per_page' => 2, 'page' => 1, 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?per_page=2&page=1&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?per_page=2&page=1&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?per_page=2&page=1&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"per_page":2,"page":1,"starts_with":"posts/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    { ... },
    { ... }
  ]
}

Example Response Headers

status: 200
per-page: 2
total: 3
...

Stories

Storyblok’s most used content delivery endpoint is trimmed for low latency and optimum availability.

To achieve low latencies all over the world, Storyblok uses a CDN in front of the API. The official Storyblok SDKs already take care of cache invalidation, so you don’t have to. But if you are doing the API calls on your own, you will need to append the cv (cache version) parameter to the story API in order to get the latest version of the content. Have a look at Cache Invalidations for workflow descriptions.

Edit this section on GitHub

Endpoint

GET /v1/cdn/stories/

Additional Information

You can load content entries from different spaces by using different access tokens for your requests. Your access tokens decide which space you want to access. With the query parameter version you can switch between draft and published. Checkout Cache Invalidations if you want to know more about how you are able to invalidate the cache of your published content.

The Story Object

This is an object representing your content entry. One Story object can be of a specific type, so called content types and is able to contain components. You define the fields and nestability of your content types to achieve your content structure. To learn how to build a basic blog you can checkout our content building tutorial.

Property Description
id Numeric id
uuid Generated uuid string
name The name you give this story
slug Gthe slug / path you give this story
full_slug Combined parent folder and current slug
created_at Creation date (Format: YYYY-mm-dd HH:MM)
published_at Latest publishing date (Format: YYYY-mm-dd HH:MM)
first_published_at First publishing date (Format: YYYY-mm-dd HH:MM)
release_id Id of your content stage (default: null)
lang Defined language (default: "default")
content Your defined custom content body object
position Position in folder
is_startpage Is startpage of current folder (true/false)
parent_id Parent folder id
group_id Alternates group id (uuid string)
alternates Array of alternate objects
Edit this section on GitHub

Example Object

{
  "story": {
    "id": 107350,
    "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
    "name": "My third post",
    "slug": "my-third-post",
    "full_slug": "posts/my-third-post",
    "created_at": "2018-04-24T11:57:29.302Z",
    "published_at": "2018-08-07T09:40:13.802Z",
    "first_published_at": "2018-08-07T09:40:13.802Z",
    "release_id": null,
    "lang": "default",
    "content": {
      "component": "your_content_type",
      // and fields you define yourself are in here
    },
    "position": -20,
    "is_startpage": false,
    "parent_id": 107348,
    "group_id": "4add5c88-8d9c-4480-bfcf-63016c4c463e",
    "alternates": [
      {
        "id": 107381,
        "name": "Mein dritter Beitrag",
        "slug": "my-third-post",
        "full_slug": "en/my-third-post",
        "is_folder": false,
        "parent_id": 107356
      }
    ]
  }
}

Retrieve one Story

Returns a story object for the full_slug, id or uuid if authenticated using a preview or public token.

Path Parameter Description
:full_slug Use the full_slug of your content entry to retrieve it
:id Use the numeric id of your content entry to retrieve it
:uuid You can use the uuid property to query for your content entry. To tell our API to use the uuid instead of the id append the query param find_by=uuid
Query Parameter Description
token (required) Your public or preview token
find_by Added if you want to query by uuid instead of using the numeric id
version Default: published. Possible values: draft, published
resolve_links The parameter resolve_links will automatically resolve internal links of the multilink field type. If the value is story the whole story object will be included. If the value is url only uuid, id, name, path, slug and url (url is a computed property which returns the "Real path" if defined to use it for navigation links) will be included. The limit of resolved links per Story is 50 when resolving with story and 100 when resolving with url.
resolve_relations Resolve relationships to other Stories of a multi-option or single-option field-type. Provide the component name and the field key as comma separated string. The limit of resolved relationships is 100 Stories of 5 different fields. Example: resolve_relations=page.author,page.categories; Read more about it in our tutorial.
from_release Access version of specific release by release id
cv Read more about cache version at Cache invalidation
Edit this section on GitHub

Endpoint

GET /v1/cdn/stories/(:full_slug|:id|:uuid)

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/posts/my-third-post?token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/posts/my-third-post', {})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.story('posts/my-third-post')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStoryBySlug('posts/my-third-post');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/posts/my-third-post?token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/posts/my-third-post?token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/posts/my-third-post?token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/posts/my-third-post"

querystring = {}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "story": {
    "id": 107350,
    "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
    "name": "My third post",
    "slug": "my-third-post",
    "full_slug": "posts/my-third-post",
    "created_at": "2018-04-24T11:57:29.302Z",
    "published_at": "2018-12-07T01:31:36.134Z",
    "first_published_at": "2018-08-07T09:40:13.000Z",
    "content": {
      "component": "post",
      // fields you define yourself are here
      // those below we defined for the examples
      "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
      "title": "My second title",
      "author": "22f4fb1b-50b3-4bf2-816e-7d589e307421",
      "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod",
      "schedule": "2018-08-31 21:59",
      "description": "Description of the third",
      "categories": [
        "9aa72a2f-04ae-48df-b71f-25f53044dc97"
      ]
    },
    "position": -20,
    "tag_list": [ ],
    "is_startpage": false,
    "parent_id": 107348,
    "group_id": "d5ea8520-1296-40b7-8360-894461fdc5b6",
    "alternates": [ ],
    "release_id": null,
    "lang": "default"
  }
}

Retrieve Multiple Stories

Returns a list of stories that are in your Storyblok space. The stories are returned in sorted order, depending on the order in your space. You can use the query parameter sort_by with any story object property and first level of your content type to order the response to your needs.

If no entries are found with your filters applied, you will receive an empty array. You will not receive a 404 error message, to check if you have results go for the array length.

Query Parameter Description
token (required) Your public or preview token
starts_with Filter by full_slug. Can be used to retrieve all entries form a specific folder. Examples: starts_with=de/beitraege, starts_with=en/posts
by_uuids Get stories by comma separated uuid. Example: by_uuids=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4
excluding_ids Exclude stories by comma separated numeric ids. Example: excluding_ids=101231,9101231
excluding_fields Exclude specific fields of your content type by comma seperated names. Example: excluding_fields=title,content
version Default: published. Possible values: draft, published
resolve_links The parameter resolve_links will automatically resolve internal links of the multilink field type. If the value is story the whole story object will be included. If the value is url only uuid, id, name, path, slug and url (url is a computed property which returns the "Real path" if defined to use it for navigation links) will be included. The limit of resolved links per Story is 50 when resolving with story and 100 when resolving with url.
resolve_relations Resolve relationships to other Stories of a multi-option or single-option field-type. Provide the component name and the field key as comma separated string. The limit of resolved relationships per item is 20 Stories of 5 different fields and with a page size higher than 25 it is 5 Stories of 5 fields. Example: resolve_relations=page.author,page.categories
from_release Access version of specific release by release id
sort_by Sort entries by specific attribute and order with content.YOUR_FIELD:asc and content.YOUR_FIELD:desc. Possible values are all attributes of the entry and all fields of your content type inside content with the dot as seperator. Example: position:desc, content.your_custom_field:asc, content.field_type_xy.field_xy:asc, created_at:desc. If you want to use the sorting provided by the user in the Storyblok admin interface you need to use position:desc. By default all custom fields are sorted as strings. To sort custom fields with numeric values you need to provide the type information (float or int) like following: content.YOUR_FIELD:asc:float or content.YOUR_FIELD:asc:int
search_term Search content items by full text.
filter_query Filter by specific attribute(s) of your content type. The filter query parameter needs to contain the query operation key. Separate the values by a comma , to filter by multiple values.

filter_query[ATTRIBUTE][OPERATION]=VALUE,...

Following filter operations OPERATION are available:
in - Exact match of one of the provided values
not_in - Does not contain the given value
all_in_array - Contains all of the values of an array value
in_array - Contains any of the values of an array value
gt-date - Greater than date (Format: 2018-03-03 10:00)
lt-date - Less than date
gt-int - Greater than integer value
lt-int - Less than integer value.
gt-float - Greater than float value
lt-float - Less than float value.

Checkout the filter_query Examples we put together for you with most common use-cases.
is_startpage Filter by folder startpage. Use is_startpage=1 to only return startpages and is_startpage=0 to exclude startpages from the result.
language Add the language i18n code as query parameter to receive a localized version if filtering by UUIDs
with_tag Filter by specific tag(s). Use comma to filter by multiple tags. Examples: with_tag=featured,home
page Numeric. default: 1. Read more at Pagination
per_page Numeric. default: 25, max: 100. Read more at Pagination
cv Read more about cache version at Cache invalidation
Edit this section on GitHub

Endpoint

GET /v1/cdn/stories?starts_with=posts/

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "starts_with": "posts/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(starts_with: 'posts/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"starts_with":"posts/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Object

{
  "stories": [
    {
      "id": 107350,
      "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
      "name": "My third post",
      "slug": "my-third-post",
      "full_slug": "posts/my-third-post",
      "created_at": "2018-04-24T11:57:29.302Z",
      "published_at": "2018-12-07T01:31:36.134Z",
      "first_published_at": "2018-08-07T09:40:13.000Z",
      "content": {
        "component": "post",
        // fields you define yourself are here
        // those below we defined for the examples
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        "author": "22f4fb1b-50b3-4bf2-816e-7d589e307421",
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod",
        "schedule": "2018-08-31 21:59",
        "description": "Description of the third",
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97"
        ]
      },
      "position": -20,
      "tag_list": [ ],
      "is_startpage": false,
      "parent_id": 107348,
      "group_id": "d5ea8520-1296-40b7-8360-894461fdc5b6",
      "alternates": [ ],
      "release_id": null,
      "lang": "default"
    },
    {
      "id": 107349,
      "uuid": "a91440ee-fd57-4ee3-83cf-d49d217ae919",
      "name": "My second post",
      "slug": "my-second-post",
      "full_slug": "posts/my-second-post",
      "created_at": "2018-04-24T11:57:29.283Z",
      "published_at": "2018-07-26T12:38:17.025Z",
      "first_published_at": "2018-07-26T12:38:17.025Z",
      "content": {
        "component": "post",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        "author": "c47be9f0-47c3-4315-a95a-550f0c560eb5",
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do...",
        "categories": [
          "5db2e929-6d3d-4564-982e-fa8513b0e5de"
        ],
        "description": "Description of the second"
      },
      "sort_by_date": null,
      "position": -10,
      "tag_list": [ ],
      "is_startpage": false,
      "parent_id": 107348,
      "group_id": "854c3d1f-5d7f-4785-92ee-620a7c6ca7ee",
      "alternates": [ ],
      "release_id": null,
      "lang": "default"
    },
    ...
  ]
}

Spaces

This endpoint is mostly useful for client side apps. The response contains space.version which developers can use to call the story API and get the most recent published version.

As Storyblok uses a CDN in front of the API to deliver the response in the fastest way possible, you should append the cv parameter to the story api.

Read more about Cache invalidation

Edit this section on GitHub

Endpoint

GET /v1/cdn/spaces/me/

The Space Object

In the content delivery API a space object is mostly used to receive the latest version timestamp to invalidate the cache.

Property Description
id Numeric id
name Given name
domain Given domain
version Cache version
language_codes Array of language codes
Edit this section on GitHub

Example Object

{
  "space": {
    "id": 123,
    "name": "Storyblok.com",
    "domain": "https://www.storyblok.com/",
    "version": 1544117388,
    "language_codes": ["de"]
  }
}

Retrieve Current Space

Returns the current space object, if you're authenticated with a token.

Query Parameter Description
token (required) Your public or preview token
Edit this section on GitHub

Endpoint

GET /v1/cdn/spaces/me/

Example Request

curl "https://api.storyblok.com/v1/cdn/spaces/me/?token=dtONJHwmxhdJOwKxyjlqAgtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/spaces/me/', {})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.space
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->get('spaces/me', ['token' => 'ask9soUkv02QqbZgmZdeDAtt'])->httpResponseBody;
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/spaces/me/?token=dtONJHwmxhdJOwKxyjlqAgtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/spaces/me/?token=dtONJHwmxhdJOwKxyjlqAgtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/spaces/me/?token=dtONJHwmxhdJOwKxyjlqAgtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/spaces/me/"

querystring = {}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "space": {
    "id": 123,
    "name": "Storyblok.com",
    "domain": "https://www.storyblok.com/",
    "version": 1544117388,
    "language_codes": ["de"]
  }
}

Datasources

A data source is contains the information (slug) to receive a collection of datasource entries. You can use this endpoint to receive all datasources and then call the datasource entries endpoint using the slug of the datasource.

Edit this section on GitHub

Endpoint

GET /v1/cdn/datasources/

The Datasource Object

Property Description
id Numeric id
name Given name
slug Given slug
dimensions Array of dimension objects
Edit this section on GitHub

Example Object

{
  "id": 1433,
  "name": "Label",
  "slug": "labels",
  "dimensions": [
    {
      "id": 126,
      "entry_value": "en",
      "name": "English"
    }
  ]
}

Retrieve Multiple Datasources

Returns an array of datasource objects.

Query Parameter Description
token (required) Your public or preview token
page Numeric. default: 1. Read more at Pagination
per_page Numeric. default: 25, max: 1000. Read more at Pagination
Edit this section on GitHub

Endpoint

GET /v1/cdn/datasources

Example Request

curl "https://api.storyblok.com/v1/cdn/datasources?token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/datasources', {})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.datasources
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->get('datasources', ['token' => 'ask9soUkv02QqbZgmZdeDAtt'])->httpResponseBody;
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/datasources?token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/datasources?token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/datasources?token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/datasources"

querystring = {}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "datasources": [
    {
      "id": 1433,
      "name": "Label",
      "slug": "labels",
      "dimensions": [
        {
          "id": 126,
          "entry_value": "en",
          "name": "English"
        }
      ]
    }
  ]
}

Datasource Entries

A data source is simply a collection of key-value pairs. One specific datasource-entry is a set of two linked attributes: a key, which is a unique identifier for the item and the value.

Key-value pairs can be used for a single-choice, multiple-choice options and as well directly through our API to use them for multi-language labels, categories, or any use-case you might need key-value pairs.

Edit this section on GitHub

Endpoint

GET /v1/cdn/datasource_entries/

Additional Information

You can load content entries from different spaces by using different access tokens for your requests. Your access tokens decide which space you want to access. Checkout Cache Invalidations if you want to know more about how you are able to invalidate the cache of your published content.

The Datasource Entry Object

You can use the dimension=your_defined_dimension (eg. dimension=en) to receive the dimensions value besides the default value in one datasource entry.

Property Description
id Numeric id
name Given name
value Given value in default dimension
dimension_value Given value in the requested dimension
Edit this section on GitHub

Example Object: No specific dimension requested

{
  "id": 22237,
  "name": "cancel",
  "value": "Abbrechen",
  "dimension_value": null
}

Example Object: Specific dimension (en) requested

{
  "id": 22237,
  "name": "cancel",
  "value": "Abbrechen",
  "dimension_value": "Cancel"
}

Retrieve Multiple Datasource Entries

Returns an array of datasource entry objects for the datasource and dimension defined, if authenticated using a preview or public token.

Query Parameter Description
token (required) Your public or preview token
datasource Datasource group id/slug
dimension Dimension that you defined for your datasource (eg. dimension=en)
page Numeric. default: 1. Read more at Pagination
per_page Numeric. default: 25, max: 1000. Read more at Pagination
cv Read more about cache version at Cache invalidation
Edit this section on GitHub

Endpoint

GET /v1/cdn/datasource_entries?datasource=:slug

Example Request

curl "https://api.storyblok.com/v1/cdn/datasource_entries?datasource=labels&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/datasource_entries', {
  "datasource": "labels"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.datasource_entries(datasource: 'labels')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getDatasourceEntries('labels');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/datasource_entries?datasource=labels&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/datasource_entries?datasource=labels&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/datasource_entries?datasource=labels&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/datasource_entries"

querystring = {"datasource":"labels"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "datasource_entries": [
    {
      "id": 22237,
      "name": "cancel",
      "value": "Abbrechen",
      "dimension_value": null
    },
    {
      "id": 22238,
      "name": "read_more",
      "value": "Mehr erfahren",
      "dimension_value": null
    }
  ]
}

Tags

Each tag is a string value that can be reused accross Stories to create features like word clouds, basic taggings for custom workflows, or similar usecases.

Edit this section on GitHub

Endpoint

GET /v1/cdn/tags/

The Tag Object

Property Description
name the actual tag (value)
taggings_count Count of how many times this tag is currenlty in use accross all stories
Edit this section on GitHub

Example Object

{
  "name": "red",
  "taggings_count": 1
}

Retrieve All Tags

Returns an array of tag objects of one space. Use the version parameter and the correct token types to receive either draft and published or only published links.

Query Parameter Description
token (required) Your public or preview token
starts_with Filter by full_slug. Can be used to retrieve all tags form a specific folder. Examples: starts_with=de/beitraege, starts_with=en/posts
version Default: published. Possible values: draft, published
Edit this section on GitHub

Endpoint

GET /v1/cdn/tags/?starts_with=posts/

Example Request

curl "https://api.storyblok.com/v1/cdn/tags/?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/tags/', {
  "starts_with": "posts/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.tags(starts_with: 'posts/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getTags(['starts_with': 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/tags/?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/tags/?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/tags/?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/tags/"

querystring = {"starts_with":"posts/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "tags": [
    {
      "name": "red",
      "taggings_count": 14
    },
    {
      "name": "spicy",
      "taggings_count": 3
    }
  ]
}

Filter Queries

With the filter_query you're able to filter by specific attribute(s) of your stories. The filter_query parameter accepts an attribute and an operation key.

Operation Description
in Matches exactly one value
not_in Matches all without the given value
in_array Matches any value of given array
all_in_array Must match all values of given array
gt-date Greater than date (Format: YYYY-mm-dd HH:MM)
lt-date Less than date (Format: 2018-03-03 10:00)
gt-int Greater than integer value
lt-int Less than integer value
gt-float Greater than float value
lt-float Less than float value

You can find one example for each filter query in the description page for each operation, and examples that combine multiple filters in the filter examples section.

Edit this section on GitHub

Endpoint

GET /v1/cdn/stories/?filter_query[ATTRIBUTE][OPERATION]=VALUE,...

Example Story Object

We will demonstrate use-cases and example on a simple blog content structure as shown below. You're not limited by the fields in this example. Every field in the content field can be used as the ATTRIBUTE key in your filter_query.

{
  "story": {
    // default story object fields
    "content": {
      "component": "post",
        // attributes you define yoruself are located here
      "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
      "title": "My second title",
      "author": "22f4fb1b-50b3-4bf2-816e-7d589e307421",
      "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod",
      "schedule": "2018-08-31 21:59",
      "description": "Description of the third",
      "categories": [
        "9aa72a2f-04ae-48df-b71f-25f53044dc97"
      ]
    }
  }
}

Operation: in

Filter your entries by checking if your custom attribute (any field inside the content field) has a value that is equal to one of the values provided.

Use-cases: in

Get all content entries that is refered to another in a 1:N relationship or if you want to get all entries with a specific value in one of it's fields.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Filter Query Description
filter_query[author][in]=authorId&starts_with=posts/ all Posts by one Author
filter_query[customer][in]=customerId&starts_with=orders/& all Comments by one Post
filter_query[post][in]=postId&starts_with=comments/ all Comments by one Post
filter_query[seo.title][in]=Title all entries with field seo and a nested field title and the value Title
filter_query[component][in]=post all entries of one Content Type
filter_query[component][in]=post,news all entries of Content Type "post" or "news"
filter_query[featured][in]=true all entries where the field featured is true
Edit this section on GitHub

Example Request (all Posts by one Author)

curl "https://api.storyblok.com/v1/cdn/stories/?filter_query[author][in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "posts/",
  "filter_query": {
    "author": {
      "in": "22f4fb1b-50b3-4bf2-816e-7d589e307421"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {author: {in: '22f4fb1b-50b3-4bf2-816e-7d589e307421'}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['author' => ['in': '22f4fb1b-50b3-4bf2-816e-7d589e307421'], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?filter_query[author][in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?filter_query[author][in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?filter_query[author][in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"posts/","filter_query":{"author":{"in":"22f4fb1b-50b3-4bf2-816e-7d589e307421"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response (all Posts by one Author)

{
  "stories": [
    {
      "name": "My third post",
      "id": 107350,
      "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
      "content": {
        "_uid": "98cccd01-f807-4494-996d-c6b0de2045a5",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        // filtered on this author attribute
        "author": "22f4fb1b-50b3-4bf2-816e-7d589e307421",
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod...",
        "schedule": "2018-08-31 21:59",
        "component": "post",
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97"
        ],
        "description": "Description of the third"
      },
      "slug": "my-third-post",
      "full_slug": "posts/my-third-post",
      ...
    },
    {
      ...
    }
  ]
}

Operation: not_in

Filter your entries by checking if your custom attribute (any field inside the content field) does not have a value that is equal to one of the values provided.

Use-cases: not_in

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Filter Query Description
filter_query[author][not_in]=authorId&starts_with=posts/ all Posts except one Author
filter_query[seo.title][not_in]=Title all entries with field seo and a nested field title and not the value Title
filter_query[component][not_in]=post all entries without one Content Type
filter_query[component][not_in]=post,news all entries that are not of Content Type "post" or "news"
filter_query[featured][not_in]=true all entries where the field featured is not true
Edit this section on GitHub

Example Request (all Posts without specific Author)

curl "https://api.storyblok.com/v1/cdn/stories/?filter_query[author][not_in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "posts/",
  "filter_query": {
    "author": {
      "not_in": "22f4fb1b-50b3-4bf2-816e-7d589e307421"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {author: {not_in: '22f4fb1b-50b3-4bf2-816e-7d589e307421'}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['author' => ['not_in' => '22f4fb1b-50b3-4bf2-816e-7d589e307421'], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?filter_query[author][not_in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?filter_query[author][not_in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?filter_query[author][not_in]=22f4fb1b-50b3-4bf2-816e-7d589e307421&token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"posts/","filter_query":{"author":{"not_in":"22f4fb1b-50b3-4bf2-816e-7d589e307421"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "My first post",
      "id": 107349,
      "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
      "content": {
        "_uid": "98cccd01-f807-4494-996d-c6b0de2045a5",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        // filtered on this author attribute
        "author": "33f4fb1b-5243-4bf2-246e-7d5753607421",
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod...",
        "schedule": "2018-08-31 21:59",
        "component": "post",
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97"
        ],
        "description": "Description of the first"
      },
      "slug": "my-first-post",
      "full_slug": "posts/my-first-post",
      ...
    },
    {
      ...
    }
  ]
}

Operation: in_array

Filter your entries by checking if your custom array attribute (any field inside the content field) contains one of the values provided. As soon as one of the provided values separated with , are in the array field, the story object will be in the response.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: in_array

Get all content entries that is refered to others in a N:N relationship or if you want to get all entries with a specific value in one of it's array fields. You can combined this query with the starts_with, pagination, and other query options of Stories if needed.

Filter Query Description
filter_query[categories][in_array]=sportsid,esportsid all entries of category sportsid or esportsid in field categories
filter_query[tags][in_array]=food,health all entries of category food or health
filter_query[related_products][in_array]=product-one-id,product-two-id all entries with product-one or product-two in the field related_products
Edit this section on GitHub

Example Request (all entries of category 9aa72a2f-04ae-48df-b71f-25f53044dc97 and 84550816-245d-4fe6-8ae8-b633d4a328f4 in field categories)

curl "https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "filter_query": {
    "categories": {
      "in_array": "9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {categories: {in_array: ['9aa72a2f-04ae-48df-b71f-25f53044dc97', '84550816-245d-4fe6-8ae8-b633d4a328f4']}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['categories' => ['in_array' => ['9aa72a2f-04ae-48df-b71f-25f53044dc97', '84550816-245d-4fe6-8ae8-b633d4a328f4']], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"filter_query":{"categories":{"in_array":"9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response (all entries of category 9aa72a2f-04ae-48df-b71f-25f53044dc97 and 84550816-245d-4fe6-8ae8-b633d4a328f4 in field categories)

{
  "stories": [
    {
      "name": "My first Post",
      "id": 107351,
      "created_at": "2018-04-24T11:57:29.321Z",
      "published_at": "2018-12-10T13:39:18.061Z",
      "uuid": "bfea4895-8a19-4e82-ae1c-1c591dce3094",
      "content": {
        "_uid": "2caef8f8-9c37-46b4-af19-8744ec5e1053",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "This is my first post title",
        "author": 107354,
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor...",
        "schedule": "",
        "component": "post",
        // filtered on this categories attribute;
        // In response because in_array matches if ONE id does.
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97",
          "84550816-245d-4fe6-8ae8-b633d4a328f4"
        ],
        "description": "Description of the first"
      },
      "slug": "my-first-post",
      "full_slug": "posts/my-first-post",
      ...
    },{
      "name": "My third post",
      "created_at": "2018-04-24T11:57:29.302Z",
      "published_at": "2018-12-10T13:39:31.999Z",
      "id": 107350,
      "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
      "content": {
        "_uid": "98cccd01-f807-4494-996d-c6b0de2045a5",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        "author": 107354,
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor incididunt ut **labore et dolore magna aliqua**. Ut enim ad minim veniam,\nquis nostrud exercitation.",
        "schedule": "2018-08-31 21:59",
        "component": "post",
        // filtered on this categories attribute;
        // In response because in_array matches if ONE id does.
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97"
        ],
        "description": "Description of the third"
      },
      ...
    },
    {
      ...
    }
  ]
}

Operation: all_in_array

Filter your entries by checking if your custom array attribute (any field inside the content field) contains all of the values provided. As soon as all of the provided values separated with , are in the array field, the story object will be in the response.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: all_in_array

Get all content entries that is refered to others in a N:N relationship or if you want to get all entries with a specific value in one of it's array fields fields. You can combined this query with the starts_with, pagination, and other query options of Stories if needed.

Filter Query Description
filter_query[categories][all_in_array]=sportsid,esportsid all entries of category sportsid and esportsid in field categories
filter_query[tags][all_in_array]=food,health all entries of category food and health
filter_query[related_products][all_in_array]=product-one-id,product-two-id all entries with product-one and product-two in the field related_products
Edit this section on GitHub

Example Request (all entries of category 9aa72a2f-04ae-48df-b71f-25f53044dc97 and 84550816-245d-4fe6-8ae8-b633d4a328f4 in field categories)

curl "https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][all_in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "filter_query": {
    "categories": {
      "all_in_array": "9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {categories: {in_array: ['9aa72a2f-04ae-48df-b71f-25f53044dc97', '84550816-245d-4fe6-8ae8-b633d4a328f4']}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['categories' => ['in_array' => ['9aa72a2f-04ae-48df-b71f-25f53044dc97', '84550816-245d-4fe6-8ae8-b633d4a328f4']], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][all_in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][all_in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?filter_query[categories][all_in_array]=9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"filter_query":{"categories":{"all_in_array":"9aa72a2f-04ae-48df-b71f-25f53044dc97,84550816-245d-4fe6-8ae8-b633d4a328f4"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response (all entries of category 9aa72a2f-04ae-48df-b71f-25f53044dc97 and 84550816-245d-4fe6-8ae8-b633d4a328f4 in field categories)

{
  "stories": [
    {
      "name": "My first Post",
      "id": 107351,
      "created_at": "2018-04-24T11:57:29.321Z",
      "published_at": "2018-12-10T13:39:18.061Z",
      "uuid": "bfea4895-8a19-4e82-ae1c-1c591dce3094",
      "content": {
        "_uid": "2caef8f8-9c37-46b4-af19-8744ec5e1053",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "This is my first post title",
        "author": 107354,
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor...",
        "schedule": "",
        "component": "post",
        // filtered on this categories attribute;
        // In response because all_in_array matches if ALL ids are present.
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97",
          "84550816-245d-4fe6-8ae8-b633d4a328f4"
        ],
        "description": "Description of the first"
      },
      "slug": "my-first-post",
      "full_slug": "posts/my-first-post",
      ...
    },
    {
      ...
    }
  ]
}

Operation: gt-date

Think of it at AFTER a specific date. Allows you to filter fields of type date/datetime (Format: YYYY-mm-dd HH:MM). Returns all entries that are greater (eg. later) than the provided value.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: gt-date

You can create custom dates that allow you to schedule posts, launch products and with this query see all entries that are scheduled after a specific date, schedule christmas teaser. Creating a field with the type date does not effect the published state of one content entry, but allows your frontend / server side implementation to query those specific entries.

Filter Query Description
filter_query[schedule][gt-date]=2019-12-24 09:00 all entries with date field schedule after "2019-12-24 09:00"
Edit this section on GitHub

Example Request (All posts scheduled AFTER now)

curl "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][gt-date]=2019-12-24 09:00" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "posts/",
  "filter_query": {
    "schedule": {
      "gt-date": "2019-12-24 09:00"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {schedule: {gt-date: '2019-12-24 09:00'}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['schedule' => ['gt-date' => '2019-12-24 09:00'], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][gt-date]=2019-12-24 09:00")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][gt-date]=2019-12-24 09:00");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][gt-date]=2019-12-24 09:00")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"posts/","filter_query":{"schedule":{"gt-date":"2019-12-24 09:00"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response (All posts scheduled AFTER now)

{
  "stories": [
    {
      "name": "My first Post",
      "created_at": "2018-04-24T11:57:29.321Z",
      "published_at": "2018-12-10T14:10:18.964Z",
      "id": 107351,
      "uuid": "bfea4895-8a19-4e82-ae1c-1c591dce3094",
      "content": {
        "_uid": "2caef8f8-9c37-46b4-af19-8744ec5e1053",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "This is my first post title",
        "author": 107354,
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor incididunt...",
        // filtered on this schedule attribute;
        // In response because gt-date matches if 
        // date in entry is GREATER than provided value
        "schedule": "2019-12-24 10:00",
        "component": "post",
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97",
          "84550816-245d-4fe6-8ae8-b633d4a328f4"
        ],
        "description": "Description of the first"
      },
      "slug": "my-first-post",
      "full_slug": "posts/my-first-post",
      ...
    },
    ...
  ]
}

Operation: lt-date

Think of it at BEFORE a specific date. Allows you to filter fields of type date/datetime (Format: YYYY-mm-dd HH:MM). Returns all entries that are lower than (eg. before) the provided date.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: lt-date

You can create custom dates that allow you to schedule posts, launch products, schedule christmas teaser and more. Creating a field with the type date does not effect the published state of one content entry, but allows your frontend / server side implementation to query all entries before a specific date (eg. today)

Filter Query Description
filter_query[schedule][lt-date]=2018-12-24 09:00 all entries with date field schedule before "2018-12-24 09:00"
Edit this section on GitHub

Example Request (All posts scheduled BEFORE date)

curl "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][lt-date]=2018-12-24 09:00" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "posts/",
  "filter_query": {
    "schedule": {
      "lt-date": "2018-12-24 09:00"
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {schedule: {lt-date: '2019-12-24 09:00'}, starts_with: 'posts/'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['schedule' => ['lt-date' => '2019-12-24 09:00'], 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][lt-date]=2018-12-24 09:00")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][lt-date]=2018-12-24 09:00");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&starts_with=posts/&filter_query[schedule][lt-date]=2018-12-24 09:00")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"posts/","filter_query":{"schedule":{"lt-date":"2018-12-24 09:00"}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response (All posts scheduled BEFORE date)

{
  "stories": [
    {
      "name": "My second Post",
      "created_at": "2018-04-24T11:57:29.321Z",
      "published_at": "2018-12-10T14:10:18.964Z",
      "id": 123122,
      "uuid": "bfea4895-8a19-4e82-ae1c-1c591dce3094",
      "content": {
        "_uid": "2caef8f8-9c37-46b4-af19-8744ec5e1053",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "This is my second post title",
        "author": 107354,
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor incididunt...",
        // filtered on this schedule attribute;
        // In response because gt-date matches if 
        // date in entry is GREATER than provided value
        "schedule": "2018-04-22 14:32",
        "component": "post",
        "categories": [
          "9aa72a2f-04ae-48df-b71f-25f53044dc97",
          "84550816-245d-4fe6-8ae8-b633d4a328f4"
        ],
        "description": "Description of the second"
      },
      "slug": "my-second-post",
      "full_slug": "posts/my-second-post",
      ...
    },
    ...
  ]
}

Operation: gt-int

Allows you to filter fields of type number, string (number value), or custom field type with numbers in the schema. Returns all entries that are GREATER than the provided value.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: gt-int

As soon as you need to query for a specific integer value in your content entries, this is your go to filter for greater than checks. You can build price filter for your products if your price value is in the CMS and not your PIM or any other number oriented kind of filter.

Filter Query Description
filter_query[price][gt-int]=100 all entries with price field greater than 100
filter_query[price][gt-int]=99 all entries with price field greater than 99
filter_query[price][gt-int]=99 all entries with price field greater than 99
filter_query[price][gt-int]=1999 all entries with price field greater than 1999 (no thousand separator)
filter_query[price][gt-int]=1999 all entries with price field greater than 1999 (no thousand separator)
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-int]=100" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/",
  "filter_query": {
    "price": {
      "gt-int": 100
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {price: {'gt-int': 100}}, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['price' => ['gt-int' => 100], 'starts_with' => 'products/');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-int]=100")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-int]=100");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-int]=100")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/","filter_query":{"price":{"gt-int":100}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Spaceship",
      "id": 461935,
      "created_at": "2018-12-10T17:51:25.161Z",
      "published_at": "2018-12-10T17:52:14.888Z",
      "uuid": "14d950c6-0a8f-4088-98e3-73efced9ff6d",
      "content": {
        "_uid": "00b45e23-5dc5-4398-9b34-e87ae4ed42e6",
        "name": "Spaceship",
        "image": "//a.storyblok.com/f/44203/6016x4016/995fde1190/spaceship.jpg",
        // filtered on this price attribute;
        // value of field price needs to be greater than 100
        "price": "1700000000",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "spaceship",
      "full_slug": "products/spaceship",
      ...
    },
    {
      "name": "Coat",
      "id": 461933,
      "uuid": "0186a027-4f04-4750-b743-8855ad4e71d4",
      "content": {
        "_uid": "baa8057c-a928-4fda-b322-9499a081a9c9",
        "name": "Coat",
        "image": "//a.storyblok.com/f/44203/5616x3744/8cff02e5d6/coat.jpg",
        // filtered on this price attribute;
        // value of field price needs to be greater than 100
        "price": "270",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "coat",
      "full_slug": "products/coat",
      ...
    }
  ]
}

Operation: lt-int

Allows you to filter fields of type number, or custom field type with numbers in the schema. Returns all entries that are LOWER than the provided value.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: lt-int

As soon as you need to query for a specific integer value in your content entries, this is your go to filter for lower than checks. You can build price filter for your products if your price value is in the CMS and not your PIM or any other number oriented kind of filter.

Filter Query Description
filter_query[price][lt-int]=100 all entries with price field lower than 100
filter_query[price][lt-int]=99 all entries with price field lower than 99
filter_query[price][lt-int]=1999 all entries with price field lower than 1999 (no thousand separator)
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-int]=100" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/",
  "filter_query": {
    "price": {
      "lt-int": 100
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {price: {'lt-int': 100}}, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['price' => ['lt-int' => 100], 'starts_with' => 'products/');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-int]=100")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-int]=100");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-int]=100")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/","filter_query":{"price":{"lt-int":100}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "24",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "paper",
      "full_slug": "products/paper",
      ...
    },
    {
      "name": "Shoe",
      "created_at": "2018-12-10T17:49:40.741Z",
      "published_at": "2018-12-10T17:50:30.588Z",
      "id": 461932,
      "uuid": "9176c97c-2602-4878-80f0-ea89c9eb26b7",
      "content": {
        "_uid": "89dbca77-6df2-4c42-bcd5-a2d81277fe4b",
        "name": "Shoe",
        "image": "//a.storyblok.com/f/44203/2880x1920/3af2f49951/shoe.jpg",
        "price": "99",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "shoe",
      "full_slug": "products/shoe",
      ...
    }
  ]
}

Operation: gt-float

Allows you to filter fields of type float, string (float value), or custom field type with numbers in the schema. Returns all entries that are GREATER than the provided value.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: gt-float

As soon as you need to query for a specific float value in your content entries, this is your go to filter for greater than checks. You can build price filter for your products if your price value is in the CMS and not your PIM or any other number oriented kind of filter.

Filter Query Description
filter_query[price][gt-float]=100.50 all entries with price field greater than 100.50
filter_query[price][gt-float]=99.50 all entries with price field greater than 99.50
filter_query[price][gt-float]=99.50 all entries with price field greater than 99.50
filter_query[price][gt-float]=1999.50 all entries with price field greater than 1999.50 (no thousand separator)
filter_query[price][gt-float]=1999.50 all entries with price field greater than 1999.50 (no thousand separator)
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/",
  "filter_query": {
    "price": {
      "gt-float": 100.5
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {price: {'gt-float': 100.5}}, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['price' => ['gt-float' => 100.5], 'starts_with' => 'products/');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/","filter_query":{"price":{"gt-float":100.5}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Spaceship",
      "id": 461935,
      "created_at": "2018-12-10T17:51:25.161Z",
      "published_at": "2018-12-10T17:52:14.888Z",
      "uuid": "14d950c6-0a8f-4088-98e3-73efced9ff6d",
      "content": {
        "_uid": "00b45e23-5dc5-4398-9b34-e87ae4ed42e6",
        "name": "Spaceship",
        "image": "//a.storyblok.com/f/44203/6016x4016/995fde1190/spaceship.jpg",
        // filtered on this price attribute;
        // value of field price needs to be greater than 100
        "price": "17000000.50",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "spaceship",
      "full_slug": "products/spaceship",
      ...
    },
    {
      "name": "Coat",
      "id": 461933,
      "uuid": "0186a027-4f04-4750-b743-8855ad4e71d4",
      "content": {
        "_uid": "baa8057c-a928-4fda-b322-9499a081a9c9",
        "name": "Coat",
        "image": "//a.storyblok.com/f/44203/5616x3744/8cff02e5d6/coat.jpg",
        // filtered on this price attribute;
        // value of field price needs to be greater than 100
        "price": "27.50",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "coat",
      "full_slug": "products/coat",
      ...
    }
  ]
}

Operation: lt-float

Allows you to filter fields of type number, or custom field type with numbers in the schema. Returns all entries that are LOWER than the provided value.

You can combined this query with the starts_with, pagination, other filter query, and query/sorting options of Stories if needed.

Use-cases: lt-float

As soon as you need to query for a specific float value in your content entries, this is your go to filter for lower than checks. You can build price filter for your products if your price value is in the CMS and not your PIM or any other number oriented kind of filter.

Filter Query Description
filter_query[price][lt-float]=100.50 all entries with price field lower than 100.50
filter_query[price][lt-float]=99.50 all entries with price field lower than 99.50
filter_query[price][lt-float]=1999.50 all entries with price field lower than 1999.50 (no thousand separator)
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-float]=100.50" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/",
  "filter_query": {
    "price": {
      "lt-float": 100.5
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {price: {'lt-float': 100.5}}, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['price' => ['lt-float' => 100.5], 'starts_with' => 'products/');
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-float]=100.50")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-float]=100.50");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][lt-float]=100.50")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/","filter_query":{"price":{"lt-float":100.5}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "paper",
      "full_slug": "products/paper",
      ...
    },
    {
      "name": "Shoe",
      "created_at": "2018-12-10T17:49:40.741Z",
      "published_at": "2018-12-10T17:50:30.588Z",
      "id": 461932,
      "uuid": "9176c97c-2602-4878-80f0-ea89c9eb26b7",
      "content": {
        "_uid": "89dbca77-6df2-4c42-bcd5-a2d81277fe4b",
        "name": "Shoe",
        "image": "//a.storyblok.com/f/44203/2880x1920/3af2f49951/shoe.jpg",
        "price": "74.99",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "shoe",
      "full_slug": "products/shoe",
      ...
    }
  ]
}

Starts With Examples

We've provided some common request example that make use of the starts_with query parameter.

Edit this section on GitHub

Entries in folder xx

You can use the starts_with parameter to load entries that are in a specific folder. This is useful if you create your articles in an articles/ folder, products/ in a products folder.

Slug Description
?starts_with=products/ all entries in folder products
?starts_with=de/products/ all entries with de values in translateable fields in folder products
?starts_with=articles/ all entries in folder articles
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['starts_with' => 'products/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Spaceship",
      "lang": "de",
      "created_at": "2018-12-10T17:51:25.161Z",
      "published_at": "2018-12-10T18:27:28.137Z",
      "id": 461935,
      "uuid": "14d950c6-0a8f-4088-98e3-73efced9ff6d",
      "content": {
        "_uid": "00b45e23-5dc5-4398-9b34-e87ae4ed42e6",
        // translateable field
        "name": "Raumschiff",
        // translateable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/6016x4016/995fde1190/spaceship.jpg",
        "price": "1700000000",
        "component": "product"
      },
      "slug": "spaceship",
      "full_slug": "de/products/spaceship"
      ...
    },
    ...
    {
      "name": "Shoe",
      "lang": "de",
      "created_at": "2018-12-10T17:49:40.741Z",
      "published_at": "2018-12-10T18:27:01.870Z",
      "id": 461932,
      "uuid": "9176c97c-2602-4878-80f0-ea89c9eb26b7",
      "content": {
        "_uid": "89dbca77-6df2-4c42-bcd5-a2d81277fe4b",
        // translateable field
        "name": "Schuh",
        // translateable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/2880x1920/3af2f49951/shoe.jpg",
        "price": "10",
        "component": "product"
      },
      "slug": "shoe",
      "full_slug": "de/products/shoe",
      ...
    }
  ]
}

Draft version of entries in folder xx

You can use the version param combined with the starts_with param to load entries that are in a specific folder.

Slug Description
?version=draft&starts_with=products/ all entries in folder products
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?version=draft&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "version": "draft",
  "starts_with": "products/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(version: 'draft', starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['version' => 'draft', 'starts_with' => 'products/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?version=draft&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?version=draft&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?version=draft&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"version":"draft","starts_with":"products/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Spaceship",
      "lang": "de",
      "created_at": "2018-12-10T17:51:25.161Z",
      "published_at": "2018-12-10T18:27:28.137Z",
      "id": 461935,
      "uuid": "14d950c6-0a8f-4088-98e3-73efced9ff6d",
      "content": {
        "_uid": "00b45e23-5dc5-4398-9b34-e87ae4ed42e6",
        // translatable field
        "name": "Raumschiff",
        // translatable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/6016x4016/995fde1190/spaceship.jpg",
        "price": "1700000000",
        "component": "product"
      },
      "slug": "spaceship",
      "full_slug": "de/products/spaceship"
      ...
    },
    ...
    {
      "name": "Shoe",
      "lang": "de",
      "created_at": "2018-12-10T17:49:40.741Z",
      "published_at": "2018-12-10T18:27:01.870Z",
      "id": 461932,
      "uuid": "9176c97c-2602-4878-80f0-ea89c9eb26b7",
      "content": {
        "_uid": "89dbca77-6df2-4c42-bcd5-a2d81277fe4b",
        // translatable field
        "name": "Schuh",
        // translatable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/2880x1920/3af2f49951/shoe.jpg",
        "price": "10",
        "component": "product"
      },
      "slug": "shoe",
      "full_slug": "de/products/shoe",
      ...
    }
  ]
}

Entries of language xx

The field type translation will map the available language keys with the folder paths. So for example if you have a folder Products with multiple products and those products do have translateable fields you are able to load those translated version with prepending the language key infront of the slug.

Slug Description
?starts_with=products/ all products of default language
?starts_with=de/products/ all products with de/ values in translateable fields
?starts_with=de/* all entries with de/ values in translatable fields without particular folder
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?starts_with=de/*&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "de/*"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(starts_with: 'de/*')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['starts_with' => 'de/*']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?starts_with=de/*&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?starts_with=de/*&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?starts_with=de/*&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"de/*"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Spaceship",
      "lang": "de",
      "created_at": "2018-12-10T17:51:25.161Z",
      "published_at": "2018-12-10T18:27:28.137Z",
      "id": 461935,
      "uuid": "14d950c6-0a8f-4088-98e3-73efced9ff6d",
      "content": {
        "_uid": "00b45e23-5dc5-4398-9b34-e87ae4ed42e6",
        // translateable field
        "name": "Raumschiff",
        // translateable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/6016x4016/995fde1190/spaceship.jpg",
        "price": "1700000000",
        "component": "product"
      },
      "slug": "spaceship",
      "full_slug": "de/products/spaceship"
      ...
    },
    ...
    {
      "name": "Shoe",
      "lang": "de",
      "created_at": "2018-12-10T17:49:40.741Z",
      "published_at": "2018-12-10T18:27:01.870Z",
      "id": 461932,
      "uuid": "9176c97c-2602-4878-80f0-ea89c9eb26b7",
      "content": {
        "_uid": "89dbca77-6df2-4c42-bcd5-a2d81277fe4b",
        // translateable field
        "name": "Schuh",
        // translateable field
        "description": "Deutsches Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet.",
        "image": "//a.storyblok.com/f/44203/2880x1920/3af2f49951/shoe.jpg",
        "price": "10",
        "component": "product"
      },
      "slug": "shoe",
      "full_slug": "de/products/shoe",
      ...
    }
  ]
}

Filter Examples

We've provided some common request example that combine multiple and different filter_querys with sorting that you might need during your implementation.

Edit this section on GitHub

Filter entries by boolean value

Imagine you want to allow your editors to have featured products with a boolean flag in your content schema. To filter all products to only receive the featured once you can utilize the filter_query operation in to check for an exact value.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?filter_query[featured][in]=true&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "starts_with": "products/",
  "filter_query": {
    "featured": {
      "in": true
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(starts_with: 'products/', filter_query: {featured: {in: true}})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['starts_with' => 'products/', 'filter_query' => ['featured' => ['in' => true]);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?filter_query[featured][in]=true&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?filter_query[featured][in]=true&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?filter_query[featured][in]=true&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"starts_with":"products/","filter_query":{"featured":{"in":true}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Coat",
      "created_at": "2018-12-10T17:50:34.547Z",
      "published_at": "2018-12-10T17:50:47.977Z",
      "id": 461933,
      "uuid": "0186a027-4f04-4750-b743-8855ad4e71d4",
      "content": {
        "_uid": "baa8057c-a928-4fda-b322-9499a081a9c9",
        "name": "Coat",
        "image": "//a.storyblok.com/f/44203/5616x3744/8cff02e5d6/coat.jpg",
        // filtered on GREATER than 100 and LOWER than 300
        "price": "270",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "coat",
      "full_slug": "products/coat",
      "lang": "default",
      ...
    }
  ]
}

Entries between two numbers

A common filter needed for a shop content structure implementation would be a simple price range products filter. In the examples above you already saw how to write one filter_query to receive all products that are greater or lower a specific price tag; In this example we will combine the gt-float and lt-float filters to get all products between a price range.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50&filter_query[price][lt-float]=300.50" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "filter_query": {
    "price": {
      "gt-float": 100.5,
      "lt-float": 300.5
    }
  }
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(filter_query: {price: {'gt-float': 100.5, 'lt-float': 300.5}}, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['filter_query' => ['price' => ['gt-float' => 100.5, 'lt-float' => 300.5], 'starts_with' => 'products/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50&filter_query[price][lt-float]=300.50")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50&filter_query[price][lt-float]=300.50");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?token=ask9soUkv02QqbZgmZdeDAtt&filter_query[price][gt-float]=100.50&filter_query[price][lt-float]=300.50")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"filter_query":{"price":{"gt-float":100.5,"lt-float":300.5}}}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "Coat",
      "created_at": "2018-12-10T17:50:34.547Z",
      "published_at": "2018-12-10T17:50:47.977Z",
      "id": 461933,
      "uuid": "0186a027-4f04-4750-b743-8855ad4e71d4",
      "content": {
        "_uid": "baa8057c-a928-4fda-b322-9499a081a9c9",
        "name": "Coat",
        "image": "//a.storyblok.com/f/44203/5616x3744/8cff02e5d6/coat.jpg",
        // filtered on GREATER than 100 and LOWER than 300
        "price": "270.50",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "coat",
      "full_slug": "products/coat",
      "lang": "default",
      ...
    }
  ]
}

Ordering / Sorting

We've provided some common request examples that make use of the sort_by query parameter.

Edit this section on GitHub

Sort by admin interface

Some of you might like to define the order of your entries in Storyblok, utilizing the move functionality. To receive the order just like in Storyblok you can make use of the position property.

Attention: The position property is only sorted within one folder

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?sort_by=position:desc&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "sort_by": "position:desc"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(sort_by: 'position:desc')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['sort_by' => 'position:desc']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?sort_by=position:desc&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?sort_by=position:desc&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?sort_by=position:desc&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"sort_by":"position:desc"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      // sorted by this property
      "position": -10,
      "slug": "paper",
      "full_slug": "products/paper"
    },
    { ... },
    { ... },
    ...
  ]
}

Sort by content attribute

To sort by a field that you have defined in your content schema of your content type, you're able to use the sort_by parameter as shown below.

Query Description
sort_by=content.name:asc Sort by the content type attribute name

As you can see it works just like with the default properties of a story object but prepending the context content. before the field.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?sort_by=content.name:asc&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "sort_by": "content.name:asc"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(sort_by: 'content.name:asc')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['sort_by' => 'content.name:asc']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?sort_by=content.name:asc&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?sort_by=content.name:asc&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?sort_by=content.name:asc&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"sort_by":"content.name:asc"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        // sorted by this property
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "paper",
      "full_slug": "products/paper"
    },
    { ... },
    { ... },
    ...
  ]
}

Sort by story object property

You can sort your content entries by custom and predefined property using the sort_by parameter and field:asc or field:desc as value.

Query Description
sort_by=name:asc Sort by the Story object property name
sort_by=position:desc Sort by the Story object property position (same as in the admin interface)
sort_by=first_published_at:desc Sort by the Story object property first_published_at
Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?sort_by=name:asc&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "sort_by": "name:asc"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(sort_by: 'name:asc')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['sort_by' => 'name:asc']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?sort_by=name:asc&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?sort_by=name:asc&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?sort_by=name:asc&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"sort_by":"name:asc"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      // sorted by this property
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "paper",
      "full_slug": "products/paper"
    },
    { ... },
    { ... },
    ...
  ]
}

Useful

Other request examples that might be useful, without specific category like ordering/sorting, starts with or filtering.

Edit this section on GitHub

Load latest CV timestamp

With the cache invalidation provided by Storyblok utilizing the cv (cache version) query paramter you're able to always hit the latest version of your content. This can either be a server side generated timestmap that receives an update if our webhook triggers a publish event or you fetch it every time you boot up your application.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/spaces/me/?cv=CURRENT_TIMESTAMP&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/spaces/me/', {
  "cv": "CURRENT_TIMESTAMP"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.space
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->get('spaces/me', ['token' => 'ask9soUkv02QqbZgmZdeDAtt'])->httpResponseBody;
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/spaces/me/?cv=CURRENT_TIMESTAMP&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/spaces/me/?cv=CURRENT_TIMESTAMP&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/spaces/me/?cv=CURRENT_TIMESTAMP&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/spaces/me/"

querystring = {"cv":"CURRENT_TIMESTAMP"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "space": {
    "name": "Blog",
    "domain": "https://www.storyblok.com/",
    // version timestamp to use for further requests
    "version": 1544466448
  }
}

Load draft version

Appending the query paramter version with the value draft (eg. version=draft) and using the preview token as token will allow you to access the draft versions of content entries. You can perform all kind of queries, sorting and filterings with either published or draft versions.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?version=draft&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "version": "draft"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(version: 'draft')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['version' => 'draft']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?version=draft&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?version=draft&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?version=draft&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"version":"draft"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      "slug": "paper",
      "full_slug": "products/paper"
    },
    { ... },
    { ... },
    ...
  ]
}

Load with resolved relationships

Resolve relationships to other Stories (in the first level of nesting) of a multi-option or single-option field-type. Provide the field key(s) as comma separated string to resolve specific fields.

Example: resolve_relations=categories.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/?resolve_relations=categories&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/', {
  "resolve_relations": "categories",
  "starts_with": "posts/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(resolve_relations: 'categories', starts_with: 'posts/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['resolve_relations' => 'categories', 'starts_with' => 'posts/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/?resolve_relations=categories&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/?resolve_relations=categories&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/?resolve_relations=categories&starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/"

querystring = {"resolve_relations":"categories","starts_with":"posts/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{
  "stories": [
    {
      "name": "My third post",
      "created_at": "2018-04-24T11:57:29.302Z",
      "published_at": "2018-12-10T13:39:31.999Z",
      "id": 107350,
      "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
      "content": {
        "_uid": "98cccd01-f807-4494-996d-c6b0de2045a5",
        "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
        "title": "My second title",
        "author": "n4a2123-e323-43ca-ae59-5cd7d38683cb",
        "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor incididunt ut **labore et dolore magna aliqua**.",
        "schedule": "2018-08-31 21:59",
        "component": "post",
        // resolved relationship by including the story 
        // object of the reference entry
        "categories": [
          {
            "name": "Design",
            "created_at": "2018-04-24T11:59:26.578Z",
            "published_at": "2018-04-24T12:07:46.278Z",
            "id": 107357,
            "uuid": "9aa72a2f-04ae-48df-b71f-25f53044dc97",
            "content": {
              "_uid": "6fc4a8e1-52a1-46b3-85b2-a1a93452c97a",
              "name": "Design",
              "image": "//a.storyblok.com/f/44203/1177x841/8c69867d6e/undraw_lighthouse2_1ebd.png",
              "component": "category"
            },
            "slug": "design",
            "full_slug": "categories/design",
            ...
          }
        ],
        "description": "Description of the third"
      },
      "slug": "my-third-post",
      "full_slug": "posts/my-third-post",
      ...
    },
    { ... }
  ]
}

Load without startpage

Appending the query paramter is_startpage with the value false (eg. is_startpage=false) to retrieve only entries of a folder and skipping the startpage you've defined in that folder.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories?is_startpage=false&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories', {
  "is_startpage": false,
  "starts_with": "products/"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.stories(is_startpage: false, starts_with: 'products/')
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->getStories(['is_startpage' => false, starts_with: 'products/']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories?is_startpage=false&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories?is_startpage=false&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories?is_startpage=false&starts_with=products/&token=ask9soUkv02QqbZgmZdeDAtt")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories"

querystring = {"is_startpage":false,"starts_with":"products/"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "stories": [
    {
      "name": "Paper",
      "created_at": "2018-12-10T17:50:54.023Z",
      "published_at": "2018-12-10T17:51:18.988Z",
      "id": 461934,
      "uuid": "7b372086-0c79-4890-9f01-2e6e41098f87",
      "content": {
        "_uid": "5bbcd6f0-494a-42bd-b135-a1f7216c27ce",
        "name": "Paper",
        "image": "//a.storyblok.com/f/44203/4032x3024/747174042a/paper.jpg",
        "price": "0.00124",
        "component": "product",
        "description": "Lorem ipsum dolor sit amet, consectetur adipiscing elit. In erat mauris, faucibus quis pharetra sit amet, pretium ac libero. Etiam vehicula eleifend bibendum."
      },
      // all stories will have the is_startpage flag set to false
      "is_startpage": false,
      "slug": "paper",
      "full_slug": "products/paper"
    },
    { ... },
    { ... },
    ...
  ]
}

Load story localized by uuid

Appending the query parameter language in combination with find_by=uuid allows you to load localized versions of your entries without knowing its slug. If you know the slug of your content entry you can simply prepend the language code, eg. /posts/my-first-post would be /de/posts/my-first-post. As you only have a UUID by hand, and you do know the slug you can use the language parameter instead.

Edit this section on GitHub

Example Request

curl "https://api.storyblok.com/v1/cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb?token=ask9soUkv02QqbZgmZdeDAtt&find_by=uuid&language=de" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
// use the universal js client to perform the request
Storyblok.get('cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb', {
  "find_by": "uuid",
  "language": "de"
})
.then(response => {
  console.log(response)
}).catch(error => { 
  console.log(error)
})
require 'storyblok'
client = Storyblok::Client.new(token: 'YOUR_TOKEN')

client.story('ac0d2ed0-e323-43ca-ae59-5cd7d38683cb', {find_by: 'uuid', language: 'de'})
$client = new \Storyblok\Client('YOUR_TOKEN');

$client->get('stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb', ['find_by' => 'uuid', 'language' => 'de']);
HttpResponse<String> response = Unirest.get("https://api.storyblok.com/v1/cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb?token=ask9soUkv02QqbZgmZdeDAtt&find_by=uuid&language=de")
  .asString();
var client = new RestClient("https://api.storyblok.com/v1/cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb?token=ask9soUkv02QqbZgmZdeDAtt&find_by=uuid&language=de");
var request = new RestRequest(Method.GET);
IRestResponse response = client.Execute(request);
import Foundation

let request = NSMutableURLRequest(url: NSURL(string: "https://api.storyblok.com/v1/cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb?token=ask9soUkv02QqbZgmZdeDAtt&find_by=uuid&language=de")! as URL,
                    cachePolicy: .useProtocolCachePolicy, timeoutInterval: 10.0)
request.httpMethod = "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/v1/cdn/stories/ac0d2ed0-e323-43ca-ae59-5cd7d38683cb"

querystring = {"find_by":"uuid","language":"de"}

payload = ""
headers = {}

response = requests.request("GET", url, data=payload, headers=headers, params=querystring)

print(response.text)

Example Response

{  
  "story": {
    "name": "My third post",
    "created_at": "2018-04-24T11:57:29.302Z",
    "published_at": "2018-12-10T13:39:31.999Z",
    "id": 107350,
    "uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
    "lang": "de",
    "content": {
      "_uid": "98cccd01-f807-4494-996d-c6b0de2045a5",
      "image": "//a.storyblok.com/f/44162/1500x500/68b522b06d/1500x500.jpeg",
      "title": "Mein zweiter Titel",
      "author": "n4a2123-e323-43ca-ae59-5cd7d38683cb",
      "content": "Lorem ipsum dolor sit amet, *consectetur* adipisicing elit, sed do eiusmod\ntempor incididunt ut **labore et dolore magna aliqua**.",
      "schedule": "2018-08-31 21:59",
      "component": "post",
      // resolved relationship by including the story 
      // object of the reference entry
      "categories": [
        ...
      ],
      "description": "Beschreibung vom zweiten Beitrag"
    },
    "slug": "my-third-post",
    "full_slug": "posts/my-third-post",
    ...
  }
}