Ir al contenido

Idempotencia

Lo que creas por la API viaja a las cajas del negocio. Si un POST se corta por la red y lo reintentas, podrías crear dos veces el mismo cliente o sumar dos veces el mismo stock. El header Idempotency-Key evita eso.

  • Es obligatorio en todo POST. Sin él, la respuesta es 400 IDEMPOTENCY_KEY_REQUIRED.
  • Usa un valor único por operación: un UUID nuevo es lo más simple. Admite hasta 255 caracteres entre letras, números y - _ : ..
  • Si reintentas la misma operación, reutiliza el mismo valor.
  • El valor vale 24 horas y es por API key: dos keys distintas no comparten valores.
Ventana de terminal
curl https://api.posdata.so/public/v1/inventory/movements \
-H "Authorization: Bearer $POSDATA_API_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: compra-OC-2026-0915" \
-d '{ "product_id": "8d2c1f0a-3b4e-4c5d-9e6f-7a8b9c0d1e2f", "type": "in", "quantity": 24, "reference": "OC-2026-0915" }'
Situación Respuesta
Primera vez con ese valor Se procesa normalmente.
Mismo valor y misma petición, ya terminada con éxito La respuesta original, con el mismo código y cuerpo, y el header Idempotent-Replayed: true. No se crea nada nuevo.
Mismo valor y otra petición (otra ruta u otro cuerpo) 422 IDEMPOTENCY_KEY_REUSED. Nunca te devolvemos en silencio el resultado de otra operación.
Mismo valor mientras la primera petición sigue en curso, o si se interrumpió antes de terminar 409 IDEMPOTENCY_IN_PROGRESS. Nunca se vuelve a ejecutar.

“Misma petición” significa mismo método, misma ruta y mismo cuerpo JSON. El orden de las claves del JSON no importa.

Solo se guarda la respuesta de una petición que terminó en 2xx, y se guarda antes de enviártela. Si la respuesta fue un error (un 400 que vas a corregir, un 409, un 500), el valor queda libre: puedes corregir la petición y reenviarla con el mismo Idempotency-Key sin recibir IDEMPOTENCY_KEY_REUSED. Un error nunca oculta una escritura que sí se hizo: si el cambio quedó guardado, la respuesta es 2xx.

En casos excepcionales, la respuesta 2xx de una escritura trae solo object e id (el cambio sí quedó guardado, pero no pudimos volver a leerlo en ese instante). Consulta el recurso con un GET por su id.

La primera petición con ese valor está en curso o se interrumpió (por ejemplo, durante un despliegue nuestro). Posdata no la vuelve a ejecutar, porque no puede saber si alcanzó a guardar el cambio: repetirla podría, por ejemplo, sumar dos veces el mismo stock.

  1. Espera unos segundos y reintenta con el mismo valor. Si la primera terminó bien, recibes su respuesta.
  2. Si sigue respondiendo 409, verifica con un GET si el recurso se creó (por ejemplo, GET /inventory/movements?product_id=…&created_since=… y busca tu reference entre los resultados, o GET /customers?email=…).
  3. Solo si no se creó, reintenta con un Idempotency-Key nuevo.

Los PATCH (editar un producto, una variante, una categoría o un cliente) no llevan Idempotency-Key: enviar dos veces el mismo cambio deja el registro igual. Ten en cuenta que en una edición gana el cambio más reciente: si alguien edita el mismo cliente desde una caja entre tus dos intentos, tu reintento lo sobrescribe.

  • Deriva el valor de algo que identifique la operación en tu sistema (pedido-1234-cliente, OC-2026-0915): así, aunque tu proceso se reinicie, el reintento usa el mismo valor.
  • Envía también tu propia referencia en el cuerpo cuando el recurso la admita (reference en los movimientos): te facilita verificar con un GET.
  • No reutilices un valor para una operación distinta, aunque hayan pasado más de 24 horas.