30 days free. No credit card. Full access from the moment you connect your site.

Start free trial

Update ACF Field Value

ACF never stores a field as a single row. Alongside the value it writes a reference row holding the field key, and for a repeater it writes one row per index per sub-field. Those reference rows are how ACF knows which field definition a value belongs to.

Write the value row directly with post meta and the reference rows stay behind, pointing at the old state. ACF can no longer read its own data — and nothing reports a problem, because the write did succeed. custom-fields/update-acf-field goes through update_field(), which keeps every row in step.

At a glance

Abilitycustom-fields/update-acf-field
ToolsetAdvanced Custom Fields — toolset/acf
GroupField Values
RequiresAdvanced Custom Fields (free edition is enough)
Capabilitymanage_options
SafetyWrites data
RepeatableIdempotent — running it twice leaves the same result
Ships inAcrossAI Abilities Manager 0.0.34 and later

Why this and not post meta

The target pair and the selector work exactly as they do on the read: a field name or field key, against a post, user, term, comment or the options store.

The shape of value follows the field type. Text and number fields take a scalar. A repeater takes an array of row objects keyed by sub-field name. A relationship takes a post ID or an array of them. An image takes an attachment ID. Read the field first if you are not certain which.

After the write the ability re-reads the field and returns it, so the response shows what ACF actually stored rather than what was sent. For most types those match; for dates, or a relationship given slugs instead of IDs, the stored form is the one that matters.

Input

NameTypeRequiredWhat it is
target_typestringNo — defaults to postWhat the value is attached to: post, user, term, comment or option. post covers pages and any custom post type.
target_idinteger | stringYes, for post, user, term and commentThe ID of the target. Optional for option, where it names a specific options page; omit it for the default options store.
selectorstringYesField name or field key.
valuestring | number | boolean | array | object | nullYesThe new value. Its shape follows the field type.
apply_wp_slashbooleanNo — defaults to trueRuns 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

NameTypeWhat it is
fieldobjectThe field as ACF stored it, re-read after the write.
updatedbooleanTrue when the write went through.
successbooleanWhether the call completed.
messagestringA one-line summary of what happened, suitable for showing a human.
error_codestringPresent 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:

Set the subtitle field on post 412 to “Built for teams that ship weekly”.

It resolves to one call:

{
  "ability": "custom-fields/update-acf-field",
  "parameters": {
    "target_type": "post",
    "target_id": 412,
    "selector": "subtitle",
    "value": "Built for teams that ship weekly"
  }
}

Worth knowing

  • Idempotent by design — writing the same value twice leaves the same state, so a retry after a dropped connection is safe.
  • Read with custom-fields/get-acf-field first when the value is complex. A repeater written from a guess replaces every row, including the ones you meant to keep.
  • ACF block values are not field values. They live in the post content as part of the block markup — use blocks/update-acf-block-data for those.
  • Changing several fields on the same target? custom-fields/update-acf-fields does it in one call and reports per-field success.

Related abilities


Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager

Browse the rest: Every ability, by category


Keep reading