GraphQL Content Delivery API
Beside the traditional REST API you can also use Storyblok with GraphQL, which offers a number of advantages like automated documentation and strongly typed responses. The API is a read-only endpoint and optimized for fast content delivery.
Endpoint
The GraphQL service has region-specific base URLs. Select one of the tabs below to check each region-specific URL.
The GraphQL endpoint is read-only. If you want to write, update, or delete your content or migrate from another solution, you can use our Management API for those operations.
Authentication
To communicate with the GraphQL endpoint, you will need to send an API token in the request header Token
. You can find your read-only API token in the Space Settings area, in the Access Tokens tab:
- Public: Allows access to your published content entries:
version=published
results in403
onversion=draft
- Preview: Allows access to the draft and published content entries:
version=draft
andversion=published
Rate limits
Storyblok's GraphQL API limit is different from the REST API limit.
Why are the API rate limits different? With GraphQL, one GraphQL call can replace multiple REST calls. A single complex GraphQL call could be the equivalent of thousands of REST requests.
To accurately represent the server cost of a query, the Storyblok's GraphQL API calculates a call's rate limit score based on a normalized scale of points. A query's score factors in first and last arguments on a parent connection and its children.
The formula uses the first and last arguments on a parent connection and its children to pre-calculate the potential load on Storyblok's systems.
Each new connection has its own point value. Points are combined with other points from the call into an overall rate limit score.
Storyblok's GraphQL API rate limit is 100 points per second. Note that 100 points per second is not the same as 100 calls per second: the GraphQL API and REST API use different rate limits.
If the GraphQL API reaches 100 points per second it will return the status code 429
which means you can retry your call with a delay later.
The limit for resolve_links
per story is 100 when resolving with url
.
Estimate the cost of a query
There is a GraphQL object called RateLimit
with a property called maxcost
that will return the maximum cost of a single request with that specific query you are performing.
For example, if the maxcost
of your query is 3 and you are performing 10 requests, you will not spend 30 credits because 3 is just an upwards approximation. Cached requests won't have any cost.
Going back to the previous example where the maxcost
is 3, in order to calculate the number of requests you can perform per second you need to divide 100 by 3. In this case, you can safely perform 33 requests per second.
If you rely on the maxcost
you will always make sure that you are not hitting the limit and that your requests won't get the 429
status as a response.
Send your first request
To try out the GraphQL endpoint you can send a basic curl request with your bash console.
$ curl 'https://gapi.storyblok.com/v1/api' \ -H 'Token: YOUR_PREVIEW_TOKEN' \ -H 'Version: draft' \ --data-binary '{ "query": "query { PageItems { items { name } } }" }'
GraphQL Playground
To see which queries are available you can use our GraphQL Browser. Just exchange YOUR_TOKEN
with your API token and you can play around with the API:
https://gapi-browser.storyblok.com?token=YOUR_TOKEN
The playground is also available in multiple regions. Select one of the tabs below to check each region-specific URL.
How to fetch content items
Generated fields
Storyblok's GraphQL engine generates a field for each content type you define by using the pascal case version of the component name. For every content type Storyblok generates two fields.
- One for receiving a single item: [Pascal-cased Name] Item
- And one for receiving a multiple items: [Pascal-cased Name] Items
Examples:
page
gets converted toPageItem
andPageItems
blog-article
gets converted toBlogArticleItem
andBlogArticleItems
Query a single record
To query a single content item use the pascal-cased version of your content type name and provide an id
as filter attribute which can be the id
, uuid
or full_slug
of the item.
Following an example which shows how to get the content item with "home" as full_slug
:
query { PageItem(id: "home") { name content { _uid component } } }
Query multiple records
To query multiple content items, you can use the pascal-cased version of your content type followed by the keyword Items
. There are the same filters available as from the REST API endpoint. Please check the REST API documentation for the filter options you have.
Following is an example of how to query the content type product
and filter the result to show only items from a specific folder:
query { ProductItems(starts_with: "products/") { items { id name } total } }
Note that the cached_url
property in the link field is camelCased
on the GraphQL API and not snake_cased
, which is the case with Storyblok CDN API.
Use the language parameter to get specific content in Queries
To get a specific language, you'd need to use the parameter starts_with
. when it is an item, use the full_slug
with the language code prefixed. The language parameter is used for the relations and in the case that you want to get a story by its ID
.
{ RelationsItems(starts_with: "en-ca/*") { total items { content { optionfield1(language: "en-ca") { lang } } lang } } Space { languageCodes } }
Another example can be found below:
{ RelationsItem(id: "en-ca/examplefolder/subfolder2/relations8") { lang id content { optionfield1(language: "en-ca") { id lang } } } }
If you're using an id
, use the language parameterbas shown below;
{ RelationsItem(id: "64499188", language: "en-ca") { lang id content { optionfield1(language: "en-ca") { id lang } } } }
Pagination
When querying content items, you can supply arguments that allow you to paginate the query response. Pagination allows you to request a certain amount of records at the same time. The default limit is 25 content items, and the maximum is 100. With the attribute total
you can get the total number of items which is useful for creating pagination links.
Use per_page
to limit the number of results:
{ ProductItems(per_page: 5) { items { name } total } }
By providing the page argument, you can go to a specific offset (page is multiplied by the default per_page value 25):
{ ProductItems(page: 2) { items { name } total } }
GraphQL Filter Query Examples
Here are some examples of our GraphQL filter query.
- To filter your entries for all components with names like "author" and sort them in ascending order.
- To filter your entries for components with content-type “page”.
- To filter your entries by checking if a custom array attribute contains one of the values provided.
https://gapi-browser.storyblok.com/?token={PREVIEW_TOKEN}
You can learn more about our GraphQL endpoint with our tutorial which uses GraphQL, React, and Apollo: storyblok.com/tp/storyblok-graphql-react-apollo
Resolve relations in GraphQL
With Storyblok GraphQL endpoint, you can resolve the relationship between content entries using the story id
and specifying the relationship, as seen below.
To explore the Storyblok GraphQL functionalities, use the playground at this URL: https://gapi-browser.storyblok.com/?token=insert-here-your-access-token