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

Name In Type Description
subdomain*
pathstringSubdomain of the blog
onConflict
querystring
default: DEDUPLICATE
Behaviour when the slug is already taken: `DEDUPLICATE` (default) or `UPDATE`

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.

string[]

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

200Existing 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

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

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