Superblog API Reference

This is an automatically generated documentation for the API endpoints of the Superblog platform. You can find the available API endpoints, expected request payload format and response format. If you need more info, just open the dashboard in your browser and open the network tools to find the api endpoint and request/response data.

Intro

Superblog API is completely based on REST. It is as intuitive as it can get.

Entire superblog dashboard is built with REST API. So, any action that you can do in dashboard can also be done with API.

You need to be on the SUPER plan for API access.

Note

Sample code is shown in the docs is in Javascript. But you can use ANY language to interact with superblog API.

Authentication

1. Generate an API key from View Dashboard > Data > API Keys section.
2. Pass the obtained API key with every request in a custom header x-superblog-access-key.

Example

#### Javascript

javascript
const response = await fetch("https://write.superblog.ai/api/sites", {
headers: {
// .....
// .....
"x-superblog-access-key": "your-api-key",
}
});

const data = await response();

POST

Request Format:

// RequestBody
{email: string}

Response Format:

{
"error": "Email is required"
}

---

/api/auth/signout-everywhere

POST

---

/api/cron/scheduler

GET

Response Format:

{
"error": "Unauthorized"
}

---

/api/cron/trial-checker

GET

Response Format:

{
"error": "Unauthorized"
}

---

/api/key/zapier/leads

GET

---

/api/sites

GET

Request Format:

// SiteInputSchema
{
site: newSiteSchema,
}

Response Format:

{
"sites": "...",
"hideCreateSuperblogButton": "...",
"pendingInvoices": "...",
"billingTexts": "..."
}
{
"newSite": "..."
}

---

POST

Request Format:

// SiteInputSchema
{
site: newSiteSchema,
}

Response Format:

{
"sites": "...",
"hideCreateSuperblogButton": "...",
"pendingInvoices": "...",
"billingTexts": "..."
}
{
"newSite": "..."
}

---

/api/sites/supername/{supername}

GET

Response Format:

{
"site": {
"supername": "...",
"customDomain": "...",
"template": "..."
}
}
{
"deletedData": "..."
}

---

DELETE

Response Format:

{
"site": {
"supername": "...",
"customDomain": "...",
"template": "..."
}
}
{
"deletedData": "..."
}

---

/api/sites/supername/{supername}/ai-helper

GET

Request Format:

// inputSchema
{
keyword: yup.string().min(6).max(50),
}

Response Format:

{}

---

POST

Request Format:

// RequestBody
{keyword: string}

Response Format:

{}

---

/api/sites/supername/{supername}/analytics

GET

Response Format:

{
"analytics": "...",
"pirschAccessLink": "..."
}

---

/api/sites/supername/{supername}/api-keys

GET

Request Format:

// RequestBody
{apiKeyId: string}

Response Format:

{
"apiKeys": "..."
}
{
"apiKey": "..."
}

---

POST

Request Format:

// RequestBody
{apiKeyId: string}

Response Format:

{
"apiKeys": "..."
}
{
"apiKey": "..."
}

---

DELETE

Request Format:

// RequestBody
{apiKeyId: string}

Response Format:

{
"apiKeys": "..."
}
{
"apiKey": "..."
}

---

/api/sites/supername/{supername}/billing

GET

Response Format:

{
"subscription": "..."
}

---

/api/sites/supername/{supername}/billing/stripe/invoices

GET

Response Format:

{
"error": "Too many requests"
}
{
"error": "No site or subscription found"
}
{
"invoices": "..."
}

---

/api/sites/supername/{supername}/categories

GET

Request Format:

