# Idempotencia

`GET`, `PUT` y `DELETE` ya son idempotentes por diseño HTTP. Para `POST` y
`PATCH` en recursos sensibles (tareas, OS, tickets), sigue estas prácticas.

## Correlación por `externalId`

- Envía un identificador generado por tu sistema en `externalId` (p. ej. ID del
ERP). Antes de crear, consulta el `GET` correspondiente filtrando por `externalId`.
- Si existe, actualiza con `PATCH`; si no, crea con `POST`.


## Clave de idempotencia por entrega (Webhooks)

- Usa `deliveryId` del payload para deduplicar del lado cliente (write-once en
una tabla `webhook_deliveries`).


## Política de retry segura


```ts
async function postWithSafety(body) {
  const existing = await findByExternalId(body.externalId);
  if (existing) return existing;
  try {
    return await api.post('/tasks', body);
  } catch (err) {
    if (err.status === 409) {
      return findByExternalId(body.externalId);
    }
    throw err;
  }
}
```

## En roadmap

- Soporte nativo a `Idempotency-Key` (estilo Stripe) — consulta el
[changelog](/changelog).