What's the right syntax for the API3 "replace" action for the "WordReplacement" entity?
Updated! based on Coleman's answer, and additional testing.
First of all, for WordReplacement, if you want to update a single record it's best and most appropriate to use the get action to get the record ID (civicrm_word_replacement.id). Then (as Coleman noted) use the create action and include the id parameter to update just that record. (Without the id parameter, create throws an error complaining the record already exists. With it, create performs an update.)
For the replace action, the values parameter must be an array of arrays. But, crucially, in addition to the values array, you must provide &quot;scope&quot; parameters outside of the values array.
So for example, with id as the &quot;scope&quot; parameter, the following will update only the record matching the id (equivalently—but more awkwardly—than create):
$result = civicrm_api3('WordReplacement', 'replace', [
  'values' =&gt; [
    'id' =&gt; 2, // &quot;scope&quot; parameter
    [
      'find_word' =&gt; &quot;Contribute&quot;,
      'replace_word' =&gt; &quot;Give Now&quot;,
      'domain_id' =&gt; &quot;my-domain-name-here&quot;,
      'match_type' =&gt; &quot;exactMatch&quot;,
      'is_active' =&gt; 1
    ]
  ]
]);

The API also supports, and is in fact intended for, multiple replacements. But in this case the values array must contain all of the records that match the &quot;scope&quot; parameter(s). In other words, it replaces the complete set of records that match the &quot;scope&quot; parameter(s). For WordReplacement, if you provide only the domain_id as the &quot;scope&quot; parameter, the replace action will match all of the records for that domain, so your values array must contain the complete set of WordReplacement records for that domain. If you have 3 replacement words, this might look like the following:
$result = civicrm_api3('WordReplacement', 'replace', [
  'values' =&gt; [
    'domain_id' =&gt; &quot;my-domain-name-here&quot;, // &quot;scope&quot; parameter
    [
      'id' =&gt; 2,
      'find_word' =&gt; &quot;Contribute&quot;,
      'replace_word' =&gt; &quot;Give Soon&quot;,
      'match_type' =&gt; &quot;exactMatch&quot;,
      'is_active' =&gt; 1
    ],
    [
      'id' =&gt; 3,
      'find_word' =&gt; &quot;Find this&quot;,
      'replace_word' =&gt; &quot;Replace with that&quot;,
      'match_type' =&gt; &quot;exactMatch&quot;,
      'is_active' =&gt; 1
    ],
    [
      'id' =&gt; 7,
      'find_word' =&gt; &quot;Find this too&quot;,
      'replace_word' =&gt; &quot;And replace it with this&quot;,
      'match_type' =&gt; &quot;wildcardMatch&quot;,
      'is_active' =&gt; 1
    ],
  ]
]);

If you had four WordReplacement records for &quot;my-domain-name-here&quot;, you'll end up with only the three above after calling replace. The fourth record will be deleted. Conversely you can add new records by omitting the id parameter (provided the new records have no &quot;already exists&quot; conflicts).
So the replace API action is powerful but potentially dangerous. Test carefully in a development environment before using.