// categoryInputSchema
{
category: z.object({
name: z
.string()
.max(SITE_NAME_MAX_LENGTH)
.trim()
.min(1)
.refine((value) => {
return !!getSlugFromText({ text: value, keepSlash: false }

// categoryDeleteSchema
{
category: z.object({
id: z.string(),
}

// categoryUpdateSchema
{
category: z.object({
id: z.string(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
slug: z.string().trim(),
iconName: z.string().trim().min(1, 'Icon is required'),
}

Response Format:

{
"categories": "...",
"site": {
"customDomain": "...",
"template": "..."
}
}
{
"category": "..."
}

---

POST

Request Format:

// categoryInputSchema
{
category: z.object({
name: z
.string()
.max(SITE_NAME_MAX_LENGTH)
.trim()
.min(1)
.refine((value) => {
return !!getSlugFromText({ text: value, keepSlash: false }

// categoryDeleteSchema
{
category: z.object({
id: z.string(),
}

// categoryUpdateSchema
{
category: z.object({
id: z.string(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
slug: z.string().trim(),
iconName: z.string().trim().min(1, 'Icon is required'),
}

Response Format:

{
"categories": "...",
"site": {
"customDomain": "...",
"template": "..."
}
}
{
"category": "..."
}

---

PATCH

Request Format:

// categoryInputSchema
{
category: z.object({
name: z
.string()
.max(SITE_NAME_MAX_LENGTH)
.trim()
.min(1)
.refine((value) => {
return !!getSlugFromText({ text: value, keepSlash: false }

// categoryDeleteSchema
{
category: z.object({
id: z.string(),
}

// categoryUpdateSchema
{
category: z.object({
id: z.string(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
slug: z.string().trim(),
iconName: z.string().trim().min(1, 'Icon is required'),
}

Response Format:

{
"categories": "...",
"site": {
"customDomain": "...",
"template": "..."
}
}
{
"category": "..."
}

---

DELETE

Request Format:

// categoryInputSchema
{
category: z.object({
name: z
.string()
.max(SITE_NAME_MAX_LENGTH)
.trim()
.min(1)
.refine((value) => {
return !!getSlugFromText({ text: value, keepSlash: false }

// categoryDeleteSchema
{
category: z.object({
id: z.string(),
}

// categoryUpdateSchema
{
category: z.object({
id: z.string(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
slug: z.string().trim(),
iconName: z.string().trim().min(1, 'Icon is required'),
}

Response Format:

{
"categories": "...",
"site": {
"customDomain": "...",
"template": "..."
}
}
{
"category": "..."
}

---

/api/sites/supername/{supername}/categories/bulk/delete

DELETE

Request Format:

// deleteSchema
{
categoryIds: yup.array().of(yup.string()).required(),
}

Response Format:

{
"categories": "..."
}

---

/api/sites/supername/{supername}/categories/bulk/exclude-posts-homepage

PUT

Request Format:

// categoryUpdateSchema
{
categoryIds: yup.array().of(yup.string()).default([]),
}

Response Format:

{
"categories": "..."
}

---

/api/sites/supername/{supername}/categories/bulk/homepage

PUT

Request Format:

// categoryUpdateSchema
{
categoryIds: yup.array().of(yup.string()).default([]),
}

Response Format:

{
"categories": "..."
}

---

/api/sites/supername/{supername}/categories/{categoryid}

GET

Response Format:

{
"category": "..."
}

---

/api/sites/supername/{supername}/checklist

GET

Response Format:

{
"checklist": "...",
"userRole": "..."
}

---

/api/sites/supername/{supername}/custom-domain

GET

Response Format:

{
"hostingData": {
"customDomain": "...",
"subdirectoryProxyType": "...",
robotsConfig
}
}
{
"hostingData": {
"customDomain": "...",
"netlifyDomain": "...",
"netlifySiteId": "..."
}
}

---

POST

Response Format:

{
"hostingData": {
"customDomain": "...",
"subdirectoryProxyType": "...",
robotsConfig
}
}
{
"hostingData": {
"customDomain": "...",
"netlifyDomain": "...",
"netlifySiteId": "..."
}
}

---

/api/sites/supername/{supername}/custom-domain/cf/connect

POST

Response Format:

{
"success": true,
"data": {
"hostname": "...",
"isSubdirectory": true
}
}
{
"success": true,
"data": {
"hostname": "..."
}

---

/api/sites/supername/{supername}/custom-domain/cf/disconnect

POST

Response Format:

{
"success": true,
"message": "Domain disconnected successfully"
}

---

/api/sites/supername/{supername}/custom-domain/cf/refresh

POST

Response Format:

{
"error": "Too many requests"
}
{
"success": true,
"data": {
"sslStatus": "active",
"hostnameVerificationStatus": "active",
"lastCheck": "...",
errors
}
}
{
"success": true,
"data": {
"sslStatus": "...",
"hostnameVerificationStatus": "...",
"dnsRecords": "...",
"lastCheck": "...",
errors
}
}

---

/api/sites/supername/{supername}/custom-domain/cf/status

GET

Response Format:

{
"success": true,
"data": null
}
{
"success": true,
"data": {
"sslStatus": "...",
"hostnameVerificationStatus": "...",
"dnsRecords": "...",
"hostname": "...",
"isSubdomain": "...",
"lastValidationCheck": "...",
"createdAt": "...",
"updatedAt": "..."
}
}

---

/api/sites/supername/{supername}/custom-domain/subdirectory-proxy-type

POST

Request Format:

// RequestBody
{subdirectoryProxyType: string}

Response Format:

{
"subdirectoryProxyType": "...",
"customDomain": "..."
}

---

GET

Request Format:

// RequestBody
{subdirectoryProxyType: string}

Response Format:

{
"subdirectoryProxyType": "...",
"customDomain": "..."
}

---

/api/sites/supername/{supername}/dashboard

GET

Response Format:

{
"error": {
"message": "Access denied",
"code": "INSUFFICIENT_PERMISSIONS",
"details": "Dashboard access is restricted to Owner,
"Admins": "...",
and Editors only.",
"userRole": "...",
"allowedRoles": ['OWNER',
'ADMIN',
'EDITOR']
}
}
{
"error": {
"message": "..."
}
}

---

/api/sites/supername/{supername}/deploy

POST

Response Format:

{
"deployLog": "..."
}

---

/api/sites/supername/{supername}/deploy/read

GET

Response Format:

{
"deployLog": "...",
"avgDeployDuration": "...",
"deploysInLast24h": "..."
}

---

GET

Response Format:

{
"footerModule": "..."
}

---

POST

Response Format:

{
"footerModule": "..."
}

---

DELETE

Response Format:

{
"footerModule": "..."
}

---

/api/sites/supername/{supername}/i18n

GET

Request Format:

// inputSchema
{
locale: yup.string().required().max('custom'.length),
localeData: localeDataSchema,
}

Response Format:

{
"locale": "...",
"localeData": "..."
}
{
"...data": "..."
}

---

PUT

Request Format:

// inputSchema
{
locale: yup.string().required().max('custom'.length),
localeData: localeDataSchema,
}

Response Format:

{
"locale": "...",
"localeData": "..."
}
{
"...data": "..."
}

---

/api/sites/supername/{supername}/i18n/reset

POST

Response Format:

{
"locale": "...",
"localeData": "..."
}

---

/api/sites/supername/{supername}/leads

GET

Request Format:

// deleteSchema
{
leadId: yup.string(),
}

Response Format:

{
"leads": "...",
"totalLeadsCount": "...",
"totalPages": "...",
"currentPage": "..."
}
{
"lead": "..."
}

---

DELETE

Request Format:

// RequestBody
{leadId: string}

// deleteSchema
{
leadId: yup.string(),
}

Response Format:

{
"leads": "...",
"totalLeadsCount": "...",
"totalPages": "...",
"currentPage": "..."
}
{
"lead": "..."
}

---

/api/sites/supername/{supername}/leads-config

GET

Response Format:

{
"leadsConfig": "...",
"site": "..."
}
{
"leadsConfig": "..."
}

---

POST

Response Format:

{
"leadsConfig": "...",
"site": "..."
}
{
"leadsConfig": "..."
}

---

/api/sites/supername/{supername}/leads-popup-config

GET

Response Format:

{
"leadsPopupConfig": "...",
"site": "..."
}
{
"leadsPopupConfig": "..."
}

---

POST

Response Format:

{
"leadsPopupConfig": "...",
"site": "..."
}
{
"leadsPopupConfig": "..."
}

---

/api/sites/supername/{supername}/leads-sidebar-config

GET

Response Format:

{
"sidebarLeadsConfig": "...",
"site": "..."
}
{
"sidebarLeadsConfig": "..."
}

---

POST

Response Format:

{
"sidebarLeadsConfig": "...",
"site": "..."
}
{
"sidebarLeadsConfig": "..."
}

---

/api/sites/supername/{supername}/leads/download

GET

---

/api/sites/supername/{supername}/members

GET

Response Format:

{
"members": "...",
"pendingInvitations": "..."
}

---

/api/sites/supername/{supername}/members/invitation

POST

Request Format:

// RequestBody
{email: string,
role: string}

// invitationSchema
{
invitation: yup.object().shape({
email: yup
.string()
.email('Invalid email address')
.required()
.max(100)
.lowercase(),
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']).required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

GET

Request Format:

// invitationSchema
{
invitation: yup.object().shape({
email: yup
.string()
.email('Invalid email address')
.required()
.max(100)
.lowercase(),
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']).required(),
}

// invitationDeleteSchema
{
invitation: yup.object().shape({
id: yup.number().required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

DELETE

Request Format:

// invitationDeleteSchema
{
invitation: yup.object().shape({
id: yup.number().required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

/api/sites/supername/{supername}/members/invitation/{invitationCuid}/accept

PATCH

Request Format:

// invitationPatchSchema
{
invitation: yup.object().shape({
cuid: yup.string().required(),
}

Response Format:

{
"siteMember": "..."
}
{
"error": {
"message": "You don't have access to this invitation."
}
}

---

DELETE

Request Format:

// invitationPatchSchema
{
invitation: yup.object().shape({
cuid: yup.string().required(),
}

Response Format:

{
"siteMember": "..."
}
{
"error": {
"message": "You don't have access to this invitation."
}
}

---

/api/sites/supername/{supername}/members/{userid}

GET

Request Format:

// memberSchema
{
member: yup.object().shape({
role: yup.mixed().oneOf(Object.values(MemberRole)),
}

Response Format:

{
"error": "User ID is required or invalid"
}
{
"error": "Site not found"
}
{
"error": "Member not found in this site"
}
{
"member": "..."
}
{
"siteMember": "..."
}
{
"data": "..."
}

---

PATCH

Request Format:

// memberSchema
{
member: yup.object().shape({
role: yup.mixed().oneOf(Object.values(MemberRole)),
}

Response Format:

{
"error": "User ID is required or invalid"
}
{
"error": "Site not found"
}
{
"error": "Member not found in this site"
}
{
"member": "..."
}
{
"siteMember": "..."
}
{
"data": "..."
}

---

DELETE

Request Format:

// memberSchema
{
member: yup.object().shape({
role: yup.mixed().oneOf(Object.values(MemberRole)),
}

Response Format:

{
"error": "User ID is required or invalid"
}
{
"error": "Site not found"
}
{
"error": "Member not found in this site"
}
{
"member": "..."
}
{
"siteMember": "..."
}
{
"data": "..."
}

---

/api/sites/supername/{supername}/members/{userid}/author-profile

POST

Response Format:

{
"siteMember": "..."
}

---

/api/sites/supername/{supername}/menu

GET

Request Format:

// nestedItemSchema
{
label: z.string().min(1).max(100),
href: z.string().max(MAX_URL_LENGTH),
}

// menuItemSchema
{
id: z.number().optional(),
label: z.string().min(1).max(6000),
href: z.string().max(MAX_URL_LENGTH),
nestedItems: z.array(nestedItemSchema).max(25).nullable(),
}

Response Format:

{
"menuItems": "..."
}
{
"menuItem": "..."
}

---

POST

Request Format:

// nestedItemSchema
{
label: z.string().min(1).max(100),
href: z.string().max(MAX_URL_LENGTH),
}

// menuItemSchema
{
id: z.number().optional(),
label: z.string().min(1).max(6000),
href: z.string().max(MAX_URL_LENGTH),
nestedItems: z.array(nestedItemSchema).max(25).nullable(),
}

Response Format:

{
"menuItems": "..."
}
{
"menuItem": "..."
}

---

PATCH

Request Format:

// nestedItemSchema
{
label: z.string().min(1).max(100),
href: z.string().max(MAX_URL_LENGTH),
}

// menuItemSchema
{
id: z.number().optional(),
label: z.string().min(1).max(6000),
href: z.string().max(MAX_URL_LENGTH),
nestedItems: z.array(nestedItemSchema).max(25).nullable(),
}

Response Format:

{
"menuItems": "..."
}
{
"menuItem": "..."
}

---

DELETE

Request Format:

// nestedItemSchema
{
label: z.string().min(1).max(100),
href: z.string().max(MAX_URL_LENGTH),
}

// menuItemSchema
{
id: z.number().optional(),
label: z.string().min(1).max(6000),
href: z.string().max(MAX_URL_LENGTH),
nestedItems: z.array(nestedItemSchema).max(25).nullable(),
}

Response Format:

{
"menuItems": "..."
}
{
"menuItem": "..."
}

---

/api/sites/supername/{supername}/menu/reorder

PATCH

Response Format:

{
"data": "..."
}

---

/api/sites/supername/{supername}/plan

GET

Response Format:

{
"site": "..."
}

---

/api/sites/supername/{supername}/posts

GET

Request Format:

// postQuerySchema
{
getPostContent: yup.boolean().required(),
page: yup.number().required(),
}

Response Format:

{
"posts": "..."
}
{
"post": "..."
}

---

POST

Request Format:

// RequestBody
{title: string,
content: string,
enableComments: string,
hideSharingIcons: string,
tagIds: string,
status: string,
metaTitle: string,
metaDescription: string,
isPage: string,
slug: string,
categoryId: string,
schema: string,
customJS: string,
customFeaturedImageUrl: string}

// postInputSchema
{
post: yup.object().shape({
title: yup.string().required().min(1).max(POST_TITLE_MAX_LENGTH),
content: yup.string().max(POST_CONTENT_MAX_LENGTH),
tagIds: yup
.array()
.of(yup.number())
.strict(true)
// .required()
.test('field is required', 'tags should not be null' || '', (value) =>
Array.isArray(value)
),
enableComments: yup.boolean().required(),
hideSharingIcons: yup.boolean().required(),
status: yup.string().required().oneOf(['PUBLISHED', 'DRAFT', 'SCHEDULED']),
metaTitle: yup.string().max(POST_TITLE_MAX_LENGTH).nullable(),
metaDescription: yup.string().max(SITE_DESC_MAX_LENGTH).nullable(),
slug: yup
.string()
.max(POST_TITLE_MAX_LENGTH)
.nullable()
.notRequired()
.lowercase(),
isPage: yup.boolean().notRequired().nullable(),
categoryId: yup.string().max(50).nullable(),
schema: yup
.object()
.nullable()
.notRequired()
.test('is-valid-schema', 'Invalid Custom Schema', (value) => {
if (!value) {
return true;
}

Response Format:

{
"posts": "..."
}
{
"post": "..."
}

---

/api/sites/supername/{supername}/posts/bulk

GET

Response Format:

{
"posts": "...",
"totalPages": "...",
"totalPosts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/assign-category

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
categoryId: yup.string().required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/assign-tags

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
tagIds: yup.array().of(yup.number()).required(),
}

Response Format:

{
"posts": "...",
"message": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/change-author

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
authorId: yup.number().required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/delete

DELETE

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/publish

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/redate

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
publishedAt: yup.date().required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/bulk/unpublish

PATCH

Request Format:

// updateSchema
{
postCuids: yup.array().of(yup.string()).required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/posts/reassign

PATCH

Request Format:

// postReassignSchema
{
post: yup.object().shape({
cuid: yup.string().required(),
newUserId: yup.string().required(),
}

Response Format:

{
"post": "..."
}

---

/api/sites/supername/{supername}/posts/tag/{tagId}

GET

Response Format:

{
"posts": "...",
"pagination": {
"total": "...",
"page": "...",
"limit": "...",
"pages": "..."
}
}

---

/api/sites/supername/{supername}/posts/{cuid}

GET

Request Format:

// RequestBody
{submitSitemap: string}

Response Format:

{
"error": "Too many requests"
}
{
"post": "..."
}

---

PATCH

Request Format:

// RequestBody
{submitSitemap: string}

Response Format:

{
"error": "Too many requests"
}
{
"post": "..."
}

---

DELETE

Request Format:

// RequestBody
{submitSitemap: string}

Response Format:

{
"error": "Too many requests"
}
{
"post": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/co-authors

GET

Request Format:

// postCoAuthorsSchema
{
userId: yup.number().required(),
}

Response Format:

{
"coAuthors": "..."
}

---

POST

Request Format:

// postCoAuthorsSchema
{
userId: yup.number().required(),
}

Response Format:

{
"coAuthors": "..."
}

---

DELETE

Request Format:

// postCoAuthorsSchema
{
userId: yup.number().required(),
}

Response Format:

{
"coAuthors": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/comments

GET

Response Format:

{
"comments": "..."
}
{
"comment": "..."
}

---

POST

Response Format:

{
"comments": "..."
}
{
"comment": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/comments/{commentId}

DELETE

Request Format:

// commentUpdateSchema
{
content: z
.string()
.min(1, 'Content length should be greater than 0')
.max(CUSTOM_CSS_MAX_LENGTH * 2)
.optional(),
isEmailApprovedBySite: z.boolean().optional(),
isHidden: z.boolean().optional(),
}

Response Format:

{
"comment": "..."
}

---

PUT

Request Format:

// commentUpdateSchema
{
content: z
.string()
.min(1, 'Content length should be greater than 0')
.max(CUSTOM_CSS_MAX_LENGTH * 2)
.optional(),
isEmailApprovedBySite: z.boolean().optional(),
isHidden: z.boolean().optional(),
}

Response Format:

{
"comment": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/faqs

GET

Request Format:

// faqSchema
{
question: yup.string().required().min(1).max(500),
answer: yup.string().required().min(1).max(2000),
}

---

POST

Request Format:

// faqSchema
{
question: yup.string().required().min(1).max(500),
answer: yup.string().required().min(1).max(2000),
}

---

/api/sites/supername/{supername}/posts/{cuid}/faqs/{faqId}

PUT

Request Format:

// faqSchema
{
question: yup.string().required().min(1).max(500),
answer: yup.string().required().min(1).max(2000),
}

---

DELETE

Request Format:

// faqSchema
{
question: yup.string().required().min(1).max(500),
answer: yup.string().required().min(1).max(2000),
}

---

/api/sites/supername/{supername}/posts/{cuid}/frontend

GET

Response Format:

{
"existsOnFrontend": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/pin

GET

Request Format:

// RequestBody
{isPinned: string}

Response Format:

{
"post": "..."
}

---

PATCH

Request Format:

// RequestBody
{isPinned: string}

Response Format:

{
"post": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/preview

GET

Response Format:

{
"postPreview": "..."
}

---

DELETE

Response Format:

{
"postPreview": "..."
}

---

POST

Response Format:

{
"postPreview": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/review-comments

GET

Request Format:

// postUpdateSchema
{
reviewComment: yup.object().shape({
text: yup.string().max(POST_CONTENT_MAX_LENGTH),
}

Response Format:

{
"reviewComments": "..."
}
{
"reviewComment": "..."
}

---

POST

Request Format:

// postUpdateSchema
{
reviewComment: yup.object().shape({
text: yup.string().max(POST_CONTENT_MAX_LENGTH),
}

Response Format:

{
"reviewComments": "..."
}
{
"reviewComment": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/review-comments/{reviewCommentId}

DELETE

Response Format:

{
"reviewComment": "..."
}

---

/api/sites/supername/{supername}/posts/{cuid}/schedule

GET

Request Format:

// RequestBody
{autoPublishAt: string}

Response Format:

{
"post": "..."
}

---

DELETE

Request Format:

// RequestBody
{autoPublishAt: string}

Response Format:

{
"post": "..."
}

---

POST

Request Format:

// RequestBody
{autoPublishAt: string}

Response Format:

{
"post": "..."
}

---

/api/sites/supername/{supername}/redirects

GET

Request Format:

// createRedirectSchema
{
from: z.string().min(1, 'Source URL is required').max(MAX_URL_LENGTH),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// updateRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
from: z
.string()
.min(1, 'Source URL is required')
.max(MAX_URL_LENGTH)
.regex(slugRegex, 'Source URL must be a valid slug'),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// deleteRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
}

Response Format:

{
"redirects": "..."
}
{
"redirect": "..."
}

---

DELETE

Request Format:

// createRedirectSchema
{
from: z.string().min(1, 'Source URL is required').max(MAX_URL_LENGTH),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// updateRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
from: z
.string()
.min(1, 'Source URL is required')
.max(MAX_URL_LENGTH)
.regex(slugRegex, 'Source URL must be a valid slug'),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// deleteRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
}

Response Format:

{
"redirects": "..."
}
{
"redirect": "..."
}

---

POST

Request Format:

// createRedirectSchema
{
from: z.string().min(1, 'Source URL is required').max(MAX_URL_LENGTH),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// updateRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
from: z
.string()
.min(1, 'Source URL is required')
.max(MAX_URL_LENGTH)
.regex(slugRegex, 'Source URL must be a valid slug'),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// deleteRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
}

Response Format:

{
"redirects": "..."
}
{
"redirect": "..."
}

---

PATCH

Request Format:

// createRedirectSchema
{
from: z.string().min(1, 'Source URL is required').max(MAX_URL_LENGTH),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// updateRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
from: z
.string()
.min(1, 'Source URL is required')
.max(MAX_URL_LENGTH)
.regex(slugRegex, 'Source URL must be a valid slug'),
to: z.string().min(1, 'Target URL is required').max(MAX_URL_LENGTH).url(),
isEnabled: z.boolean(),
}

// deleteRedirectSchema
{
id: z.string().cuid('Invalid redirect ID'),
}

Response Format:

{
"redirects": "..."
}
{
"redirect": "..."
}

---

/api/sites/supername/{supername}/scribble

GET

Response Format:

{
"scribble": "..."
}

---

POST

Response Format:

{
"scribble": "..."
}

---

/api/sites/supername/{supername}/settings

GET

Response Format:

{
"settings": "...",
"subscription": "...",
"pages": "...",
"customDomain": "..."
}

---

PATCH

Response Format:

{
"settings": "...",
"subscription": "...",
"pages": "...",
"customDomain": "..."
}

---

/api/sites/supername/{supername}/site-data/export/download

POST

Response Format:

{
"reOrganisedData": "..."
}
{}

---

/api/sites/supername/{supername}/storage/images/opt

POST

Response Format:

{
"link": "...".newUrl
}
{
"link": "..."
}

---

/api/sites/supername/{supername}/tags

GET

Request Format:

// tagInputSchema
{
tag: z.object({
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

// tagDeleteSchema
{
tag: z.object({
id: z.number(),
}

// tagUpdateSchema
{
tag: z.object({
id: z.number(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

Response Format:

{
"tags": "...",
"totalPages": "...",
"totalTags": "...",
"currentPage": "...",
"pageSize": "..."
}
{
"tag": "..."
}

---

POST

Request Format:

// tagInputSchema
{
tag: z.object({
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

// tagDeleteSchema
{
tag: z.object({
id: z.number(),
}

// tagUpdateSchema
{
tag: z.object({
id: z.number(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

Response Format:

{
"tags": "...",
"totalPages": "...",
"totalTags": "...",
"currentPage": "...",
"pageSize": "..."
}
{
"tag": "..."
}

---

PATCH

Request Format:

// tagInputSchema
{
tag: z.object({
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

// tagDeleteSchema
{
tag: z.object({
id: z.number(),
}

// tagUpdateSchema
{
tag: z.object({
id: z.number(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

Response Format:

{
"tags": "...",
"totalPages": "...",
"totalTags": "...",
"currentPage": "...",
"pageSize": "..."
}
{
"tag": "..."
}

---

DELETE

Request Format:

// tagInputSchema
{
tag: z.object({
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

// tagDeleteSchema
{
tag: z.object({
id: z.number(),
}

// tagUpdateSchema
{
tag: z.object({
id: z.number(),
name: z.string().min(1).max(SITE_NAME_MAX_LENGTH).trim(),
slug: z.string().trim(),
metaTitle: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
metaDescription: z.string().max(SITE_DESC_MAX_LENGTH).trim().nullish(),
}

Response Format:

{
"tags": "...",
"totalPages": "...",
"totalTags": "...",
"currentPage": "...",
"pageSize": "..."
}
{
"tag": "..."
}

---

/api/sites/supername/{supername}/tags/bulk/delete

DELETE

Request Format:

// deleteSchema
{
tagIds: yup.array().of(yup.number()).required(),
}

Response Format:

{
"posts": "..."
}

---

/api/sites/supername/{supername}/tags/{tagname}

GET

Response Format:

{
"tag": "..."
}

---

/api/sites/supername/{supername}/transfer

POST

---

/api/sites/supername/{supername}/transfer/confirm

POST

Response Format:

{
"message": "Transfer complete"
}

---

/api/sites/supername/{supername}/wrapped

GET

Response Format:

{
"wrappedData": "...",
"customDomain": "..."
}
{
"wrappedData": "..."
}

---

PUT

Response Format:

{
"wrappedData": "...",
"customDomain": "..."
}
{
"wrappedData": "..."
}

---

/api/users/agency

GET

Response Format:

{
"subscription": "...",
"sitesCount": "..."
}
{
"deletedSites": "..."
}

---

DELETE

Response Format:

{
"subscription": "...",
"sitesCount": "..."
}
{
"deletedSites": "..."
}

---

/api/users/agency/checkout-session

POST

Request Format:

// RequestBody
{priceId: string}

---

/api/users/agency/members

GET

Response Format:

{
"members": "...",
"pendingInvitations": "..."
}

---

/api/users/agency/members/invitation

POST

Request Format:

// RequestBody
{email: string,
role: string}

// invitationSchema
{
invitation: yup.object().shape({
email: yup
.string()
.email('Invalid email address')
.required()
.max(100)
.lowercase(),
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']).required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

GET

Request Format:

// invitationSchema
{
invitation: yup.object().shape({
email: yup
.string()
.email('Invalid email address')
.required()
.max(100)
.lowercase(),
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']).required(),
}

// invitationDeleteSchema
{
invitation: yup.object().shape({
id: yup.number().required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

DELETE

Request Format:

// invitationDeleteSchema
{
invitation: yup.object().shape({
id: yup.number().required(),
}

Response Format:

{
"invitation": "..."
}
{
"pendingInvitations": "..."
}

---

/api/users/agency/members/invitation/{agencyInvitationCuid}/accept

PATCH

Request Format:

// invitationPatchSchema
{
invitation: yup.object().shape({
cuid: yup.string().required(),
}

Response Format:

{
"agencyMember": "..."
}
{
"error": {
"message": "You don't have access to this invitation."
}
}

---

DELETE

Request Format:

// invitationPatchSchema
{
invitation: yup.object().shape({
cuid: yup.string().required(),
}

Response Format:

{
"agencyMember": "..."
}
{
"error": {
"message": "You don't have access to this invitation."
}
}

---

/api/users/agency/members/{userid}

PATCH

Request Format:

// memberSchema
{
member: yup.object().shape({
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']),
}

Response Format:

{}
{
"data": "..."
}

---

DELETE

Request Format:

// memberSchema
{
member: yup.object().shape({
role: yup.mixed().oneOf(['ADMIN', 'EDITOR', 'WRITER']),
}

Response Format:

{}
{
"data": "..."
}

---

/api/users/customer-portal

GET

Response Format:

{
"customerPortalUrl": "..."
}

---

/api/users/profile

PATCH

Request Format:

// profileSchema
{
name: yup.string().min(3).max(25),
}

Response Format:

{
"user": "..."
}
{
"deletedData": {
data
}
}

---

DELETE

Request Format:

// profileSchema
{
name: yup.string().min(3).max(25),
}

Response Format:

{
"user": "..."
}
{
"deletedData": {
data
}
}

---