DEV Community

Alex Spinov
Alex Spinov

Posted on

Payload CMS Has a Free API: The TypeScript Headless CMS That's Actually Developer-First

Payload is a TypeScript-first headless CMS that generates REST and GraphQL APIs from your config. It runs on Next.js, gives you full code control, and is completely free and open source.

Why Payload?

  • Code-first — config in TypeScript, not GUI clicks
  • Next.js native — runs inside your Next.js app
  • Auto REST + GraphQL — generated from your schema
  • Auth built-in — users, roles, field-level access control
  • Open source — MIT license, self-host free

Quick Start

npx create-payload-app@latest my-cms
cd my-cms
npm run dev
# Admin: http://localhost:3000/admin
# API: http://localhost:3000/api
Enter fullscreen mode Exit fullscreen mode

Define Collections (Schema)

// collections/Articles.ts
import type { CollectionConfig } from 'payload';

export const Articles: CollectionConfig = {
  slug: 'articles',
  admin: {
    useAsTitle: 'title',
  },
  access: {
    read: () => true,
    create: ({ req: { user } }) => !!user,
  },
  fields: [
    { name: 'title', type: 'text', required: true },
    { name: 'slug', type: 'text', unique: true },
    { name: 'content', type: 'richText' },
    { name: 'status', type: 'select',
      options: ['draft', 'published', 'archived'],
      defaultValue: 'draft',
    },
    { name: 'author', type: 'relationship', relationTo: 'users' },
    { name: 'tags', type: 'array',
      fields: [{ name: 'tag', type: 'text' }],
    },
    { name: 'coverImage', type: 'upload', relationTo: 'media' },
    { name: 'publishedAt', type: 'date' },
  ],
};
Enter fullscreen mode Exit fullscreen mode

REST API (Auto-Generated)

# List articles
curl http://localhost:3000/api/articles

# Filter + sort + paginate
curl 'http://localhost:3000/api/articles?where[status][equals]=published&sort=-publishedAt&limit=10'

# Get by ID
curl http://localhost:3000/api/articles/ARTICLE_ID

# Create (authenticated)
curl -X POST http://localhost:3000/api/articles \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"title": "Hello World", "status": "published"}'

# Update
curl -X PATCH http://localhost:3000/api/articles/ARTICLE_ID \
  -H 'Authorization: Bearer TOKEN' \
  -H 'Content-Type: application/json' \
  -d '{"status": "archived"}'

# Upload media
curl -X POST http://localhost:3000/api/media \
  -H 'Authorization: Bearer TOKEN' \
  -F 'file=@photo.jpg'
Enter fullscreen mode Exit fullscreen mode

Local API (Server-Side — Type-Safe)

// In your Next.js pages/API routes
import { getPayload } from 'payload';
import config from '@payload-config';

const payload = await getPayload({ config });

// Fully typed queries
const articles = await payload.find({
  collection: 'articles',
  where: { status: { equals: 'published' } },
  sort: '-publishedAt',
  limit: 10,
});

// Create
const newArticle = await payload.create({
  collection: 'articles',
  data: {
    title: 'New Article',
    status: 'draft',
  },
});
Enter fullscreen mode Exit fullscreen mode

Key Features

Feature Details
Framework Next.js native
API REST + GraphQL + Local (type-safe)
Database Postgres, MongoDB
Auth Built-in, field-level access
Media Upload, image resize, S3
Versions Draft/publish, revisions
Localization Built-in i18n
Live Preview Real-time content preview

Resources


Building content-driven apps? Check my Apify actors or email spinov001@gmail.com.

Top comments (0)