Editing six fields on a landing page should not be six round trips. custom-fields/update-acf-fields takes a map of field name to new value and writes the lot against one target.
What makes it more than a convenience is the reporting. A batch write that collapses to a single true or false hides the one field that failed. This one returns updated and failed separately, with a reason attached to each failure.
At a glance
| Ability | custom-fields/update-acf-fields |
| Toolset | Advanced Custom Fields — toolset/acf |
| Group | Field Values |
| Requires | Advanced Custom Fields (free edition is enough) |
| Capability | manage_options |
| Safety | Writes data |
| Repeatable | Idempotent — running it twice leaves the same result |
| Ships in | AcrossAI Abilities Manager 0.0.34 and later |
How it works
Every entry in fields is written through ACF’s own update_field(), exactly as the single-field ability does. Batching changes the number of calls, never the correctness of the write.
Keys may be field names or field keys, and the two can be mixed in one payload. Values follow the same shape rules as a single write: a scalar for text, an array of row objects for a repeater, an ID for a relationship.
Writes are attempted in order, and a failure does not stop the rest. That makes a partial result possible, which is exactly why the response separates what landed from what did not rather than throwing the whole batch away.
Input
| Name | Type | Required | What it is |
|---|---|---|---|
target_type | string | No — defaults to post | What the value is attached to: post, user, term, comment or option. post covers pages and any custom post type. |
target_id | integer | string | Yes, for post, user, term and comment | The ID of the target. Optional for option, where it names a specific options page; omit it for the default options store. |
fields | object | Yes | Field name or key => new value. At least one entry. |
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 |
|---|---|---|
updated | array | The selectors that were written. |
failed | array | One entry per failure, each with the selector and the reason. |
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:
On post 412, set the subtitle, the CTA label and the CTA URL in one go.
It resolves to one call:
{
"ability": "custom-fields/update-acf-fields",
"parameters": {
"target_type": "post",
"target_id": 412,
"fields": {
"subtitle": "Built for teams that ship weekly",
"cta_label": "Start free",
"cta_url": "https://example.com/signup"
}
}
}Worth knowing
- Check
failedon every response. A call can report success with three fields written and one rejected. - Pair it with
custom-fields/get-acf-fields: discover what exists, then write only what actually differs. - An empty
fieldsobject is refused rather than treated as a successful no-op.
Related abilities
- Get All ACF Field Values — discover the field names first
- Update ACF Field Value — when only one field changes
Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager
Browse the rest: Every ability, by category