This adds www.example.com as a proxied A record, served through the OpenWAF edge, with the full simulate-then-confirm protocol. The token needs the Tech role.
import { OpenWAF, OpenWAFError, type Applied } from "./openwaf.ts";
const owf = new OpenWAF();
// 1. Find the zone's id.
const { items: zones = [] } = await owf.listZones();
const zone = zones.find((z) => z.name === "example.com");
if (!zone?.id) throw new Error("example.com not found");
const record = { type: "A", name: "www", content: "203.0.113.10", proxied: true } as const;
const reason = "Add www behind the WAF";
// 2. Simulate: nothing is applied.
const plan = (await owf.createRecord({ zone: zone.id, body: record }, { reason, dryRun: true })) as Applied;
for (const c of plan.diff?.changes ?? []) console.log(c.op, c.path);
console.log(`version ${plan.from_version} → ${plan.to_version}`, plan.warnings);
// 3. Confirm with the version the plan was made against.
try {
const created = await owf.createRecord({ zone: zone.id, body: record }, { reason, ifMatch: plan.from_version! });
console.log("created", created);
} catch (err) {
if (err instanceof OpenWAFError && err.code === "version_conflict") {
console.error("The zone changed in the meantime: run again and review the new plan.");
} else {
throw err;
}
}from openwaf import OpenWAF, OpenWAFError
owf = OpenWAF()
# 1. Find the zone's id.
zone = next(z for z in owf.list_zones()["items"] if z["name"] == "example.com")
record = {"type": "A", "name": "www", "content": "203.0.113.10", "proxied": True}
reason = "Add www behind the WAF"
# 2. Simulate: nothing is applied.
plan = owf.create_record(zone=zone["id"], body=record, reason=reason, dry_run=True)
for change in plan["diff"]["changes"]:
print(change["op"], change["path"])
print("version %d -> %d" % (plan["from_version"], plan["to_version"]), plan["warnings"])
# 3. Confirm with the version the plan was made against.
try:
created = owf.create_record(zone=zone["id"], body=record, reason=reason, if_match=plan["from_version"])
print("created", created)
except OpenWAFError as e:
if e.code != "version_conflict":
raise
print("The zone changed in the meantime: run again and review the new plan.")The simulation prints one change, add records[id=…], and the version the record would create. The confirmed call answers the new record with its id.
Several records in one change
To create, update and delete several records as one version, use batchRecords / batch_records (up to 500 operations, all or nothing), with a body of create, update and delete lists. It takes the same reason, dryRun and ifMatch options.
Record fields
type and content are required; name, ttl, priority (MX and SRV only), proxied (A, AAAA and CNAME only), comment and tags are optional. The CLI records reference describes each field; the API reference has the full schema.