Skip to content

REST and GraphQL

View markdown

KDIGI CMS is headless: the admin panel lives at /admin, while the public website is a frontend of your choice (Next.js, Astro, Nuxt, PHP...). The frontend fetches content over REST or GraphQL provided out of the box by Payload.

Each collection has an endpoint at /api/<collection>:

Terminal window
# the 5 latest posts of one site
curl "https://cms.example.com/api/posts?where[tenant][equals]=<site-id>&sort=-publishedAt&limit=5"
# one post by slug
curl "https://cms.example.com/api/posts?where[tenant][equals]=<site-id>&where[slug][equals]=hello-world"

Main content collections: posts, pages, products, landings, taxonomies, menus, faqs, authors, redirects, media, sites. Payload's query parameters (where, sort, limit, page, depth, locale) work as usual.

The endpoint is /api/graphql. The playground is disabled in production and query complexity is capped. Note that rendering Markdown to HTML only applies to REST, so GraphQL consumers need to handle the *Md field themselves.

  • Always filter by site. Public reads do not filter by site on their own; add where[tenant][equals]=<site-id>. See Multiple sites.
  • Only published content is returned to anonymous visitors: status published and already due.
  • Markdown is rendered. REST returns HTML in the original field (content); the Markdown source is in contentMd. Shortcodes are already expanded. See Markdown editor.
  • SEO: an empty seo.title or seo.description means use the site template; the frontend replaces variables when building tags. seo.jsonLd is a prebuilt JSON-LD graph. See SEO and JSON-LD.
  • Language: content defaults to vi, with en available; pass locale to choose, missing translations fall back.
  • Menus come back as a tree in items.
  • Site config: the sites collection is publicly readable but secrets (R2 and so on) are never exposed.

Reading published content needs no login. To read drafts or write data, use a user account and API key:

Terminal window
curl -H "Authorization: users API-Key <api-key>" "https://cms.example.com/api/posts?where[status][equals]=draft"

Create the API key in the user's profile in the admin panel. A key has the same permissions as that user's role. See Roles and permissions.

  • Submit comments through the dedicated POST /api/comments/create endpoint (needs postId or productId and the site key); they start as pending. Set RECAPTCHA_SECRET to enable reCAPTCHA verification.
  • On every content save the CMS queues a job that calls POST https://<site domain>/api/cms/revalidate so your frontend refreshes its cache. This needs ENABLE_JOBS_AUTORUN=true on one instance.

The full conventions are in the REST API reference.