DEV Community

Alex Spinov
Alex Spinov

Posted on

Payload CMS Has a Free API: The TypeScript-First Headless CMS for Developers

What is Payload CMS?

Payload is a headless CMS and application framework built entirely in TypeScript. Unlike Strapi or Contentful, Payload generates a full admin panel, REST API, and GraphQL API from your TypeScript config — with zero code generation and full type safety.

Why Payload?

  • Free and open-source — MIT license, self-hosted
  • TypeScript-native — config IS your schema, types are automatic
  • Next.js integration — runs inside your Next.js app (v3)
  • Database flexible — PostgreSQL, MongoDB, SQLite
  • Admin panel — beautiful, auto-generated from config
  • Access control — field-level permissions built in

Quick Start

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

Define Collections

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

export const Posts: CollectionConfig = {
  slug: 'posts',
  admin: {
    useAsTitle: 'title'
  },
  access: {
    read: () => true,
    create: ({ req: { user } }) => Boolean(user),
    update: ({ req: { user } }) => user?.role === 'admin',
  },
  fields: [
    { name: 'title', type: 'text', required: true },
    { name: 'slug', type: 'text', unique: true, admin: { position: 'sidebar' } },
    { name: 'content', type: 'richText' },
    { name: 'featuredImage', type: 'upload', relationTo: 'media' },
    { name: 'author', type: 'relationship', relationTo: 'users' },
    { name: 'tags', type: 'array', fields: [
      { name: 'tag', type: 'text' }
    ]},
    { name: 'status', type: 'select', options: [
      { label: 'Draft', value: 'draft' },
      { label: 'Published', value: 'published' }
    ], defaultValue: 'draft' },
    { name: 'publishedAt', type: 'date' }
  ]
};
Enter fullscreen mode Exit fullscreen mode

Auto-Generated API

# REST API (automatic)
GET    /api/posts           # List posts
GET    /api/posts/:id       # Get single post
POST   /api/posts           # Create post
PATCH  /api/posts/:id       # Update post
DELETE /api/posts/:id       # Delete post

# With query parameters
GET /api/posts?where[status][equals]=published&sort=-publishedAt&limit=10

# GraphQL (also automatic)
POST /api/graphql
Enter fullscreen mode Exit fullscreen mode

Use in Next.js Pages

// app/blog/[slug]/page.tsx
import { getPayload } from 'payload';
import config from '@payload-config';

export default async function BlogPost({ params }: { params: { slug: string } }) {
  const payload = await getPayload({ config });

  const { docs } = await payload.find({
    collection: 'posts',
    where: { slug: { equals: params.slug } }
  });

  const post = docs[0];
  if (!post) return notFound();

  return (
    <article>
      <h1>{post.title}</h1>
      <RichText content={post.content} />
    </article>
  );
}
Enter fullscreen mode Exit fullscreen mode

Payload vs Alternatives

Feature Payload Strapi Contentful Sanity
Cost Free (self-host) Free (self-host) $300/mo $99/mo
TypeScript Native Plugin SDK GROQ
Next.js integration Built-in (v3) API calls API calls Plugin
Admin UI Auto-generated Auto-generated Hosted Hosted
Database PG, Mongo, SQLite PG, MySQL, SQLite Cloud only Cloud only
Access control Field-level Role-based Role-based GROQ filters

Real-World Impact

A media company used Contentful at $300/month for 5 editors. As content grew, they hit API rate limits and needed the $750 plan. After migrating to Payload on a $20 VPS: unlimited API calls, unlimited content, custom admin workflows, and the same editors found the auto-generated admin panel more intuitive. Saved $8,760/year.


Building content-driven applications? I help teams choose and implement the right CMS. Contact spinov001@gmail.com or explore my data tools on Apify.

Top comments (0)