Webhooks
En vez de consultar, tu app puede recibir un POST cuando un comprobante queda aprobado o rechazado, y con los avisos del monotributo de tus CUIT. Se configuran en el portal (Webhooks, en el menú de usuario): una URL https y los eventos. Al crearlo se muestra una vez el secreto de firma.
| Evento | Cuándo |
|---|---|
comprobante.aprobado | ARCA aprobó un comprobante (también notas de crédito y débito, y los que se reconcilian). |
comprobante.rechazado | ARCA rechazó un comprobante (con sus observaciones). |
monotributo.tope | Un CUIT facturó el 80 % o el 100 % del tope de su categoría en los últimos 12 meses (una vez por umbral; se repite solo si cambian los montos: otra categoría, una tabla de topes nueva o el tope cargado a mano). |
monotributo.recategorizacion | Recategorización sugerida por facturación: momento proyeccion (desde el 1/6 y el 1/12), apertura (al abrir la ventana con la tabla nueva) o recordatorio (2 días antes del cierre). Una vez por momento y semestre. |
monotributo.vencimiento | Vence la cuota del monotributo del mes (el 20), desde 5 días antes. Una vez por mes. |
ping | Prueba desde el portal (Probar). |
{
"id": "6b0f…",
"tipo": "comprobante.aprobado",
"creado": "2026-10-14T12:00:00.000Z",
"datos": { "cuit": 20111111112, "entorno": "produccion", "idempotencyKey": "cobro-8812", "numero": 154, "ptoVta": 2,
"tipoComprobante": 11, "descripcion": "Factura C", "cae": "86410992198264", "caeVencimiento": "2026-10-24",
"resultado": "A", "total": 15000, "moneda": "PES" }
}
Los del monotributo traen en datos el CUIT, el tipo (tope, recategorizacion o cuota), el nivel (alerta o urgente), la ref del aviso y sus números y fechas (no texto armado). Son solo por facturación hecha con arcafactura (la recategorización también mira la superficie, la energía y los alquileres). Por ejemplo, la apertura de la recategorización:
{
"tipo": "monotributo.recategorizacion",
"datos": { "cuit": 20111111112, "tipo": "recategorizacion", "nivel": "alerta", "ref": "recat:20111111112:2026-2:apertura",
"semestre": "2026-2", "momento": "apertura", "categoria": "D", "sugerida": "E", "cambio": "sube", "excede": false,
"facturado": 49000000, "desde": "2025-07-01", "hasta": "2026-06-30", "tope": 60000000,
"vigenciaTabla": "2026-08-01", "vigencia": "2026-08-01", "cierre": "2026-08-05" }
}
En monotributo.tope: categoria (o null si el tope lo cargaste a mano), facturado, tope, porcentaje y vigenciaTabla. En monotributo.vencimiento: categoria, actividad, vencimiento (YYYY-MM-DD), monto (según la actividad; null si no se sabe), cuotaServicios, cuotaBienes y vigenciaTabla. sugerida es null cuando el facturado supera el máximo (excede: true).
Headers: X-Arcafactura-Evento (el tipo), X-Arcafactura-Entrega (id único de la entrega: usalo para no procesar dos veces la misma) y X-Arcafactura-Signature: t=<unix>,v1=<firma>, donde la firma es HMAC-SHA256 con tu secreto de "<t>.<cuerpo crudo>". Verificala antes de confiar en el cuerpo:
import { createHmac, timingSafeEqual } from 'node:crypto'
function firmaValida(secreto, header, cuerpoCrudo) {
const m = /^t=(\d+),v1=([0-9a-f]{64})$/.exec(header ?? '')
if (!m || Math.abs(Date.now() / 1000 - Number(m[1])) > 300) return false
const esperada = createHmac('sha256', secreto).update(`${m[1]}.${cuerpoCrudo}`).digest()
return timingSafeEqual(esperada, Buffer.from(m[2], 'hex'))
}
- Respondé 2xx rápido (en menos de 10 s); si tu app tarda, encolá el trabajo y respondé.
- Cualquier otra respuesta, un timeout o un error de red se reintenta con espera creciente (1 min, 5 min, 30 min, 2 h, 6 h, 12 h, 24 h): hasta 8 intentos. Las entregas se ven en el portal.
- Un mismo comprobante genera un solo evento aunque repitas la Idempotency-Key. Un webhook pausado no recibe nada (ni lo que tenía en cola) hasta que lo actives. Probar manda como máximo una prueba por minuto.
- Por seguridad no se entregan a direcciones internas (IP privada, localhost) ni se siguen redirecciones.