# Escrituras: motivo, simulación y versión

> Cómo los métodos de escritura del SDK reciben el motivo del cambio, simulan con dryRun y confirman contra la versión de la zona con ifMatch.

Los métodos de escritura reciben tres opciones de cambio junto a sus parámetros, el mismo protocolo que describe [Simular y después confirmar](https://developers.openwaf.dev/es/change-control/simulate-and-confirm/):

| Opción | TypeScript | Python | Se envía como |
|---|---|---|---|
| Motivo | `reason` | `reason=` | `X-Change-Reason`. Obligatorio en las escrituras de configuración (el tipo lo exige), de 1 a 500 caracteres. |
| Simulación | `dryRun: true` | `dry_run=True` | `?dry_run=1`: la respuesta es el plan y no cambia nada. |
| Versión esperada | `ifMatch` | `if_match=` | `If-Match: "<versión>"`. Una versión antigua falla con `412 version_conflict`. Obligatoria en `revertZone` / `revert_zone`. |

Un método solo acepta las opciones que admite su operación: por ejemplo, `purgeCache` recibe motivo y `dryRun`, pero no `ifMatch`, porque las purgas no se versionan.

## El patrón

1. Llama al método con `dryRun`. La respuesta es un plan `Applied`: `from_version`, `to_version`, `diff.changes` y `warnings`.
2. Enseña o comprueba las diferencias.
3. Llama al mismo método con los mismos argumentos, sin `dryRun` y con `ifMatch` igual al `from_version` del plan.


**TypeScript**

```ts
import { OpenWAF, type Applied } from "./openwaf.ts";

const owf = new OpenWAF();
const params = { zone: zoneId, body: { hsts: { max_age: 300 } } };
const reason = "Activar 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! });
```
Un método que puede responder un plan o un resultado está tipado como su unión, por ejemplo `Promise<ZoneEdgeSettings | Applied>`; convierte la respuesta de la simulación a `Applied`.
**Python**

```py
from openwaf import OpenWAF

owf = OpenWAF()
patch = {"hsts": {"max_age": 300}}
reason = "Activar 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"])
```


Si la zona cambia entre las dos llamadas, la segunda lanza `version_conflict` y no aplica nada: ver [Gestión de errores](https://developers.openwaf.dev/es/sdk/error-handling/#version-conflict).

## La versión nueva

El SDK devuelve el cuerpo de la respuesta, no sus cabeceras, así que el número de la versión nueva (`X-Config-Version`) no forma parte del resultado en la mayoría de las escrituras. Léelo cuando lo necesites: `getZone` / `get_zone` devuelve la zona con su `config_version`, y el historial de la zona enumera todas las versiones. La respuesta de una vuelta atrás sí lleva `version` en el cuerpo.
