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.
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
andversion=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.
Example Request
curl "https://api.storyblok.com/v1/cdn/stories?token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
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.
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.) |
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.
Recommended: Client Side
- Request the resource
/v1/cdn/spaces/me
to get thespace.version
property - Append the
space.version
to all your subsequent calls of the endpoint/v1/cdn/stories
Recommended: SSG / Server Side
- Generate a timestamp (once on a server, not on every request/client load)
- 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.
Example Request
curl "https://api.storyblok.com/v1/cdn/spaces/me?token=wANpEQEsMYGOwLxwXQ76Ggtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
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"
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 |
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"
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.
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 |
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 |
If resolve_links=1 it will automatically resolve internal links of the multilink field type. The limit of resolved links per Story is 50 . |
resolve_relations |
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=author,categories |
cv |
Read more about cache version at Cache invalidation |
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"
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 |
If resolve_links=1 it will automatically resolve internal links of the multilink field type. The limit of resolved links per Story is 50 . |
resolve_relations |
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=author,categories |
sort_by |
Sort entries by specific attribute and order with content.YOUR_FIELD:asc and content.YOUR_FIELD:desc . Possible values are all root 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 , created_at:desc . If you want to use the sorting in the Storyblok admin interface you can use position:desc to achieve that. |
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 valuesnot_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 |
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 |
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"
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
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 |
value |
Given value in default dimension |
dimension_value |
Given value in the requested dimension |
Example Object
{
"space": {
"name": "Storyblok.com",
"domain": "https://www.storyblok.com/",
"version": 1544117388
}
}
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 |
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"
Example Response
{
"space": {
"name": "Storyblok.com",
"domain": "https://www.storyblok.com/",
"version": 1544117388
}
}
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.
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 |
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 |
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"
Example Response
{
"datasource_entries": [
{
"id": 22237,
"name": "cancel",
"value": "Abbrechen",
"dimension_value": null
},
{
"id": 22238,
"name": "read_more",
"value": "Mehr erfahren",
"dimension_value": null
}
]
}
Links
Links are another representation of your content entries, eg. Stories. With the Links format you can resolve uuid
s of stories. The links object returned consists of multiple keys, where each key is the uuid
of one Story. In the link object you will have access to basic information to identify, load or already display a link to that resource.
Endpoint
GET /v1/cdn/links/
The Links Object
Property | Description |
---|---|
Multiple uuid |
One key per Story, where the key is the uuid of the story |
Example Object
{
"links": {
"ac0d2ed0-e323-43ca-ae59-5cd7d38683cb": {
"id": 107350,
"slug": "posts/my-third-post",
"name": "My third post",
"is_folder": false,
"parent_id": 107348,
"published": true,
"position": -20,
"uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
"is_startpage": false
},
...
}
}
The Link Object
You can access a draft or published version of your links by providing the version
parameter and the correct token type (eg. preview for draft, public for published).
Property | Description |
---|---|
id |
Numeric id of the referenced content entry |
slug |
The full_slug of the content entry |
name |
Given name of the content entry |
is_folder |
Is this content entry a folder (true/false) |
parent_id |
Parent folder numeric id |
published |
Is this story published (true/false) |
position |
Numeric position value of the content entry |
uuid |
The uuid of the content entry |
is_startpage |
IS this story a startpage (true/false) |
Example Object
...
{
"id": 107350,
"slug": "posts/my-third-post",
"name": "My third post",
"is_folder": false,
"parent_id": 107348,
"published": true,
"position": -20,
"uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
"is_startpage": false
}
...
Retrieve Multiple Links
Returns the links object containing all links 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 links form a specific folder. Examples: starts_with=de/beitraege , starts_with=en/posts |
version |
Default: published . Possible values: draft , published |
Attention: This API endpoint is not paged.
Endpoint
GET /v1/cdn/links/?starts_with=posts/
Example Request
curl "https://api.storyblok.com/v1/cdn/links/?starts_with=posts/&token=ask9soUkv02QqbZgmZdeDAtt" \
-X GET \
-H "Accept: application/json" \
-H "Content-Type: application/json"
Example Object
{
"links": {
"ac0d2ed0-e323-43ca-ae59-5cd7d38683cb": {
"id": 107350,
"slug": "posts/my-third-post",
"name": "My third post",
"is_folder": false,
"parent_id": 107348,
"published": true,
"position": -20,
"uuid": "ac0d2ed0-e323-43ca-ae59-5cd7d38683cb",
"is_startpage": false
},
"a91440ee-fd57-4ee3-83cf-d49d217ae919": {
"id": 107349,
"slug": "posts/my-second-post",
"name": "My second post",
"is_folder": false,
"parent_id": 107348,
"published": true,
"position": -10,
"uuid": "a91440ee-fd57-4ee3-83cf-d49d217ae919",
"is_startpage": false
},
"bfea4895-8a19-4e82-ae1c-1c591dce3094": {
"id": 107351,
"slug": "posts/my-first-post",
"name": "My first Post",
"is_folder": false,
"parent_id": 107348,
"published": true,
"position": 0,
"uuid": "bfea4895-8a19-4e82-ae1c-1c591dce3094",
"is_startpage": false
}
}
}
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.
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 |
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"
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 |
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"
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 |
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"
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 |
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"
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" |
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"
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" |
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"
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) |
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"
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) |
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"
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) |
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"
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) |
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"
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.
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 |
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"
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 |
---|---|
?draft=version&starts_with=products/ |
all entries in folder products |
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"
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",
...
}
]
}
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 |
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"
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.
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.
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"
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.
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"
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.
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
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"
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.
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"
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 |
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"
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.
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.
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"
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.
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"
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
.
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"
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.
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"
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.
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"
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",
...
}
}