Strapi GraphQL API

Strapi exposes content over GraphQL through its official plugin, which generates a schema from your content types. This page covers how to configure it, which depth and result limits to set, and what to confirm before publishing the endpoint.

On this page

When a Strapi GraphQL API fits your front-end and data needs

The official GraphQL plugin adds a GraphQL endpoint to a self-hosted Strapi 5 instance and generates its schema from your content types. Its Shadow CRUD feature creates the query and mutation operations automatically, so you can start reading content without writing custom resolvers. A team that needs one request to fetch a article with its nested author, sections and media for several front ends is the typical case. Confirm the endpoint path, the generated operations and the plugin's current configuration options against the version you install, because the plugin documentation is the authority for those details.

GraphQL suits clients that need exact fields and related records in a single round trip. A mobile app that needs only a title and thumbnail, a web page that needs the full article body, and a kiosk that needs a short summary can each request their own shape from the same endpoint. REST is simpler when your content API has a small, stable set of endpoints, when most reads are plain GET requests that a CDN can cache by URL, or when one or two consumers read a fixed payload. Count the distinct data shapes your front ends need before you choose. If the answer is two or three, REST may be enough. If it is many, with deep relations, GraphQL reduces the number of calls each client makes.

GraphQL access does not drive plan choice. The Strapi self-hosted pricing page lists Community (free, unlimited users), Growth (listed at 45 US dollars per month including 3 users, plus 15 dollars per extra user) and Enterprise (custom pricing), and states that all three include REST and GraphQL APIs. The decision therefore turns on other needs, such as SSO, review workflows, audit logs or content history, which the pricing page places in higher tiers. Confirm current prices and inclusions on the pricing page before budgeting, because list prices change and a quote should follow from your written scope.

Before you launch, test the API against your own environment. Depth and result limits are off by default in the GraphQL plugin, so a client can request deeply nested relations or very large result sets unless you set limits. Build a worst-case nested query from your real content model and measure its response time and size on a staging instance. Review the permissions for each role that will call the API, including public access, because the policies you set determine which fields and entries a query can return. Document which front ends depend on which fields, so a schema change does not break a consumer without warning.

Plan ownership of the schema over time. When content types change, the generated GraphQL schema changes with them, and clients that request removed or renamed fields will fail. Decide who reviews schema changes, how front-end teams are notified, and whether you will add custom resolvers for business logic that the generated operations do not cover. Custom resolvers and policies are part of the plugin's design, so they belong in the build scope with tests, not as an afterthought. A short written decision on these points gives your team a clear basis for choosing GraphQL or REST for each consumer.

Which GraphQL configuration options fit your API

This table compares the main Strapi GraphQL choices, from schema generation to access and query limits. Read each row for when the option fits and what it costs in effort or risk. Depth and result limits are off by default, so set them deliberately before the API is exposed.

OptionWhen it fitsEffort or risk
Keep Shadow CRUD onContent types are stable and you want the schema generated from them quicklyLow build effort. Every exposed field and relation needs a permission review.
Extend the schema manuallyYou need custom types, aggregated queries or a contract that holds while content models changeHigher effort to write and test types and resolvers. Content model changes may require schema review.
Enable depth limitsAny public or partner-facing endpoint where clients can request deeply nested relationsOff by default, so it must be set. Limits that are too strict can break legitimate nested queries.
Set result limits and complexity controlsEndpoints that return lists to anonymous or untrusted clientsOff by default. Caps need measured page sizes and ongoing tuning as queries change.
Use Apollo Sandbox or similar explorersSchema exploration and query testing in development or stagingKeep it out of production or restrict it there. Confirm the plugin setting in each environment.
Allow public accessPublished content meant for any visitor, such as marketing or catalog dataPublic roles expose every field and relation granted to them. Review each content type's public permissions.
Require authenticated accessMember content, drafts or internal consumers that need identityMore client work for token or session handling. Lower exposure, but depth and result limits still apply.

Which Strapi plan GraphQL needs and what else the plan decides

GraphQL is included on every self-hosted Strapi plan, so it does not decide the plan by itself. The choice turns on admin-side features that change how editors work around the API: SSO, content history, releases, review workflows and audit logs. The cards below set out what each one covers and what to confirm before you buy.

GraphQL on all self-hosted plans

Community, Growth and Enterprise self-hosted plans all include the REST and GraphQL APIs, with unlimited entries and API calls, according to the self-hosted pricing page. Choosing a plan for the API alone therefore means choosing on other grounds. Check whether your frontend and integration partners need GraphQL, REST or both. Confirm the current plan terms on the pricing page before you sign, since plan contents can change.

