POST/v1/blogs/{subdomain}/posts

Create a draft post, or update the post holding the same slug

Creates a new post as a draft. The post is never published by this call; use the publish endpoint to make it visible.

The slug is optional: when omitted it is generated from the title.

onConflict decides what happens when that slug is already taken on the blog:

  • DEDUPLICATE (default): the slug is suffixed (-2, -3…) and a new post is created. Replaying the request creates another post, so keep the returned id as your reference.
  • UPDATE: the slug identifies the post. The existing one is updated in place and 200 is returned instead of 201, which makes this call safe to replay. Fields absent from the payload are left unchanged, as with a partial update. The publication state is never changed here.

The post author is the blog owner.

Parameters

subdomainpathstringrequired
Subdomain of the blog
onConflictquerystringoptional
Behaviour when the slug is already taken: DEDUPLICATE (default) or UPDATE
DefaultDEDUPLICATEOne ofDEDUPLICATEUPDATE

Request body

required

application/json

titlestringrequired
Post title
contentstringrequired
Post body in Markdown
slugstringoptional
URL-safe slug. Optional: generated from the title when omitted. The response always carries the final slug, which may differ if a collision was resolved.
excerptstringoptional
Short excerpt or teaser text
coverImageUrlstringoptional
URL of the post cover image (e.g. an URL returned by the media upload endpoint)
tagsstring[]optional
Tag names. Tags are created on the fly if they do not exist yet.
accessModestringoptional
Content access mode: FREE or PAID. Defaults to FREE.

Responses

200
Existing post updated (onConflict=UPDATE only)
idstringrequired
Unique post identifier
titlestringrequired
Post title
slugstringrequired
URL-safe slug
excerptstringoptional
Short excerpt or teaser text, if provided by the author
contentstringrequired
Full post body in the format described by contentFormat
contentFormatstringrequired
Format of the content field. Currently always markdown.
publishedAtstring (date)optional
Date the post was published (ISO 8601 date). Null if the post is not yet published.
updatedAtstring (date-time)required
Date and time the post was last updated (ISO 8601 datetime)
coverImageUrlstringoptional
URL of the post cover image
urlstringrequired
Canonical public URL of the post
accessModestringrequired
Content access mode: FREE (visible to all readers) or PAID (requires an active paid subscription)
clapsinteger (int64)required
Total number of claps / reactions the post has received
tagsobject[]required
Tags associated with this post
2 properties
namestringrequired
Human-readable tag name
slugstringrequired
URL-safe slug — use as the tag query parameter when filtering posts
authorsobject[]required
Authors credited on this post
3 properties
namestringrequired
Display name of the author
avatarUrlstringoptional
URL of the author's avatar image
shortBiostringoptional
Short one-line biography suitable for bylines

Code example

POST/v1/blogs/{subdomain}/posts
curl -X POST \
  -H "Accept: application/json" \
  "https://api.writizzy.com/v1/blogs/<subdomain>/posts"