Publishing
Markdown to Gutenberg: blocks, ::: directives, captions, media, taxonomy and idempotency.
Agents send markdown. Pressbotics converts it into real Gutenberg blocks — not a single HTML lump — so the post is editable in WordPress afterwards.
Supported blocks
- Paragraphs
- Headings H1–H6
- Bold, italic and links
- Bulleted lists
- Numbered lists
- Blockquotes
- Pullquotes (:::pullquote)
- Fenced code blocks
- Tables
- Horizontal rules / separators
- Images, with an optional caption
- Galleries (:::gallery)
- Cover blocks (:::cover)
- Columns (:::columns)
- Groups (:::group)
- Embeds from supported providers
- Self-hosted video files
- Self-hosted audio files
Composite blocks with ::: directives
Some Gutenberg blocks have no markdown equivalent. Write them as fence directives inside the markdown parameter. Each opens with :::name on its own line and closes with ::: on its own line.
| Directive | Block | What it does |
|---|---|---|
| :::cover <image-url> | wp:cover | Full-bleed hero with the enclosed content overlaid. The hero image is uploaded to the media library like any other image. |
| :::pullquote | wp:pullquote | A large decorative quote, distinct from a normal > blockquote. A second paragraph inside becomes the citation. |
| :::gallery | wp:gallery | One image per line — markdown image syntax or a bare URL. Produces a gallery with nested images, all uploaded. |
| :::columns | wp:columns | Columns separated by a line containing only ---. Markdown inside each column is compiled normally. |
| :::group | wp:group | A grouped section. |
A worked example
Cover, pullquote, captioned image, gallery, columns, an embed and a self-hosted video in one article body:
:::cover https://cdn.example.com/hero.jpg
# Inside the launch of Orbit 2.0
A year of work, in one release.
:::
Orbit 2.0 is the biggest release we have shipped.
:::pullquote
We stopped optimising the old thing and rebuilt the loop.
Ana Reyes, Head of Product
:::

:::gallery

https://cdn.example.com/g2.jpg

:::
:::columns
### Faster
Builds are 3x quicker.
---
### Simpler
One screen instead of four.
:::
https://www.youtube.com/watch?v=dQw4w9WgXcQ
https://cdn.example.com/walkthrough.mp4Image captions
Markdown's title argument becomes a real WordPress figcaption. Without a title argument no caption is rendered. This is the only way to caption an image.
Video and audio
A bare link on its own line to a media file becomes a real player, not a link or an embed card.
| Kind | Extensions | Block |
|---|---|---|
| Video | .mp4 .webm .ogv .mov .m4v | wp:video |
| Audio | .mp3 .wav .m4a .ogg .oga .flac | wp:audio |
Embeds
A bare link on its own line to a supported provider becomes a wp:embed block. Supported providers:
- YouTube
- Vimeo
- TikTok
- Spotify
- SoundCloud
- Wistia
Pressbotics creates the embed block; WordPress resolves it with the provider. If the provider has retired its oEmbed endpoint (Twitter/X, Instagram) or your site cannot reach it, the post still publishes and embed_status comes back "partial" with the provider's error. Any other URL stays an ordinary paragraph or link — embedding is not universal.
Images
A featured image can come from exactly one of three inputs: featured_image_url (a public URL, downloaded and sideloaded), featured_image_id (an attachment already in the library, found with list_media) or featured_media_ref (a file the person uploaded through the media handoff). Supplying more than one is rejected. Inline images in the markdown — including cover and gallery images — are downloaded and re-hosted in the site's media library, so nothing hotlinks to an external host. The response reports inline_images with total, failed and errors. See the Images article.
Categories and tags
Pass names, not ids. Pressbotics matches an existing term by name or creates it. Call get_site_context first to see the site's existing terms and reuse them rather than creating near-duplicates.
Partial success
A post can publish while one component fails — a bad image URL, for example. Pressbotics reports that rather than hiding it:
| Field | Values | Meaning |
|---|---|---|
| state | queued | published | scheduled | failed | rejected | reverted | What happened to the post itself. Everything below describes its components. |
| partial | boolean | True when the post landed but at least one component did not. |
| image_status | none | ok | failed | Featured image outcome. |
| image_error | string | Why the featured image failed, when it did. |
| taxonomy_status | none | ok | partial | failed | Categories and tags outcome. |
| taxonomy_error | string | Which terms could not be applied. |
| seo_status | none | ok | unsupported | Whether SEO meta was actually written. |
| seo_error | string | Which piece is missing when seo_status is "unsupported". |
| embed_status | none | ok | partial | failed | Whether provider embeds resolved. A provider that will not embed stays a plain link and the post still publishes. |
| embeds | array | The embed URLs found and what each became. |
| inline_images | { total, failed, errors } | Inline image re-hosting. An image that cannot be fetched is REMOVED from the post body and listed in errors; the post still publishes. |
| post_url | string (URL) | The live post URL, once it exists. |
| render_check | pass | fail | not_yet | pass: the live post was fetched and rendered correctly. fail: it did not, and the post was reverted to draft. not_yet: a scheduled post that is not public yet — the scheduler verifies it when it goes live and writes pass or fail then. |
Read image_status, taxonomy_status, inline_images and seo_status before you tell your user the post succeeded. A post can go live without its featured image, and the response will say so.
In the Activity feed those actions show as "Published (partial)" with the component that failed. A post that never made it to WordPress shows as Failed; one you declined shows as Rejected.
Scheduling and updating
schedule_post takes everything publish_post takes plus publish_at, an ISO 8601 timestamp. update_post targets an existing post id and applies whatever fields you pass.
Idempotency
Pass idempotency_key on any publish call. If the agent retries with the same key, Pressbotics returns the original action instead of creating a second post. Use a stable key derived from the content, not a random one per attempt.