Growth price and seat count

The Growth plan is listed at 45 US dollars per month including 3 users, with 15 dollars per additional user, according to the self-hosted pricing page. Seats are the recurring cost to watch. Count roles by who signs in to the admin panel. API consumers who only read published content may not need a seat, but confirm that with Strapi before you size the plan. Recount seats each time you add an editor or reviewer.

SSO for administrator login

SSO is an add-on on Growth and included on Enterprise. It covers administrator login to the admin panel through an identity provider, with auto-registration, a default role and an optional local login lock-out. It does not authenticate end users of your GraphQL API, which the Users and Permissions plugin handles separately. Decide before purchase whether editors need the add-on, and plan how an editor who leaves the identity provider is removed from the admin panel.

Content history and releases from Growth

Content history and releases both start at the Growth plan. Content history lets editors compare and restore earlier versions of a document, and releases group changes across content types for a coordinated publish. Editors who use these tools change content in a different order than API consumers may expect. Test how a restored or scheduled version appears in your GraphQL queries before editors depend on it, and confirm retention settings with Strapi.

Review workflows and audit logs on Enterprise

Review workflows and audit logs are Enterprise features. Review workflows add approval stages that content passes through before publishing, and audit logs record administrator actions for accountability. If your approval rules must hold for writes made through the API as well as the admin panel, get that confirmed by Strapi in writing and test it. Audit logs support evidence gathering, but they do not replace a retention policy that your compliance team has approved.

Enterprise pricing and what to request

Enterprise pricing is custom and is not listed on the self-hosted pricing page, so the quote depends on your requirements. Ask for the price in writing, including which features it covers, the user count, support terms and the license terms that apply to your deployment. Ask Strapi which of SSO, review workflows, audit logs and any other features you need are included and which are add-ons.

How to enable and configure the GraphQL plugin in Strapi 5

This sequence takes a self-hosted Strapi 5 project from a supported stack to a GraphQL endpoint that exposes only the content, depth and result sizes your team has approved. Each step ends with a check so the team can confirm the behavior before moving on.

  1. Confirm the Strapi 5 and runtime versions

    The platform team confirms the exact Strapi 5 release, the Node.js version and the database engine against the current installation requirements before anything is installed. Strapi 5 supports PostgreSQL 14 or later, MySQL 8.0 or later, MariaDB 10.3 or later and SQLite 3. It does not support MongoDB or other NoSQL databases, and it runs only on Active or Maintenance LTS Node.js versions. Confirm the Node.js line in the installation docs on the day of the build, since supported lines change. Also confirm your plan: the self-hosted plans include REST and GraphQL APIs. Done when the environment matrix is written down and signed off by the lead engineer.

  2. Back up and prepare a staging copy

    Before any change, the team takes a verified database backup and restores it into a staging instance that matches production's Strapi version, plugins and database engine. Strapi's migration guidance says to back up the database first because downgrading is not supported, and the same caution applies to any change that alters the API surface. All GraphQL work happens in staging first, and changes move to production only after the checks in the later steps pass. Done when a test restore has completed and the team has recorded where the backup is stored and who can run the restore.

  3. Install and enable the official GraphQL plugin

    A developer installs the official GraphQL plugin in the staging project, confirms that its version matches the Strapi 5 release in use, and enables it in the plugin configuration. Confirm the package name and compatible version in the official plugin documentation before installing. Rebuild the admin panel and restart the server. Then send a simple query for the standard __typename field to the GraphQL endpoint. Done when the endpoint answers in staging. Decide now whether the GraphQL playground stays enabled in production, because it lets anyone explore the schema.

  4. Decide the Shadow CRUD scope

    Shadow CRUD generates the GraphQL schema from your content types, so the team decides which collections receive queries and mutations before anything is exposed. Product, editorial and security owners list each content type and mark it as read only, read and write, or excluded. Fields that hold internal notes, draft data or personal information should stay out of the generated types. Use the plugin configuration to exclude them where your version supports it, and confirm the option names in the documentation. Done when the scope sheet is approved and the generated schema has been compared line by line against that sheet.

  5. Set depth and result limits

    Depth and result limits are off by default, so the team sets them explicitly before any public traffic reaches the endpoint. Depth limits how many levels of nested relations one query may traverse, and result limits cap how many entries one request can return. Choose values from the content model: start with the deepest relation chain that editors truly need to render a page, then test around it. Confirm the exact configuration keys in the plugin documentation for your version. Check that a deeply nested query in staging is rejected at the configured depth and that a request for an oversized list is capped. Done when both checks pass.

  6. Configure public and authenticated permissions

    In the admin panel, the team sets permissions separately for the Public and Authenticated roles on each content type in the approved scope. Grant read actions only where the scope requires them, and leave create, update and delete off for public access. Hide sensitive fields from the public role. End-user accounts come from the Users and Permissions plugin, not from SSO, so create the authenticated test account there. Check that a public collection query returns only allowed published entries, and that a public request for a restricted field returns an error. Done when both role checks match the signed-off permissions matrix.

  7. Verify, document and promote to production

    The team runs the full check set in staging: a single collection query, the restricted field test for a public request, and the nested depth test. A second engineer repeats one check independently. The change record captures the Strapi version, plugin version, limits, permissions matrix and check results. Production receives the same configuration during an agreed window, after a fresh backup taken immediately before the change. Repeat the three checks in production and confirm they match staging. Before any future Strapi upgrade, repeat the backup and staging steps first. Done when the change record is signed off.

