---
title: Introduction
description: Learn the basics of the Storyblok GraphQL API, including authentication, field generation, pagination, and rate limits.
url: https://www.storyblok.com/docs/api/graphql
---

# Introduction

Storyblok’s GraphQL API offers advantages such as automated documentation and strongly typed responses. The API is a read-only endpoint optimized for fast content delivery.

> [!NOTE]
> Storyblok’s REST API is more feature-rich than the GraphQL API. For new projects, we recommend choosing the REST API if you have the flexibility or are uncertain about which to use.

The base URL for the GraphQL API depends on the server location of the space. Below are the available endpoints for different regions:

-   European Union
    
    ```plaintext
    https://gapi.storyblok.com/v2/api
    ```
    
-   United States
    
    ```plaintext
    https://gapi-us.storyblok.com/v2/api
    ```
    
-   Canada
    
    ```plaintext
    https://gapi-ca.storyblok.com/v2/api
    ```
    
-   Australia
    
    ```plaintext
    https://gapi-ap.storyblok.com/v2/api
    ```
    
-   China
    
    ```plaintext
    https://gapi.storyblokchina.cn/v2/api
    ```

## Authentication

API requests must be authenticated by providing an access token. Learn more in the [access tokens concept](/docs/concepts/access-tokens).

The following example demonstrates how to send an authenticated request to the GraphQL API:

```js
const url = "https://gapi.storyblok.com/v1/api";
const headers = {
 Token: "YOUR_PREVIEW_TOKEN",
 Version: "draft",
 "Content-Type": "application/json",
};
const body = JSON.stringify({
 query: "query { PageItems { items { name } } }",
});

fetch(url, {
 method: "POST",
 headers: headers,
 body: body,
})
 .then((response) => response.json())
 .then((data) => console.log(data))
 .catch((error) => console.error("Error:", error));
```

## Field generation

Storyblok’s GraphQL engine generates two fields for each content type using the Pascal case version of the component name:

-   For receiving a single item: `[Pascal-cased Name]Item`
-   For receiving multiple items: `[Pascal-cased Name]Items`

> [!WARNING]
> The word “content” is a reserved keyword. Only use it as a block’s technical name when combined with other characters.

For example:

-   `page` is converted to `PageItem` and `PageItems`
-   `blog-article` is converted to `BlogArticleItem` and `BlogArticleItems`

## Versions

Since its v2 release, the GraphQL API uses a new ID format for spaces and entities. Read more about the change in the [announcement](https://www.storyblok.com/mp/upcoming-update-to-the-id-format-of-spaces-and-entities#graphql-api). To access the previous version of this API, change the version path from `v2` to `v1` in your requests.

> [!WARNING]
> In GraphQL API v1, an existing bug may cause `translated_slugs` to return a null value. To fix this, switch to v2, or [contact support](https://support.storyblok.com/hc/en-us).

## Rate limits

The GraphQL API rate limits differ from the Content Delivery API limits because a single GraphQL call can replace multiple REST calls.

To accurately represent a query’s server cost, the GraphQL API calculates a rate limit score based on a normalized scale of points. A query’s score factors the `first` and `last` arguments on a parent connection and its children. Each new connection has its own point value. Points are combined with other points from the call into an overall rate limit score.

The GraphQL API rate limit is 100 points per second. Note that 100 points per second is not the same as 100 calls per second.

If the rate limit is exceeded, the API returns status code `429`. Retry the call with a delay. In a production scenario where multiple subsequent requests are sent, some requests may fail if they are sent after the per-second limit is breached.

### Estimate the cost of a query

A GraphQL object called `RateLimit` with a property called `maxcost` returns an approximation of the maximum cost of a single request with the specific query performed.

For example, if the `maxcost` of a query is 3 and 10 requests are performed, 30 points will not be consumed because 3 is merely an upward approximation. To calculate the number of requests per second, divide 100 by 3. In this example, 33 requests per second can be performed safely.

Relying on `maxcost` ensures operation within limits, avoiding a `429` response. Cached requests have no cost.

## Pagination

When querying content items, arguments can be supplied to paginate the query response. The default limit is `25` content items, and the maximum is `100`. Use the attribute `total` to retrieve the total number of items.

Use `per_page` to limit the number of results:

```graphql
{
 ProductItems(per_page: 5) {
   items {
     name
   }
   total
 }
}
```

Provide the `page` argument to go to a specific offset (`page` is multiplied by the default `per_page` value `25`):

```graphql
{
  ProductItems(page: 2) {
    items {
      name
    }
    total
  }
}
```

## GraphQL playground

The GraphQL playground provides an overview of available queries. Replace `ACCESS_TOKEN` with an [access token](/docs/concepts/access-tokens) to start experimenting with the API:

```plaintext
https://gapi-browser.storyblok.com?token=ACCESS_TOKEN
```

The playground is available in multiple regions:

-   European Union
    
    ```plaintext
    https://gapi-browser.storyblok.com
    ```
    
-   United States
    
    ```plaintext
    https://gapi-us-browser.storyblok.com
    ```
    
-   Canada
    
    ```plaintext
    https://gapi-ca-browser.storyblok.com
    ```
    
-   Australia
    
    ```plaintext
    https://gapi-ap-browser.storyblok.com
    ```

## Further resources

[Technical Limits](/pricing/technical-limits)

## Pagination

-   [Previous: Workflow Object](/docs/api/management/workflows/workflow-object)
-   [Next: Retrieve a Single Story](/docs/api/graphql/examples/retrieve-a-single-story)
