On this page

GraphQL

Query and change your tables with GraphQL at /graphql/v1: collections, filters, paging, mutations and nested relations, with Row Level Security.

Every project can answer GraphQL at https://<project-ref>.p.stitchdb.com/graphql/v1. The schema is built from the tables, views and foreign keys in your public schema and follows changes on its own. It uses the same API keys as the REST API, and Row Level Security decides what each request can read and write.

#Turn it on

In Studio open API › GraphQL and choose Turn on GraphQL (owners and admins). This installs the pg_graphql extension and restarts the REST API for a few seconds. Turning it off stops the endpoint; your tables and data are not changed.

#Send a query

Terminal
curl https://<project-ref>.p.stitchdb.com/graphql/v1 \
  -H "apikey: $STITCHDB_ANON_KEY" \
  -H "Authorization: Bearer $USER_ACCESS_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"query":"{ todosCollection(first: 10, orderBy: [{ id: DescNullsLast }]) { edges { node { id title } } } }"}'

Send a POST with a JSON body of query, and optionally variables and operationName. The answer is the usual { "data": …, "errors": [...] } with HTTP 200, also when the query has errors. Leave out Authorization to query as an anonymous user; with a signed-in user's access token, policies see auth.uid().

#What you get

Your schemaIn GraphQL
Table todostodosCollection with filter, orderBy, first / after paging (cursor based)
Insert, update, deleteinsertIntotodosCollection, updatetodosCollection, deleteFromtodosCollection; each returns affectedCount and records
Foreign keyA nested field on both sides (one row, or a collection)
Function public.search_todos(q text)A query field (stable functions) or a mutation (volatile functions)
Primary keyA global nodeId and node(nodeId:) lookup

Names keep the table's spelling. To get Todos and insertIntoTodosCollection style names, turn on name inflection once in the SQL editor:

SQL
comment on schema public is '@graphql({"inflect_names": true})';

#Who can see what

  • A table appears for a role only when that role has privileges on it, so anon sees no insert mutation for a table it can only read.
  • Row Level Security policies apply to every query and mutation exactly as on the REST API.
  • Requests with the service_role key bypass Row Level Security; use it only on servers.
  • Only the public schema is part of the API, like the REST API.

#GraphQL clients

Apollo, urql, graphql-request and GraphiQL work with the URL above: set the apikey header (and Authorization for signed-in users) on the client. Tools that generate types can read the schema with a standard introspection query.

#Limits

GraphQL requests count as API requests of your plan and share its requests per second and statement timeout. A collection returns at most 30 rows per page by default; page with first and after, or raise it with comment on schema public is '@graphql({"max_rows": 100})'. Rate limit rules on API › Rate limits do not apply to /graphql/v1 yet.