Custom resolvers and policies: where GraphQL authorization is enforced

Authorization for a custom GraphQL resolver is enforced in the resolver, not in the Strapi permission screens alone, so each resolver needs its own check and its own tests. A custom resolver adds a field to a type, combines data from several content types or external services, or changes how a query behaves, such as default filters, sorting or pagination. Each one creates an entry point that generated CRUD queries never passed through. Before you write any resolver, list every role that should reach it and the data it may return.

Strapi permissions are set per content type and per route for each role in the Users and Permissions plugin. Those settings describe REST routes, and they do not automatically govern every GraphQL operation. A role allowed to read articles over REST may not be the role you want reading the same articles through a custom query that joins authors, drafts or internal notes. The reverse also happens: a GraphQL query can expose a relation or field that the REST route for that role hides. Confirm with your plugin version how Strapi permissions are applied to generated and custom GraphQL operations, including whether relations and nested fields are checked, and record the answer in your design notes.

Put the control where the data is read. Inside the resolver, identify the authenticated user from the request context, reject unauthenticated calls before any query runs, and check ownership or role for each record returned. Reuse the same service and permission logic that the REST path uses, rather than copying field lists into the resolver, so the two paths cannot drift apart. Filter nested relations with the caller's rights, and never rely on the front end to hide fields. Illustrative example: a resolver that returns order status joined to customer contact details should return contact data only to support staff with the matching role, and return status alone to the customer who owns the order.

Test denial cases for each role and each custom resolver, in a staging environment seeded with accounts for every role. Cover at least an unauthenticated request, a role that should have no access, a valid role asking for a record it does not own, a nested relation or field outside its permissions, and any mutation the resolver exposes. Assign a named owner for these tests and keep the results as evidence. Rerun them after any Strapi upgrade, plugin change or new content type, because schema changes can alter which paths reach a resolver. Ask your partner or internal team to confirm, in writing, which roles were tested and which denial cases were covered.

Securing the Strapi GraphQL API against denial of service

Denial of service through GraphQL usually comes from valid-looking queries that ask for too much. The controls below work in layers: limit what a query can request, watch what queries cost, meter the clients that send them, and remove the schema details attackers use to plan. DeployOpen tests and documents each control as part of the implementation.

Nested and expensive queries

GraphQL lets a client request related entries several levels deep in one call, and each level can multiply database work. A single query that combines nested relations, large lists and heavy fields can hold server resources long enough to slow the API for every other client. Map which content types have relations that loop back on themselves, and which fields resolve through custom code or extra lookups. Those paths define the worst case your limits must cover.

Depth and result limits

Depth and result limits are off by default, so a new Strapi GraphQL setup accepts queries of any depth and any page size until you configure them. Set a maximum depth that matches the relations your front end actually uses, and cap how many entries one list can return. Test each limit with the queries your front end sends, then with deliberately deep examples, and confirm that rejected queries return a clear error instead of a server failure.

Query cost logging and monitoring

Limits stop the worst queries, but you also need visibility into the ones that come close. Log the operation name, requested depth, response time and client identity for GraphQL requests, and send those logs to the monitoring platform you already run. Alert on sustained spikes in slow requests from a single client. Strapi audit logs are an Enterprise feature and track admin actions, so on other plans confirm which evidence you can keep for API traffic and where it is stored.

Rate limiting at the gateway

Rate limiting belongs at the edge, where requests from one client can be counted before they reach Strapi. Place the GraphQL endpoint behind your API gateway, set request limits per API key or client identity, and apply limits that suit the traffic pattern of your front end. Confirm how the gateway counts a request that bundles several operations, because a per-request count does not measure the cost of each operation inside it.

