Adding one row to a repeater the naive way means reading the whole field, appending to the array and writing all of it back: three round trips, and a diff that touches every row even though one changed.
custom-fields/add-acf-repeater-row is one call. Append a row, or insert it at a 1-based position, on a repeater or flexible-content field attached to any target.
At a glance
| Ability | custom-fields/add-acf-repeater-row |
| Toolset | Advanced Custom Fields — toolset/acf |
| Group | Repeater & Flexible Content |
| Requires | Advanced Custom Fields Pro, plus a repeater field registered on the site |
| Capability | manage_options |
| Safety | Writes data |
| Repeatable | Not idempotent — each call changes the row set, so re-running is not a no-op |
| Ships in | AcrossAI Abilities Manager 0.0.34 and later |
How it works
Append is a single targeted write. ACF’s add_row() writes the new row and updates the count, leaving the existing rows alone.
Insert is different. ACF has no positional-insert API, so asking for a position rewrites the array server-side to make room. It is still one call from where you sit, but it touches more rows than an append does — so append unless the order genuinely matters.
The response returns the index the row landed at and the new row count, which is what you need to address it later with custom-fields/update-acf-repeater-row.
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. |
selector | string | Yes | Repeater or flexible-content field name (e.g. cards) or field key. |
row | object | Yes | Sub-field name => value for the new row. |
position | integer | No | 1-based position to insert at. 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 |
|---|---|---|
index | integer | Where the row landed, 1-based. |
row_count | integer | How many rows the field holds now. |
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 fourth card to the features repeater on page 87 — title “Audit trail”, body “Every call is logged.”
It resolves to one call:
{
"ability": "custom-fields/add-acf-repeater-row",
"parameters": {
"target_type": "post",
"target_id": 87,
"selector": "features",
"row": {
"title": "Audit trail",
"body": "Every call is logged."
}
}
}Worth knowing
- Not idempotent. Retry a call you are unsure about and you get two rows — read the field first if a previous attempt may have landed.
- The ACF Pro check is on the repeater field type, not on a function name.
add_row()ships in the free edition too, where no repeater field can exist for it to act on, so a function check would pass and the write would fail later. - Flexible-content fields take layouts, not plain rows. Use
custom-fields/add-acf-flex-layoutwhen the field defines layouts.
Related abilities
- Get ACF Field Value — see the current rows and the row count
- Update Repeater Row — patch the row once it exists
- Add Flexible Content Layout — the flexible-content equivalent
Get the plugins:
AcrossAI Abilities Manager · AcrossAI MCP Manager
Browse the rest: Every ability, by category