Skip to main content

Reintentar sin duplicar facturas: Idempotency-Key

Cuando mandás una factura y la conexión se corta, el servidor tarda demasiado o recibís un 5xx, no sabés si la factura quedó encolada o no. Si la reenviás “por las dudas” podés terminar con dos comprobantes reales ante ARCA por la misma venta. El header Idempotency-Key resuelve eso: le ponés una clave a cada factura y, si reenviás el mismo pedido con la misma clave, Facturear te devuelve la respuesta original (mismo batchId) en vez de encolar otra factura.

Dónde se usa

El header es opcional: sin él, la API funciona igual que siempre.

Cómo funciona

  1. Generá una clave única por factura (te recomendamos un UUID v4) y mandala en el header Idempotency-Key. Tiene que tener entre 1 y 255 caracteres ASCII imprimibles.
  2. La primera vez, Facturear procesa el pedido normalmente y guarda la respuesta asociada a esa clave durante 7 días.
  3. Si llega otra vez la misma clave con el mismo cuerpo, la API devuelve la respuesta guardada, con el mismo status y el header Idempotent-Replayed: true. No se encola nada nuevo ni se descuenta otra factura de tu plan.
Qué respuestas se guardan:
  • Las 2xx (la factura quedó encolada) y los errores de validación (400, 404, 422): el mismo pedido daría siempre lo mismo.
  • Los 5xx, el 403 por límite del plan, los 409 y los 429 no se guardan: la clave queda libre y podés reintentar con la misma.
Las claves son por cuenta y por entorno: la misma clave en homologación y en producción son pedidos distintos. Pasados los 7 días, la clave se considera nueva.

¿Misma clave o clave nueva?

La regla: la clave identifica la factura, no el intento.
Una clave nueva siempre es una factura nueva. Si no sabés si la factura anterior se emitió (timeout, 5xx, ARCA_OUTCOME_UNKNOWN), no cambies la clave.
Con la misma clave, Facturear además protege la emisión en sí: si por cualquier motivo se encola un segundo intento de la misma factura, antes de pedir un número a ARCA busca la que ya emitió con esa clave y la devuelve.

Ejemplo con curl

Si el pedido se corta, repetí exactamente el mismo comando con el mismo $KEY. Si la primera vez había llegado, la respuesta es la misma (mismo batchId) y trae el header:
Con ese batchId seguís como siempre: consultás GET /api/invoices/batches/{batchId} o esperás el webhook invoice.completed / invoice.failed.

Ejemplo en JavaScript con reintentos

Guardá la clave junto con la venta en tu sistema (por ejemplo, en la fila del pedido) para que un reintento —aunque sea de otro proceso o después de reiniciar— use la misma.

Lotes

En un lote (POST /api/invoices con un array, o PATCH /api/invoices/batches/{batchId}) mandás una sola clave para todo el pedido. Si lo reenviás con la misma clave, recibís el mismo batchId y no se duplica ningún ítem. Internamente, cada factura del lote queda identificada como <clave>:<posición> (empezando en 0), así que la protección también vale para cada ítem por separado. Por eso, si reenviás un lote corregido, mandalo con una clave nueva.
La clave puede ser cualquier texto que identifique la operación en tu sistema (pedido-1234, cierre-2026-09-lote-1), siempre que nunca la uses para otra factura. Un UUID es lo más seguro.

Anular una factura

POST /api/invoices/{invoiceId}/credit-note emite la nota de crédito que anula una factura por el total (ver Notas de Crédito y Débito). También acepta Idempotency-Key: mandá una clave por anulación y, si el pedido se corta, reenvialo con la misma.
El status es 202. Un reenvío con la misma clave devuelve esa misma respuesta (mismo batchId) con Idempotent-Replayed: true. La clave queda atada a esa factura: usarla para anular otra responde 422. Aunque no mandes clave, una factura nunca se anula dos veces: si su nota de crédito ya está en la cola o en ARCA, el pedido responde 409 con el batchId para seguirla; si ya está autorizada, 409 con el creditNoteId. Si ARCA rechazó la nota de crédito, podés volver a pedirla con una clave nueva.

Lo que ya lo usa

  • El dashboard: la factura rápida, la detallada y los lotes mandan una clave por envío, así que un doble clic o un reintento por la red no duplica la factura. Anular manda una clave por anulación.
  • Zapier: cada paso de “Crear factura” o de borrador manda una clave derivada del Zap y de los datos del paso; si Zapier repite el paso, no se factura dos veces. Ver Zapier y Google Drive.
  • Agentes de IA (MCP): create_invoice acepta idempotency_key, y las instrucciones del servidor le piden al agente mandar una y reusarla al reintentar. Ver Agentes de IA.

Recursos relacionados