Disable introspection and the playground

Introspection lets anyone download the full schema, and the GraphQL playground gives them an interactive console to test queries against it. On public endpoints, turn both off in production and keep them only in development environments behind authentication. Then test from outside your network that the schema cannot be retrieved anonymously. Confirm the exact setting names for your Strapi version and GraphQL plugin, since configuration options can change between releases.

Supported Strapi and Node.js versions

Fixes for denial of service issues ship in Strapi and Node.js releases, so the platform under your limits must stay current. Strapi 5 runs only on Active or Maintenance LTS Node.js versions, and Strapi v4 reached end of life on April 30, 2026, with no further updates after its final release. Review both versions against each vendor's support schedule on a set cadence, and plan upgrades before a version leaves support.

Questions teams ask before building a Strapi GraphQL API

What drives the cost of building a Strapi GraphQL API?

The cost follows the size of the schema and the rules around it. The main drivers are the number of content types and components exposed, the number of custom resolvers beyond the generated schema, the authorization rules that decide who sees which fields, the number of client applications that query the API, the depth of testing before launch, and where the platform is hosted. Each one adds design, build and verification work. Ask for a written scope that lists each content type, resolver, policy and client, with the testing approach stated for each. Keep Strapi's license cost separate from the build fee. Strapi's self-hosted pricing page lists the Growth plan at 45 US dollars per month including 3 users, plus 15 dollars per extra user. Ask the quote to show one-time build work apart from recurring hosting, licenses and support.

How long does a Strapi GraphQL API project usually take?

Duration depends on the same drivers as cost, so no single timeline fits every project. A small schema with one client and standard permissions moves faster than a large content model with custom resolvers, several front ends and detailed authorization. Your team's availability for reviews also sets the pace, especially for content modeling, which is hard to change once editors and client applications depend on it. Ask for milestones in the written scope: schema design, resolver build, policy build, depth and limit tuning, abuse testing and handover. Each milestone should name its deliverable and the person who signs it off. If a provider offers a duration before reviewing your content model and client list, ask which assumptions it rests on.

What does our team need to provide before a GraphQL build starts?

Your team supplies the decisions and access that only your organization can make. Start with the content model: which content types and fields are public, which are internal, and which need localization or draft handling. Then list the client applications that will query the API, their expected query patterns, and any data sources outside Strapi that resolvers must read. Authorization needs your role definitions and rules for who can read, create and change each type. You also need a staging environment, database access for backups and test data, and a named owner who can approve changes. Confirm early whether the Strapi instance will run on your infrastructure, since hosting and network rules affect the build and its testing.

Can an internal team build a Strapi GraphQL API without outside help?

A team with Strapi and Node.js experience can build a GraphQL API without a partner. The parts that most often need an outside review are authorization and query protection. The GraphQL plugin generates a schema from your content types, but custom resolvers and policies decide what callers can reach. Depth and result limits are off by default, so an unprotected endpoint can be expensive to query. Before deciding, check whether your team includes someone who has tested GraphQL endpoints for abuse, and whether it can maintain the code through future Strapi upgrades. A written scope lets you compare your own estimate with an outside quote for the same deliverables.

Does exposing GraphQL in Strapi require a paid plan?

The GraphQL API itself does not require a paid plan. Strapi's self-hosted pricing page lists REST and GraphQL APIs in every self-hosted plan, including Community, which is free with unlimited users. Growth is listed at 45 US dollars per month including 3 users, plus 15 dollars per extra user. Enterprise pricing is custom. Paid plans matter for admin features: SSO is an add-on for Growth and included in Enterprise, while audit logs and review workflows are Enterprise features. Confirm current terms on the pricing page before you budget, because plan details change. Your provider's fee for building the API is a separate cost and should appear as its own line in the written scope.

How do we keep GraphQL queries from overloading our Strapi server?

Set depth and result limits explicitly, because Strapi leaves them off by default and an open query can request deeply nested relations or very large lists. Depth limits cap how many levels of related content one query can traverse. Result limits cap how many items a query can return. Pair them with a review of which relations are exposed, since a relation that is not exposed cannot be traversed. Then test the endpoint with deliberately heavy queries in staging and record response times and errors. State the depth of this testing in the written scope, because a quick check and a sustained abuse test cover different risks. Recheck the limits after each schema change, since a new relation can open a new path to data.

How should authorization be planned for a Strapi GraphQL API?

