Reintentar sin duplicar facturas: Idempotency-Key
Cuando mandás una factura y la conexión se corta, el servidor tarda demasiado o recibís un5xx, 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
- 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. - La primera vez, Facturear procesa el pedido normalmente y guarda la respuesta asociada a esa clave durante 7 días.
- 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, el403por límite del plan, los409y los429no se guardan: la clave queda libre y podés reintentar con la misma.
¿Misma clave o clave nueva?
La regla: la clave identifica la factura, no el intento.
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
$KEY. Si la primera vez había llegado, la respuesta es la misma (mismo batchId) y trae el header:
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.
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.
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_invoiceaceptaidempotency_key, y las instrucciones del servidor le piden al agente mandar una y reusarla al reintentar. Ver Agentes de IA.