---
title: "Create a new post"
method: POST
path: "/api/posts"
tags: ["Posts"]
---

# Create a new post

`POST /api/posts`

# Errors
Returns error if series not found, access denied, slug/number conflict, or database error

## Request body

- CreatePostRequest — Request payload for creating a new post with content and metadata
  - `audioFileId` string, uuid, nullable — Optional audio file attachment for the post
  - `content` string, required — Full content of the post
  - `isPremium` boolean, nullable — Restrict this post to premium subscribers only
  - `isPublished` boolean, nullable — Publish this post immediately upon creation
  - `postNumber` integer, required — Episode or post number for sequencing content within the series
  - `seriesId` string, uuid, required — Series to add this post to
  - `slug` string, required — Unique URL path segment for the new post
  - `thumbnailUrl` string, nullable — Cover image URL for the post preview
  - `title` string, required — Post title for display
  - `videoFileId` string, uuid, nullable — Optional video file attachment for the post

## Response `201`

Post created successfully

- PostResponse — API response model for posts
  - `audioFileId` string, uuid, nullable — ID of associated audio file
  - `content` string, required — Post body text and content
  - `createdAt` string, date-time, nullable — Post creation timestamp
  - `id` string, uuid, required — Post's unique identifier
  - `isPremium` boolean, required — Whether the post requires premium access
  - `isPublished` boolean, required — Whether the post is published and visible to users
  - `postNumber` integer, required — Position number for ordering this post within its parent series
  - `seriesId` string, uuid, required — Parent series identifier
  - `slug` string, required — SEO-friendly URL identifier for the post
  - `thumbnailUrl` string, nullable — URL to the post's thumbnail image
  - `title` string, required — Post display title
  - `updatedAt` string, date-time, nullable — Post last update timestamp
  - `videoFileId` string, uuid, nullable — ID of associated video file

## Other responses

- `400` — Invalid post data
- `401` — Authentication required to create posts
- `403` — Access denied - post series does not belong to authenticated user
- `409` — Post creation failed - slug or number already exists in series
- `500` — Server error during post creation

## Changes

- **2025-09-22** `08a2378b4e66` — 1 info
  - endpoint added
- **2025-09-01** `a2488be8a6e4` — 1 breaking
  - api path removed without deprecation

[Change history](https://skmtc.dev/patroninc/apis/patron-api/changes/api/posts/post.md)

---

[API](https://skmtc.dev/patroninc/apis/patron-api.md) · [All operations](https://skmtc.dev/patroninc/apis/patron-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/patroninc/patron-api/revisions/08a2378b4e66/schema)
