Write methods take three change options next to their parameters, the same protocol described in Simulate, then confirm:
| Option | TypeScript | Python | Sent as |
|---|---|---|---|
| Reason | reason | reason= | X-Change-Reason. Required on configuration writes (the type makes it mandatory), 1–500 characters. |
| Simulation | dryRun: true | dry_run=True | ?dry_run=1: the answer is the plan, nothing changes. |
| Expected version | ifMatch | if_match= | If-Match: "<version>". A stale version fails with 412 version_conflict. Required on revertZone / revert_zone. |
A method only accepts the options its operation supports: for example purgeCache takes a reason and dryRun but no ifMatch, because purges are not versioned.
The pattern
- Call the method with
dryRun. The answer is anAppliedplan:from_version,to_version,diff.changesandwarnings. - Show or check the diff.
- Call the same method with the same arguments, without
dryRun, and withifMatchset to the plan'sfrom_version.
import { OpenWAF, type Applied } from "./openwaf.ts";
const owf = new OpenWAF();
const params = { zone: zoneId, body: { hsts: { max_age: 300 } } };
const reason = "Enable HSTS";
const plan = (await owf.updateZoneEdge(params, { reason, dryRun: true })) as Applied;
console.log(plan.diff?.changes);
await owf.updateZoneEdge(params, { reason, ifMatch: plan.from_version! });A method that can answer either a plan or a result is typed as a union, such as Promise<ZoneEdgeSettings | Applied>; cast the simulation's answer to Applied.
from openwaf import OpenWAF
owf = OpenWAF()
patch = {"hsts": {"max_age": 300}}
reason = "Enable HSTS"
plan = owf.update_zone_edge(zone=zone_id, body=patch, reason=reason, dry_run=True)
print(plan["diff"]["changes"])
owf.update_zone_edge(zone=zone_id, body=patch, reason=reason, if_match=plan["from_version"])If the zone changed between the two calls, the second one raises version_conflict and applies nothing: see Error handling.
The new version
The SDK returns the answer's body, not its headers, so the new version number (X-Config-Version) is not part of the result for most writes. Read it when you need it: getZone / get_zone answers the zone with its config_version, and the zone history lists every version. A revert's answer does carry version in its body.