Plan authorization as a list of rules per content type, role and operation before any resolver is written. Strapi's permissions control access to generated content, while custom resolvers and policies control anything the generated schema does not cover. Map each role to the operations it can run and the fields it can read, including whether it can see draft or only published content. Include rules for relations, since a permitted type can still expose linked data that should stay private. Ask the team building the API to write test cases for each rule, including denied requests, and to run them in staging after every change. Confirm with your security team which roles touch customer or personal data, because those rules need the closest review.

What to confirm in your environment before going live

A GraphQL endpoint inherits the constraints of its version, database, hosting and gateway, and it can expose more query paths than a REST API. The cards below list what to verify in your own environment before any traffic reaches the API. None of them is a performance guarantee, so load testing in your environment is required before launch.

Plugin version and Strapi 5 compatibility

Confirm the exact GraphQL plugin version you intend to run and check its compatibility with the target Strapi 5 release, including the release you pin in production. Strapi 5 minor releases ship frequently (v5.58.0 was published on October 14, 2026), so pin both the core and the plugin and retest after each upgrade. Record the versions in your change log before go-live.

Database and Node.js support matrix

Check the supported database versions in the Strapi installation docs: PostgreSQL 14 or later, MySQL 8.0 or later, MariaDB 10.3 or later, or SQLite 3. MongoDB and other NoSQL databases are not supported. Also confirm that your Node.js version is on Strapi's Active or Maintenance LTS list. Verify the matrix against the docs for your exact release, since support windows change.

Behavior under your hosting model

Test how the GraphQL endpoint behaves on the hosting you chose, whether that is your own containers, virtual machines or a managed Strapi Cloud project. Check process restarts, horizontal scaling with shared sessions and cache, file storage for media, and how long-running queries are timed out by the load balancer. Confirm whether the plugin's query depth and result limits are configured in the environment, since they are off by default.

Gateway for rate limiting

Decide whether a gateway in front of the endpoint must enforce per-client rate limits, request size limits and authentication before requests reach Strapi. The plugin's depth and result limits protect the server from expensive queries, but they do not replace throttling of request volume. If you already run an API gateway, confirm that it passes the GraphQL request body and headers through unchanged to Strapi.

GraphQL and REST permission gaps

Compare the role permissions that apply to the GraphQL API with those on the REST API for each content type, including find, findOne, create, update and delete actions. Shadow CRUD schema generation can expose fields and relations that a REST route would not return by default, so review field-level and relation-level access. Test every role with both query paths before go-live.

Load testing in your environment

This page does not guarantee performance figures for any query shape, dataset size or concurrency level. Build a test plan that uses your real schema, realistic nested queries and your production-sized dataset, and run it on the same infrastructure you will operate. Use the results to set depth, complexity and result limits, and repeat the test after each Strapi or plugin upgrade.

How DeployOpen scopes and delivers a Strapi GraphQL API

DeployOpen plans, implements, hardens and documents self-hosted Strapi GraphQL APIs inside your own cloud accounts, data centers or air-gapped networks. Engagements are fixed-scope, with the schema, limits and policies agreed in writing before build starts. Ongoing support is available as a retainer for changes after go-live.

How we scope

  • The written scope lists which content types Shadow CRUD exposes and which are left out of the GraphQL schema.
  • Depth limits, result limits and any other query controls are named with agreed values before build starts.
  • Engagements are fixed-scope, so scope, deliverables and timelines are agreed in writing before work starts.

How we build

  • Custom resolvers and policies are built for the business logic that Shadow CRUD cannot express.
  • Permissions are tested per role, so anonymous and authenticated queries return only the fields each role may read.
  • Limits are tested with deeply nested and oversized queries before go-live to confirm they reject requests.

How we hand over

  • Handover includes the schema, resolver and policy source code, and configuration in your own version control.
  • Documentation covers the public query surface, the limits in force, and how to change them safely.
  • Your team receives a walkthrough of the Strapi GraphQL deployment, running in infrastructure you control.

How we support

  • Ongoing support is available as a retainer covering Strapi upgrades, dependency changes and query limit reviews.
  • Schema changes after a Strapi upgrade are re-checked against the policies and limits before release.
  • Continuous security testing of the API can be added as a separate engagement or retainer.

Sources and further reading

Talk to our team.

Tell us what you're working on, whether it's a deployment, an audit, a security test or a cyber range. You'll speak with an engineer who can help you scope it.

  • 30-minute call: free, with no obligation.
  • NDA on request: we can sign before you share details.
  • Clear next steps: a scope and plan after the call.