ACF block values do not live in post meta. They are serialised into the block’s own comment delimiter inside the post content, which is why custom-fields/update-acf-field cannot touch them — and why writing them by hand means editing block markup.
blocks/insert-acf-block puts a block instance into a post with its field values in the data payload, serialised the way the editor expects.
At a glance
| Ability | blocks/insert-acf-block |
| Toolset | Advanced Custom Fields — toolset/acf |
| Group | ACF Blocks |
| Requires | Advanced Custom Fields Pro |
| Capability | manage_options |
| Safety | Writes data |
| Repeatable | Not idempotent — each call inserts another instance |
| Ships in | AcrossAI Abilities Manager 0.0.34 and later |
How it works
Give it a post ID, the block name and a data object keyed by field name. Omit index and the block is appended; pass one and it lands at that 0-based position among the post’s top-level blocks.
Note the indexing difference: block positions are 0-based here, while repeater and flexible-content rows are 1-based. That split is ACF’s own, and this suite follows each API rather than papering over it.
Call blocks/get-acf-block-fields first. A key that matches no field is written into the payload and then ignored by the block — a silent no-op rather than an error.
Input
| Name | Type | Required | What it is |
|---|---|---|---|
post_id | integer | Yes | The post to insert the block into. |
name | string | Yes | Block name, with or without the acf/ prefix. |
data | object | No | Field name => value for the block, matching blocks/get-acf-block-fields. |
index | integer | No | 0-based position among the post’s top-level blocks. Omit to append. |
apply_wp_slash | boolean | No — defaults to true | Runs wp_slash() over your strings before writing, so literal backslashes survive. Set it false only when you have already slashed the payload yourself. |
What comes back
| Name | Type | What it is |
|---|---|---|
post_id | integer | The post that was written. |
name | string | The block that was inserted. |
index | integer | Where it landed, 0-based. |
success | boolean | Whether the call completed. |
message | string | A one-line summary of what happened, suitable for showing a human. |
error_code | string | Present only on failure — a stable machine-readable reason, such as a missing field, a wrong field type or an unmet confirmation. |
Example
Ask your assistant:
Add a testimonial block to post 412, quoting Maya at Northwind, just after the intro paragraph.
It resolves to one call:
{
"ability": "blocks/insert-acf-block",
"parameters": {
"post_id": 412,
"name": "testimonial",
"data": {
"quote": "We shipped in a week instead of a quarter.",
"attribution": "Maya, Northwind"
},
"index": 1
}
}Worth knowing
- Not idempotent — each call inserts another instance.
- Page builders are the exception to all of this. If a post is built with Elementor or similar, its layout is not in the post content, and inserting a block there changes nothing a visitor sees.
- To change a block already in a post, use
blocks/update-acf-block-datarather than inserting a second one. - Requires ACF Pro.
Related abilities
- Get ACF Block Fields — learn the payload shape first
- Update ACF Block Data — edit one that is already there
- List ACF Blocks — find the block name
Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager
Browse the rest: Every ability, by category