Skip to main content

Call the GraphQL API

You can make requests to the TakeShape GraphQL API from your project endpoint:[project-id]/v3/graphql

You can find your project's ID in its URL. When inside your project, the ID follows after

You can find and copy your project's API endpoint from the left sidebar within the API section.

Your request should include the API key you created as a Bearer Token.

For a simple request using fetch set the body of the request as a stringified object with the query key containing the GraphQL query.

const query = `{    getBookList {        items {            title        }    }}`;
fetch(`${PROJECT_ID}/v3/graphql`, {  method: 'POST',  headers: {    'Content-Type': 'application/json',    Authorization: `Bearer ${API_KEY}`  },  body: JSON.stringify({query})})  .then(res => {    return res.json();  })  .then(json => {    console.log(json);  });

The response will look like this:

{  "data": {    "getBookList": {      "items": [        {          "title": "Peter Pan"        },        {          "title": "The Lion, the Witch, and the Wardrobe"        },        {          "title": "Treasure Island"        },        {          "title": "Alice in Wonderland"        }      ]    }  }}

When you're making GraphQL requests from client-side code, you're exposing your API key to the world. Make sure you only use read-only permissions on keys you intend to use in queries from the browser.


When you create a shape with built-in data storage, TakeShape automatically creates queries for getting results.

Here's an example of a query for books and for authors, from a project using our Shape Books pattern:

query {  books: getBookList {    items {      title      author {        name      }    }  }  authors: getAuthorList {    items {      name      authored {        items {          title        }      }    }  }}

As you can see, with GraphQL we're able to get data about books and authors at the same time. Additionally, for each book we get a little information about its author, and for each author we get a little information about the books they've written.


TakeShape's automatically-generated queries support pagination with the from and size arguments and total return value.

  • from -  The offset to start from.
  • size - The maximum number of items to return. size is limited to 100.
  • total - The total number of items matching your search criteria.

With these three values, you can generate and navigate pages of your responses.

query($size: Int, $from: Int) {  getBookList(size: $size, from: $from) {    total    items {      title    }  }}
{  "size": 12,  "from": 0}


Automatically-generated queries also support two approaches to filtering using the terms and where arguments.


The terms argument will filter results that match the provided string in any of their text fields.

query($terms: String) {  getPostList(terms: $terms) {    items {      title    }    total  }}
{  "terms": "Lewis"}


The where argument allows for more complex filters that can also be combined using the boolean operators AND, OR, and NOT.

query jobs($where: TSWhereJobInput!) {  getJobList(where: $where) {    items {      title      company {        name      }    }  }}
{  "where": {    "OR": {      "title": {        "match": "front end"      },      "title": {        "match": "back end"      }    }  }}


Use the sort argument to order the results of TakeShape's automatically generated queries. It takes the name of a field to sort by and an order, either asc for ascending ordering or desc for descending ordering.

query($sort: TSSearchSort) {  getPostList(sort: $sort) {    items {      _id      title    }    total  }}
{  "sort": {    "field": "_updatedAt",    "order": "desc"  }}


TakeShape also automatically creates mutations for creating, duplicating, updating, and deleting records for shapes that use built-in data storage.

Mutations must use the mutation keyword at the beginning of their query and data as an input argument. When duplicating, updating or deleting a record, the input should contain the _id for the record you'd like to operate on. When creating a new record, you don't need to provide a unique id—one will be generated for you.

These built-in mutations will resolve with the created, duplicated, or updated record, allowing you to query their data as result of a successful mutation. When deleting records, the result will be a boolean indicating success.

mutation($newTag: CreateTagInput!) {  createTag(input: $newTag) {    result {      _id      name    }  }}
{  "newTag": {    "name": "My New Tag"  }}

Cache Control#

GraphQL and Rest resolvers support a TTL caching option. Caching can be disabled by including a header in your request.

X-TakeShape-Cache: 'false'

Rate Limits and 429 Errors#

If you receive a 429 error you are bumping into a rate limit. 429 means "Too Many Requests". You can use the following HTTP response headers to tune requests to the API.

X-RateLimit-Limit: NNNX-RateLimit-Remaining: NNNX-RateLimit-Reset: NNN

X-RateLimit-Limit - How many API requests you can make per second. Your limit is measured over a 60 second window.

X-RateLimit-Remaining - How many API requests are remaining in the window.

X-RateLimit-Reset - When the rate limit window resets.