API Reference

Todo lo que necesitás para integrar facturación electrónica AFIP/ARCA en tu aplicación.

Base URL

https://api.lafactureadora.com.ar

Versión

v1 (estable)

Inicio rápido

Emití tu primera factura en 3 pasos.

  1. 1. Obtené una API key

    Generala desde el dashboard. Las de testing arrancan con lf_test_ y las de producción con lf_live_.

  2. 2. Configurá tu certificado AFIP/ARCA

    Generá un CSR y cargalo en ARCA (WSASS para testing — el certificado aparece como texto en el campo "Resultado"; Administración de Certificados Digitales para producción — se descarga un .crt). Después subí ese certificado con /certs/upload. Ver Certificados.

  3. 3. Emití tu primera factura

    curl -X POST https://api.lafactureadora.com.ar/api/v1/invoices \
      -H "Authorization: Bearer lf_test_tu_api_key" \
      -H "Content-Type: application/json" \
      -d '{
        "cuit": "20359403616",
        "punto_venta": 1,
        "tipo_comprobante": 11,
        "cliente": {
          "tipo_documento": 96,
          "numero_documento": "12345678",
          "razon_social": "Juan Perez"
        },
        "items": [{
          "descripcion": "Servicio web",
          "cantidad": 1,
          "precio_unitario": 50000
        }]
      }'

Autenticación

La API soporta dos métodos. Los endpoints públicos (/health, /health/deep, /plans, /billing/webhook, /whatsapp/webhook, /chat) no requieren auth.

Opción 1 — API Key (recomendada para integraciones)

# Authorization header
Authorization: Bearer lf_live_tu_api_key

# O X-API-Key
X-API-Key: lf_live_tu_api_key

Opción 2 — Firebase ID Token (dashboard web)

Authorization: Bearer eyJhbGciOiJSUzI1NiIs...

Ambientes y prefijos

lf_test_*
Testing

Ambiente homologación. Se fuerza ambiente: "testing". Facturas sin validez fiscal.

lf_live_*
Producción

Facturas reales. Requiere certificado de producción validado.

Atención:Una key lf_test_ solo opera en testing, en TODOS los endpoints que aceptan ambiente (invoices, certs, afip, padrón): si mandás ambiente:"production" recibís 403 TEST_KEY_PRODUCTION, y si lo omitís se fuerza testing. Para producción usá una key lf_live_.

Emitir factura

POST/api/v1/invoices

Emite una factura electrónica y obtiene el CAE de AFIP/ARCA. Si el comprobante es rechazado por race condition (10016) la API reintenta automáticamente con backoff (hasta 5 intentos en total).

Cuidado:Códigos de error 400: error.code es siempre "BAD_REQUEST". El código específico (CLASE_A_REQUIRES_CUIT, INVALID_DOC_NUMBER, DATE_RANGE_INVALID, FCE_NOT_SUPPORTED, etc.) viene en error.details.code. No matchees contra error.code para estos casos.
Atención:FCE MiPyMEs (tipos 201-213) NO están soportados por ahora: requieren informar el CBU del emisor y la API los rechaza con 400 + details.code FCE_NOT_SUPPORTED. Usá los comprobantes estándar A/B/C.
Atención:Comprobantes Clase A (1/2/3/4): AFIP exige receptor con CUIT (DocTipo 80) + condición IVA 1, 6, 11, 13 o 16 (RI o Monotributista — tabla RG 5616). Sino la API devuelve 400 con details.code CLASE_A_REQUIRES_CUIT o CLASE_A_REQUIRES_RI. Inversa: un monotributista no puede recibir clase B (Ley 27618) → 400 con details.code MONO_REQUIRES_CLASE_A.
Atención:IVA en facturas A/B: los items sin alicuota_iva (default 0) se informan como EXENTOS. Si vendés gravado, mandá alicuota_iva explícita (21, 10.5, etc.); para tasa 0% real usá gravado_cero: true.
Nota:Validación de documentos del receptor: CUIT/CUIL/CDI requieren 11 dígitos + módulo 11 válido. DNI requiere 7-8 dígitos. Errores: 400 con details.code INVALID_DOC_NUMBER o INVALID_DOC_CHECKSUM antes de pegarle a AFIP.
Nota:Para servicios (concepto 2/3): fecha_servicio_desde ≤ fecha_servicio_hasta, y fecha_vencimiento_pago ≥ fecha_servicio_desde. Formato yyyy-mm-dd. Errores: 400 con details.code INVALID_DATE_FORMAT, INVALID_DATE o DATE_RANGE_INVALID.
Atención:Si AFIP aprueba con observaciones (warnings), aparecen en data.observaciones: [{code, message}]. Importante: la factura es válida, pero el cliente debería ver el aviso.
Atención:Si la respuesta es 202 Accepted (no 201), el CAE en AFIP es válido pero falló el guardado en nuestra DB. Guardá el CAE de warning.cae para reconciliación.
Nota:Idempotencia: si tu request da timeout no sabés si el CAE se emitió — NO reintentes a ciegas (riesgo de doble CAE). Mandá external_reference (una clave única por venta) y ante timeout reintentá con LA MISMA clave. Posibles respuestas del reintento: 201 (se emitió ahora), 200 con data.already_existed: true (ya estaba emitida — mismo CAE y número, aplica también tras un 202), o 409 EXTERNAL_REFERENCE_IN_PROGRESS (la emisión original sigue procesando: esperá unos minutos y reintentá con la misma clave). La misma clave con OTRO total (>$0,10 de diferencia) devuelve 409 EXTERNAL_REFERENCE_CONFLICT: es un bug de tu integración, cada venta necesita su propia clave. Usá claves distintas para una factura y su NC. La clave también viaja en el webhook invoice.created y se puede consultar con GET /invoices?external_reference=.
Nota:emisor.razon_social puede venir null si el CUIT nunca completó sus datos fiscales (la ficha se auto-crea al vincular). Cargalos con PUT /api/v1/cuits/:cuit.

Body (raíz)

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor (11 dígitos). Debe estar configurado y tener cert validado.
punto_ventanumberPunto de venta tipo RECE (1-99999).
tipo_comprobantenumberNoDefault: 11 (Factura C). Enviar como número JSON (no string). Ver tabla más abajo. FCE MiPyMEs (201-213) no soportados: devuelven 400 con details.code FCE_NOT_SUPPORTED.
conceptonumberNo1: Productos, 2: Servicios, 3: Productos y Servicios. Default: 1.
ambientestringNo"testing" o "production". Con key lf_test_*: si pedís "production" recibís 403 TEST_KEY_PRODUCTION; si lo omitís se usa testing.
external_referencestringNoClave de idempotencia (1-64 chars, opaca, la generás vos — ej: "venta_abc123_f"). Reintentar con la MISMA clave nunca emite dos veces: si la emisión ya se hizo devuelve el comprobante original (200 + data.already_existed), si está en curso devuelve 409 EXTERNAL_REFERENCE_IN_PROGRESS. Única por usuario + ambiente. Ver la nota "Idempotencia".
monedastringNo"PES" (ARS), "DOL" (USD), "EUR". Default: "PES".
cotizacionnumberNoTipo de cambio. OBLIGATORIA (> 0) si moneda != PES — sin ella recibís 400 MONEDA_REQUIRES_COTIZACION. Cotización oficial: POST /afip/wsfev1/FEParamGetCotizacion.
cancelacion_misma_monedastringNoSolo moneda != PES: 'S' si el comprobante se cancela en esa misma moneda, 'N' si no (RG 5259, campo CanMisMonExt). Default: 'N'.
condicion_pagonumberNoSe acepta por compatibilidad pero NO se envía a AFIP (wsfev1 no tiene campo de condición de venta).
observacionesstringNoTexto libre: se persiste y se imprime en el PDF del comprobante (no se envía a AFIP). No confundir con data.observaciones de la respuesta (avisos de AFIP).
fecha_servicio_desdestringNoYYYY-MM-DD. Requerido si concepto es 2 o 3.
fecha_servicio_hastastringNoYYYY-MM-DD. Requerido si concepto es 2 o 3.
fecha_vencimiento_pagostringNoYYYY-MM-DD. Opcional para servicios.

Body > cliente (objeto, requerido)

ParámetroTipoReq.Descripción
tipo_documentonumber80: CUIT, 86: CUIL, 87: CDI, 96: DNI, 94: Pasaporte (5-20 alfanuméricos), 99: Consumidor Final sin identificar (numero_documento debe ser "0" o vacío).
numero_documentostringNúmero del documento (sin guiones).
razon_socialstringNombre o razón social del receptor.
domiciliostringNoDirección del receptor.
emailstringNoEmail del receptor.
condicion_ivanumberNo1: RI, 4: Exento, 5: CF, 6: Monotributo, 11: RI Agente Percep., 13: Monot. Social, 16: Monot. Promovido. Default: 5. Clase A admite 1/6/11/13/16; monotributistas (6/13/16) NO pueden recibir clase B.

Body > items[] (array, requerido, mín. 1)

ParámetroTipoReq.Descripción
descripcionstringDescripción del item.
cantidadnumberNoCantidad. Default: 1.
precio_unitarionumberPrecio unitario en la moneda del comprobante.
alicuota_ivanumberNoPorcentaje IVA: 0, 2.5, 5, 10.5, 21, 27. Default: 0. ATENCIÓN (facturas A/B): con 0 y sin gravado_cero el importe se informa a AFIP como EXENTO (ImpOpEx). En Factura C es irrelevante (sin desglose de IVA).
bonificacionnumberNoPorcentaje de descuento (0-100). Default: 0.
gravadobooleanNoSi el item está gravado con IVA. false lo informa como No Gravado (ImpTotConc). Default: true.
gravado_cerobooleanNoSolo facturas A/B con alicuota_iva 0: true informa el item como GRAVADO a tasa 0% real (AlicIva Id 3), en vez de Exento. Default: false.

Body > comprobante_asociado (objeto, solo NC/ND)

ParámetroTipoReq.Descripción
tiponumberTipo del comprobante original.
punto_ventanumberPV del comprobante original.
numeronumberNúmero del comprobante original.
cuitstringNoCUIT del emisor original.
fechastringNoFecha del comprobante original (YYYY-MM-DD).

Body > tributos[] (array, opcional — IIBB, percepciones)

ParámetroTipoReq.Descripción
idnumberID del tributo según AFIP.
descripcionstringNoDescripción del tributo.
base_imponiblenumberNoBase imponible.
alicuotanumberNoAlícuota del tributo.
importenumberNoImporte del tributo.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/invoices \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "cuit": "20359403616",
    "punto_venta": 1,
    "tipo_comprobante": 11,
    "concepto": 1,
    "cliente": {
      "tipo_documento": 96,
      "numero_documento": "12345678",
      "razon_social": "Juan Perez"
    },
    "items": [{
      "descripcion": "Servicio de desarrollo web",
      "cantidad": 1,
      "precio_unitario": 50000
    }]
  }'
Respuesta
{
  "success": true,
  "data": {
    "id": "5f3a8b9c1e7d4a2b8c1e7d4a",
    "cae": "75044220307741",
    "cae_vencimiento": "20260405",
    "numero_comprobante": 12,
    "tipo_comprobante": 11,
    "punto_venta": 1,
    "fecha": "2026-03-26",
    "total": 50000,
    "neto": 50000,
    "iva": 0,
    "tributos": 0,
    "qr_data": null,
    "observaciones": null,
    "emisor": {
      "cuit": "20359403616",
      "razon_social": "Mi Empresa SRL",
      "punto_venta": 1
    },
    "cliente": {
      "tipo_documento": 96,
      "numero_documento": "12345678",
      "razon_social": "Juan Perez"
    }
  }
}

Listar facturas

GET/api/v1/invoices

Lista las facturas emitidas por el usuario, ordenadas por fecha desc. Filtros opcionales. Paginación con cursor (no offset).

Nota:Paginación: la primera llamada no necesita cursor. La respuesta trae `next_cursor` y `has_more`. Para la siguiente página, pasá `?cursor=<next_cursor>`. Cuando `has_more=false` ya no hay más facturas.

Query parameters

ParámetroTipoReq.Descripción
cuitstringNoFiltrar por CUIT emisor.
ambientestringNo"testing" o "production".
external_referencestringNoLookup puntual por clave de idempotencia: devuelve 0 o 1 resultado dentro del scope usuario + ambiente (si no pasás ambiente se usa el de tu key). Ignora limit/cursor. El campo también viene incluido en los objetos de invoices[] cuando la factura se emitió con clave.
limitnumberNoResultados por página. Default: 50. Max: 200.
cursorstringNoPara paginar: pasar `next_cursor` de la respuesta anterior. Si no se pasa, devuelve la primera página.
Request — cURL
# Primera página
curl "https://api.lafactureadora.com.ar/api/v1/invoices?cuit=20359403616&limit=50" \
  -H "Authorization: Bearer lf_test_tu_api_key"

# Páginas siguientes (usando next_cursor de la respuesta anterior)
curl "https://api.lafactureadora.com.ar/api/v1/invoices?cuit=20359403616&limit=50&cursor=abc123" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "invoices": [
      {
        "id": "abc123",
        "user_id": "fWq8zK1x...",
        "cuit_emisor": "20359403616",
        "ambiente": "testing",
        "tipo_comprobante": 11,
        "punto_venta": 1,
        "numero_comprobante": 12,
        "cae": "75044220307741",
        "cae_vencimiento": "20260405",
        "total": 50000,
        "neto": 50000,
        "iva": 0,
        "tributos": 0,
        "items": [
          { "descripcion": "Servicio de desarrollo web", "cantidad": 1, "precio_unitario": 50000, "total": 50000 }
        ],
        "cliente": {
          "tipo_documento": 96,
          "numero_documento": "12345678",
          "razon_social": "Juan Perez"
        },
        "fecha_emision": "2026-03-26",
        "created_at": "2026-03-26T15:30:00.000Z"
      }
    ],
    "count": 1,
    "next_cursor": "abc123",
    "has_more": true
  }
}

Resumen fiscal mensual

GET/api/v1/invoices/summary

Totales facturados del mes en curso, IVA, tributos y desglose por tipo de comprobante.

Query parameters

ParámetroTipoReq.Descripción
cuitstringNoFiltrar por CUIT emisor.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/invoices/summary?cuit=20359403616" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "mes": "2026-05",
    "total_comprobantes": 12,
    "total_facturado": 685000,
    "total_neto": 566115.7,
    "total_iva": 118884.3,
    "total_tributos": 0,
    "por_tipo": [
      { "tipo_comprobante": 1, "nombre": "Factura A", "cantidad": 8, "total": 580000 },
      { "tipo_comprobante": 6, "nombre": "Factura B", "cantidad": 4, "total": 105000 }
    ],
    "por_estado": { "aprobadas": 12, "rechazadas": 0 }
  }
}

Último comprobante autorizado

GET/api/v1/invoices/last-authorized

Consulta el último número de comprobante autorizado en AFIP/ARCA para un PV y tipo específicos.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
punto_ventanumberPunto de venta.
tipo_comprobantenumberTipo de comprobante.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/invoices/last-authorized?cuit=20359403616&punto_venta=1&tipo_comprobante=11" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "CbteNro": 12,
    "PtoVta": 1,
    "CbteTipo": 11
  }
}

Consultar comprobante en AFIP

GET/api/v1/invoices/query

Consulta un comprobante específico en AFIP/ARCA por su número.

Nota:La respuesta es el resultado crudo de FECompConsultar (wsfev1): los datos vienen en ResultGet. Ojo: el CAE se llama CodAutorizacion y su vencimiento FchVto (nomenclatura AFIP de consulta, distinta a la de emisión). Si el comprobante no existe, AFIP devuelve el detalle en Errors.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
punto_ventanumberPunto de venta.
tipo_comprobantenumberTipo de comprobante.
numeronumberNúmero del comprobante.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/invoices/query?cuit=20359403616&punto_venta=1&tipo_comprobante=11&numero=12" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "ResultGet": {
      "Concepto": 1,
      "DocTipo": 96,
      "DocNro": 12345678,
      "CbteDesde": 12,
      "CbteHasta": 12,
      "CbteFch": "20260326",
      "ImpTotal": 50000,
      "ImpNeto": 50000,
      "ImpIVA": 0,
      "MonId": "PES",
      "MonCotiz": 1,
      "CodAutorizacion": "75044220307741",
      "EmisionTipo": "CAE",
      "FchVto": "20260405",
      "PtoVta": 1,
      "CbteTipo": 11,
      "Resultado": "A"
    }
  }
}

Tipos de comprobante disponibles

GET/api/v1/invoices/types

Lista los tipos de comprobante habilitados para el CUIT en AFIP/ARCA.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/invoices/types?cuit=20359403616" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": [
    { "Id": 1, "Desc": "Factura A", "FchDesde": "20100901", "FchHasta": "20990101" },
    { "Id": 6, "Desc": "Factura B", "FchDesde": "20100901", "FchHasta": "20990101" },
    { "Id": 11, "Desc": "Factura C", "FchDesde": "20100901", "FchHasta": "20990101" }
  ]
}

Generar PDF de comprobante

POST/api/v1/invoices/:id/pdf

Genera el PDF (formato AFIP con QR) de una factura ya emitida. Lookup por :id interno de Firestore (caso común) o por (cuit, punto_venta, tipo_comprobante, numero) en el body como fallback. Devuelve un binario application/pdf.

Nota:El PDF se genera desde la DB de La Factureadora (donde guardamos cae + items + cliente al emitir). NO re-consultamos AFIP — más rápido y robusto.
Atención:Si el comprobante no existe en la DB de La Factureadora (ej. fue emitido por otro sistema o se perdió en un DB_SAVE_FAILED), devuelve 404. Para esos casos, recomendado guardar el binario PDF en tu lado al recibir el 201 inicial.
Atención:Cargá los datos fiscales del CUIT emisor (domicilio_comercial, ingresos_brutos, inicio_actividades) con PUT /api/v1/cuits/:cuit. Son obligatorios en el comprobante impreso (RG 1415): si faltan, el PDF los imprime como "No informado".
Nota:El comprobante incluye la condición frente al IVA del receptor (RG 5616), el IVA discriminado por alícuota real, período facturado y vencimiento de pago en servicios, comprobante asociado en NC/ND, y el QR de RG 4892.
Nota:Comprobantes emitidos antes del 2026-07-30 no tienen guardado el desglose de alícuotas ni la condición IVA del receptor: al reimprimirlos, el IVA aparece en un único renglón sin discriminar.

Path parameter

ParámetroTipoReq.Descripción
:idstringNoID interno de Firestore (el que viene en `data.id` del response de POST /invoices). Si no lo tenés, mandalo como cualquier string (ej. "factura") y la API hace fallback al lookup por body.

Body (JSON) — fallback si :id no es ID interno válido

ParámetroTipoReq.Descripción
cuitstringNoCUIT del emisor. Requerido si :id no es ID interno.
punto_ventanumberNoPunto de venta. Requerido si :id no es ID interno.
tipo_comprobantenumberNoTipo de comprobante. Requerido si :id no es ID interno.
numeronumberNoNúmero del comprobante. Requerido si :id no es ID interno.
Request — cURL
# Caso normal: usar el id que viene en data.id del response de POST /invoices
curl -X POST https://api.lafactureadora.com.ar/api/v1/invoices/5f3a8b9c1e7d4a2b8c1e7d4a/pdf \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  --output factura.pdf

# Fallback si no tenés el id interno: mandalo cualquier cosa en :id y pasá los identificadores en body
curl -X POST https://api.lafactureadora.com.ar/api/v1/invoices/x/pdf \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "cuit": "30718954149",
    "punto_venta": 2,
    "tipo_comprobante": 6,
    "numero": 1
  }' \
  --output factura.pdf
Respuesta
(application/pdf — binario)

Generar CSR (Certificate Signing Request)

POST/api/v1/certs/generate

Genera un CSR + clave privada RSA 2048 para un CUIT. El CSR se pega en ARCA (WSASS para testing, Administración de Certificados Digitales para producción).

Nota:No hace falta pasar por testing: podés generar el certificado de producción directo.
Nota:Efectos secundarios: si el CUIT no estaba vinculado a tu cuenta, este endpoint lo vincula (crea el doc en cuits_configurados) respetando el límite de CUITs de tu plan (403 si lo superás). También descarta CSRs pendientes anteriores del mismo CUIT+ambiente: la clave privada cambia, así que un .crt generado en ARCA con un CSR viejo deja de servir.
Atención:Si el CUIT ya está vinculado a OTRA cuenta, devuelve 403 con error.code CUIT_ALREADY_LINKED. Si superás el límite de CUITs de tu plan, 403 CUIT_LIMIT_EXCEEDED. (Antes del 2026-08-08 los dos casos devolvían FORBIDDEN.)

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT (11 dígitos).
razon_socialstringRazón social o nombre.
condicion_ivanumberNoCódigo AFIP de condición frente al IVA (los mismos que PUT /cuits/:cuit: 1, 4, 5, 6, 8, 9, 10, 11, 13). No se valida: se guarda tal cual.
domicilio_fiscalstringNoDomicilio fiscal.
ambientestringNo"testing" o "production". Default: "testing".
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/certs/generate \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "cuit": "20359403616",
    "razon_social": "Mi Empresa SRL",
    "condicion_iva": 1,
    "ambiente": "testing"
  }'
Respuesta
{
  "success": true,
  "data": {
    "csr": "-----BEGIN CERTIFICATE REQUEST-----\nMIIC...\n-----END CERTIFICATE REQUEST-----",
    "alias": "lafactureadora_20359403616_1716598123456",
    "cuit": "20359403616",
    "ambiente": "testing"
  }
}

Subir certificado .crt firmado por ARCA

POST/api/v1/certs/upload

Sube el certificado .crt firmado por ARCA y lo valida contra la clave privada guardada previamente.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT (11 dígitos).
certificatestringContenido del .crt en formato PEM (con BEGIN/END CERTIFICATE).
ambientestringNo"testing" o "production". Default: "testing".
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/certs/upload \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "cuit": "20359403616",
    "certificate": "-----BEGIN CERTIFICATE-----\nMIIE...\n-----END CERTIFICATE-----",
    "ambiente": "testing"
  }'
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "ambiente": "testing",
    "status": "certificado_activo",
    "validation": {
      "valid": true,
      "validFrom": "2026-03-01T00:00:00Z",
      "validTo": "2028-03-01T00:00:00Z",
      "subject": "CN=20359403616"
    }
  }
}

Listar CSRs sin completar

GET/api/v1/certs/pending

Lista los CSRs generados que aún no fueron completados con un .crt subido. Útil para retomar onboarding a medias.

Query parameters

ParámetroTipoReq.Descripción
ambientestringNoFiltrar por "testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/certs/pending?ambiente=testing" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "pending": [
      {
        "id": "abc123",
        "cuit": "20359403616",
        "ambiente": "testing",
        "alias": "lafactureadora_20359403616_1716598123456",
        "created_at": "2026-05-24T18:30:00.000Z"
      }
    ]
  }
}

Limpiar CSR pendiente

DELETE/api/v1/certs/pending

Borra atómicamente: cert no validado + tokens AFIP cacheados. Si no queda cert validado en ningún ambiente, desvincula también el CUIT del perfil.

Atención:Si el CUIT ya tiene un cert validado y activo en el ambiente, retorna 409 CERT_ALREADY_VALIDATED. Usa /regenerate en su lugar.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT a limpiar.
ambientestring"testing" o "production".
Request — cURL
curl -X DELETE "https://api.lafactureadora.com.ar/api/v1/certs/pending?cuit=20359403616&ambiente=testing" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "ambiente": "testing",
    "deleted_certs": 1,
    "removed_from_profile": true,
    "message": "Se limpió el CSR pendiente y se desvinculó el CUIT 20359403616 del perfil."
  }
}

Regenerar certificado

POST/api/v1/certs/regenerate

Borra los certificados de un CUIT+ambiente de tu cuenta (incluso validados) para poder generar uno nuevo desde cero. También limpia los tokens AFIP cacheados de ese CUIT+ambiente.

Cuidado:Acción destructiva: deja al CUIT sin poder facturar en ese ambiente hasta que generes y subas un certificado nuevo.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT (11 dígitos).
ambientestringNo"testing" o "production". Default: "testing".
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/certs/regenerate \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "cuit": "20359403616", "ambiente": "testing" }'
Respuesta
{
  "success": true,
  "data": {
    "message": "Se eliminaron 1 certificado(s) para CUIT 20359403616 en testing. Ahora podés generar uno nuevo.",
    "cuit": "20359403616",
    "ambiente": "testing"
  }
}

Estado del certificado

GET/api/v1/certs/:cuit/status

Consulta el estado actual del certificado de un CUIT. El campo autoritativo es status: "CSR_GENERADO" (falta subir el .crt), "CERTIFICADO_VALIDADO" (listo para emitir) o "NO_ENCONTRADO" (nunca se generó nada para ese CUIT+ambiente).

Nota:La respuesta incluye también createdAt/updatedAt, validation (resultado de validar el .crt subido) y dos campos legacy hasCertificate/hasPrivateKey que hoy siempre vienen false — ignoralos y usá status.

URL parameters

ParámetroTipoReq.Descripción
:cuitstringCUIT (11 dígitos) en la URL.

Query parameters

ParámetroTipoReq.Descripción
ambientestringNo"testing" o "production". Default: "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/certs/20359403616/status?ambiente=testing" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "status": "CERTIFICADO_VALIDADO",
    "ambiente": "production",
    "alias": "lafactureadora_20359403616_1716598123456"
  }
}

Datos para delegar

GET/api/v1/delegacion/info

Devuelve a que CUIT hay que delegarle el web service y cual es el servicio. Si el deploy no tiene configurada la modalidad, responde { disponible: false } en vez de error.

Nota:La modalidad delegada es una alternativa al certificado propio: el contribuyente le delega wsfe al CUIT de La Factureadora desde su Administrador de Relaciones y nosotros firmamos con nuestro certificado. La API de emision NO cambia: POST /invoices es identico y los comprobantes salen a nombre del contribuyente, con su numeracion y su CAE.
Atención:La delegacion se registra en el ARCA de PRODUCCION. Homologacion es un circuito separado (WSASS) que no se puede delegar: un CUIT delegado solo opera en produccion.
Atención:Consecuencia para integradores: un CUIT delegado NO se puede usar con una API key lf_test_ (esas keys fuerzan ambiente testing). Usa lf_live_ con ambiente "production". Si necesitas un ambiente de pruebas, ese CUIT tiene que tener certificado propio de homologacion.
Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/delegacion/info \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "disponible": true,
    "cuit_delegatario": "30719503337",
    "servicio": "wsfe",
    "servicio_label": "Facturacion Electronica"
  }
}

Marcar un CUIT como delegado

POST/api/v1/delegacion/start

Vincula el CUIT a la cuenta y lo marca en modalidad delegada. Aplica los mismos guards de titularidad que POST /certs/generate.

Nota:Despues de este paso el contribuyente tiene que hacer la delegacion en ARCA (Administrador de Relaciones, Nueva Relacion, WebServices, Facturacion Electronica, CUIT de La Factureadora) y llamar a /delegacion/confirm.
Atención:Consume un slot de CUIT del plan, igual que /certs/generate.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT a facturar. Se acepta con o sin guiones: se normaliza a 11 digitos.
razon_socialstringNoOpcional: si no viene, se completa despues desde el padron.
condicion_ivanumberNoCondicion frente al IVA del emisor.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/delegacion/start \
  -H "Authorization: Bearer lf_live_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{"cuit":"20359403616"}'
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "modo": "delegado",
    "status": "esperando_delegacion",
    "cuit_delegatario": "30719503337",
    "servicio": "wsfe",
    "aviso_cert_propio": null
  }
}

Avisar que ya se delego en ARCA

POST/api/v1/delegacion/confirm

El contribuyente declara que ya hizo la delegacion. Pasa el estado a pendiente_admin: quedan los pasos que hace La Factureadora (aceptar la designacion y asociarla al certificado), que son manuales.

Nota:Por el paso manual, la habilitacion no es instantanea. Usa /delegacion/verify para saber cuando quedo activa.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT en modalidad delegada.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/delegacion/confirm \
  -H "Authorization: Bearer lf_live_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{"cuit":"20359403616"}'
Respuesta
{
  "success": true,
  "data": { "cuit": "20359403616", "status": "pendiente_admin" }
}

Consultar el estado de la delegacion

GET/api/v1/delegacion/status

Devuelve la modalidad del CUIT y, si es delegado, el estado de la cadena en ARCA. No consulta a ARCA: lee lo ultimo verificado.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT a consultar.
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/delegacion/status?cuit=20359403616" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "modo": "delegado",
    "delegacion": {
      "status": "activa",
      "verificada_at": "2026-08-08T22:10:00.000Z",
      "ultima_verificacion_error": null
    },
    "cuit_delegatario": "30719503337"
  }
}

Preguntarle a ARCA si la delegacion ya rige

POST/api/v1/delegacion/verify

Sonda en vivo: llama a FECompUltimoAutorizado con el CUIT del contribuyente. Si ARCA responde sin errores, la cadena esta completa y el estado pasa a activa.

Nota:Es de SOLO LECTURA: no emite comprobantes ni reserva numeracion. Se puede llamar las veces que haga falta.
Nota:Devuelve 200 tanto si esta activa como si no. Mira status y activa en la respuesta, no el codigo HTTP.
Atención:Mientras la cadena no este completa, ARCA responde el error 600 "No aparecio CUIT en lista de relaciones" DENTRO del cuerpo, con HTTP 200. La API lo interpreta y lo devuelve en detalle.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT en modalidad delegada.
ambientestringNoSolo production tiene sentido (es el default).
punto_ventanumberNoPunto de venta a consultar. Default 1.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/delegacion/verify \
  -H "Authorization: Bearer lf_live_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{"cuit":"20359403616","punto_venta":1}'
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "status": "activa",
    "mensaje": "La delegacion esta activa: ya podes emitir con este CUIT."
  }
}

Salir de la modalidad delegada

POST/api/v1/delegacion/cancel

Devuelve el CUIT a modalidad de certificado propio.

Atención:NO da de baja la relacion en ARCA: eso lo hace el contribuyente desde su Administrador de Relaciones. Hasta que suba un certificado propio, no va a poder emitir con ese CUIT.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT en modalidad delegada.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/delegacion/cancel \
  -H "Authorization: Bearer lf_live_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{"cuit":"20359403616"}'
Respuesta
{
  "success": true,
  "data": { "cuit": "20359403616", "modo": "cert_propio" }
}

Listar CUITs configurados

GET/api/v1/cuits

Lista todos los CUITs vinculados a la cuenta con info fiscal y puntos de venta configurados.

Nota:Si un CUIT vinculado no tiene datos fiscales cargados todavía, su entrada viene reducida: { cuit, razon_social: null, condicion_iva: null, status: "active", modo: "cert_propio", delegacion: null } — sin condicion_iva_label ni puntos_venta. No asumas que esos campos siempre están.
Nota:modo indica cómo está vinculado el CUIT con ARCA: "cert_propio" (certificado del contribuyente, es el default) o "delegado" (el contribuyente le delegó wsfe al CUIT de La Factureadora y firmamos con el nuestro).
Nota:delegacion es null en modo cert_propio. En modo delegado trae { status: "esperando_delegacion" | "pendiente_admin" | "activa" | "revocada", solicitada_at, confirmada_at, activada_at, verificada_at, ultima_verificacion_error }. Sólo con status "activa" está confirmado contra ARCA que se puede emitir.
Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/cuits \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "cuits": [
      {
        "cuit": "20359403616",
        "razon_social": "Mi Empresa SRL",
        "condicion_iva": 1,
        "condicion_iva_label": "IVA Responsable Inscripto",
        "status": "active",
        "domicilio_comercial": "Av. Corrientes 1234, CABA",
        "ingresos_brutos": "901-123456-7",
        "inicio_actividades": "2019-03-15",
        "modo": "cert_propio",
        "delegacion": null,
        "puntos_venta": [
          { "numero": 1, "tipo": "electronico" }
        ]
      }
    ]
  }
}

Actualizar datos fiscales de un CUIT

PUT/api/v1/cuits/:cuit

Actualiza los datos fiscales del emisor: condición frente al IVA, razón social, domicilio comercial, ingresos brutos e inicio de actividades. Al menos un campo. Si el CUIT está vinculado pero nunca terminó la configuración (no existe su ficha), devuelve 404.

Atención:domicilio_comercial, ingresos_brutos e inicio_actividades son OBLIGATORIOS en el comprobante impreso (RG 1415). Si no los cargás, el PDF los imprime como "No informado" — nunca inventa un valor.
Nota:Los tres campos de texto se comparan contra undefined, no contra falsy: mandá "" para vaciarlos y omitilos para dejarlos como están. Errores: 400 con details.code INVALID_FIELD_TYPE, FIELD_TOO_LONG, INVALID_DATE_FORMAT o INVALID_DATE.
Nota:El domicilio se puede autocompletar desde el padrón: GET /api/v1/afip/padron devuelve domicilio_fiscal para el CUIT consultado.

URL parameters

ParámetroTipoReq.Descripción
:cuitstringCUIT (11 dígitos) en la URL.

Body (JSON)

ParámetroTipoReq.Descripción
condicion_ivanumberNo1: RI, 4: Exento, 5: CF, 6: Monotributo, 8: Prov.Exterior, 9: Cliente Exterior, 10: Ley 19640, 11: RI Agente Percep., 13: Monot. Social.
razon_socialstringNoRazón social o nombre.
domicilio_comercialstringNoDomicilio comercial que se imprime en el comprobante. Máx 200 caracteres. Mandá "" para borrarlo.
ingresos_brutosstringNoNúmero de Ingresos Brutos o "Convenio Multilateral". Máx 200 caracteres.
inicio_actividadesstringNoFecha de inicio de actividades en formato yyyy-mm-dd.
Request — cURL
curl -X PUT https://api.lafactureadora.com.ar/api/v1/cuits/20359403616 \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "condicion_iva": 1,
    "razon_social": "Mi Empresa SRL",
    "domicilio_comercial": "Av. Corrientes 1234, CABA",
    "ingresos_brutos": "901-123456-7",
    "inicio_actividades": "2019-03-15"
  }'
Respuesta
{
  "success": true,
  "data": {
    "cuit": "20359403616",
    "condicion_iva": 1,
    "condicion_iva_label": "IVA Responsable Inscripto",
    "razon_social": "Mi Empresa SRL",
    "domicilio_comercial": "Av. Corrientes 1234, CABA",
    "ingresos_brutos": "901-123456-7",
    "inicio_actividades": "2019-03-15"
  }
}

Consultar padrón AFIP (constancia de inscripción)

GET/api/v1/afip/padron

Obtiene datos de un contribuyente: razón social, condición frente al IVA real (desde la constancia de inscripción), domicilio fiscal, actividad principal y estado. Cache 24h por CUIT consultado + ambiente.

Atención:El CUIT emisor debe tener autorizado el servicio ws_sr_constancia_inscripcion en ARCA, asociado al alias del certificado. Es una autorización separada de wsfe (vía Administrador de Relaciones → Nueva Relación → WebServices). Con ws_sr_padron_a13 solo (legacy) también funciona, pero ese servicio no informa impuestos: condicion_iva puede venir null (persona física) o inferida (persona jurídica).
Nota:condicion_iva_confirmada: true significa que la condición salió de los impuestos reales de ARCA (fuente "constancia"). Si es false o condicion_iva es null, NO asumas Consumidor Final: pedile la condición al cliente.
Nota:Siempre retorna 200 OK con un wrapper { ok, data?, authorized?, constancia_authorized?, from_cache?, error? } para no romper UX. Inspeccionar data.ok antes de usar data.data. constancia_authorized: false aparece cuando se cayó al fallback A13; from_cache: true cuando el dato salió del cache de 24h.

Query parameters

ParámetroTipoReq.Descripción
cuit_consultastringCUIT que querés consultar (puede ser el propio o el de un cliente).
cuit_emisorstringNoCUIT del emisor que firma. Si no se pasa, usa el primero del usuario.
ambientestringNo"testing" o "production". Default: "production".
forcestringNoPasar "1" para saltear el cache de 24h y consultar ARCA en fresco.
debugstringNoPasar "1" para incluir la respuesta cruda de ARCA en _debug_raw (para diagnóstico).
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/padron?cuit_consulta=30712345678&ambiente=production" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "ok": true,
    "data": {
      "cuit": "30712345678",
      "razon_social": "Empresa SA",
      "tipo_persona": "JURIDICA",
      "estado": "ACTIVO",
      "condicion_iva": 1,
      "condicion_iva_label": "IVA Responsable Inscripto",
      "condicion_iva_confirmada": true,
      "condicion_iva_inferida": null,
      "fuente": "constancia",
      "monotributo_categoria": null,
      "forma_juridica": null,
      "domicilio_fiscal": {
        "direccion": "Av. Corrientes 1234",
        "localidad": "CABA",
        "cod_postal": "1043",
        "provincia": "CIUDAD AUTONOMA BUENOS AIRES"
      },
      "actividad_principal": "Servicios de consultoría informática"
    }
  }
}

Ficha completa de un contribuyente

GET/api/v1/afip/contribuyente

Combina en una sola llamada el padrón (razón social, condición IVA, domicilio) con los catálogos de wsfev1: condiciones IVA de receptor por clase de comprobante (tabla RG 5616) y tipos de comprobante. Si no se pasa cuit_consulta, consulta el propio CUIT emisor.

Nota:El bloque padron tiene los mismos requisitos y formato que GET /api/v1/afip/padron (ws_sr_constancia_inscripcion autorizado en ARCA). Si la consulta al padrón falla, padron viene null y el motivo en padron_error — los catálogos wsfev1 se devuelven igual.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT emisor que firma las consultas (debe estar configurado en tu cuenta, con cert validado).
cuit_consultastringNoCUIT a consultar (ej. un cliente). Default: el mismo cuit.
ambientestringNo"testing" o "production". Default: el ambiente de la key (API key) o "testing" (dashboard).
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/contribuyente?cuit=20359403616&cuit_consulta=30712345678" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "cuit": "30712345678",
    "padron": {
      "razon_social": "Empresa SA",
      "condicion_iva": 1,
      "condicion_iva_label": "IVA Responsable Inscripto",
      "condicion_iva_confirmada": true,
      "...": "mismo formato que data.data de GET /afip/padron"
    },
    "padron_error": null,
    "tipos_comprobante_habilitados": [
      { "id": 1, "descripcion": "Factura A", "fecha_desde": "20100917", "fecha_hasta": null },
      { "id": 6, "descripcion": "Factura B", "fecha_desde": "20100917", "fecha_hasta": null }
    ],
    "condiciones_iva": [
      { "Id": 1, "Desc": "IVA Responsable Inscripto", "Cmp_Clase": "A" },
      { "Id": 5, "Desc": "Consumidor Final", "Cmp_Clase": "B" }
    ]
  }
}

Listar puntos de venta

GET/api/v1/afip/puntos-venta

Lista los puntos de venta habilitados del CUIT en AFIP. Si AFIP no devuelve datos (común en testing), hace fallback a los PVs ya usados en facturas locales.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/puntos-venta?cuit=20359403616&ambiente=production" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "puntos_venta": [
      { "numero": 1, "emision_tipo": "CAE", "bloqueado": false, "fecha_baja": null, "origen": "afip" },
      { "numero": 2, "emision_tipo": "CAE", "bloqueado": false, "fecha_baja": null, "origen": "afip" }
    ],
    "total": 2
  }
}

Último número autorizado

GET/api/v1/afip/ultimo-comprobante

Consulta el último número autorizado para un PV. Si no se pasa tipo_comprobante, consulta los 6 más comunes (1, 6, 11, 3, 8, 13).

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
punto_ventanumberNúmero de PV.
tipo_comprobantenumberNoTipo específico. Si se omite, consulta los más comunes.
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/ultimo-comprobante?cuit=20359403616&punto_venta=1" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "punto_venta": 1,
    "comprobantes": [
      { "tipo_comprobante": 1, "nombre": "Factura A", "ultimo_numero": 12 },
      { "tipo_comprobante": 11, "nombre": "Factura C", "ultimo_numero": 47 }
    ]
  }
}

Health check de AFIP/ARCA

GET/api/v1/afip/estado

Health check de los servicios AFIP/ARCA (WSFEv1). Útil para verificar que AFIP está operativo antes de emitir.

Atención:Siempre responde 200 OK, incluso con AFIP caído: en ese caso data.online viene false, los servicios en "ERROR" y aparece data.error. Un monitor que solo mira el HTTP status no lo detecta — inspeccioná data.online. Para monitoreo por status codes usá GET /api/v1/health/deep?afip=1.

Query parameters

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor (para firmar el dummy).
ambientestringNo"testing" o "production".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/estado?cuit=20359403616&ambiente=production" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "servicios": {
      "app_server": "OK",
      "db_server": "OK",
      "auth_server": "OK"
    },
    "online": true,
    "ambiente": "production",
    "timestamp": "2026-05-30T22:10:33.000Z"
  }
}

Describir un servicio SOAP

GET/api/v1/afip/:service/describe

Devuelve la estructura WSDL de un servicio AFIP/ARCA (métodos con sus inputs/outputs) más la lista plana availableMethods. Útil para explorar qué se puede llamar vía el wrapper genérico.

Nota:No recibe query params: el ambiente sale de la autenticación (lf_test_ → testing, lf_live_ → production; token de dashboard → testing).
Nota:availableMethods lista lo que expone el WSDL, no lo que podés ejecutar: el wrapper POST /:service/:method aplica su propia whitelist (los métodos de emisión están bloqueados).

URL parameters

ParámetroTipoReq.Descripción
:servicestringNombre del servicio. Ej: "wsfev1".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/afip/wsfev1/describe" \
  -H "Authorization: Bearer lf_test_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "service": "wsfev1",
    "environment": "testing",
    "serviceUrl": "https://wswhomo.afip.gov.ar/wsfev1/service.asmx",
    "description": { "Service": { "ServiceSoap": { "FEDummy": { "...": "WSDL completo" } } } },
    "availableMethods": ["FEDummy", "FECompUltimoAutorizado", "FEParamGetTiposCbte", "..."]
  }
}

Wrapper SOAP genérico

POST/api/v1/afip/:service/:method

Llama cualquier método SOAP de AFIP de la whitelist. Útil para operaciones de consulta avanzadas no cubiertas por endpoints específicos.

Atención:Whitelist: FEDummy, FECompUltimoAutorizado, FECompConsultar, FEParamGet* (todos los paramétricos). Los métodos de emisión (FECAESolicitar, FECAEARegInformativo) deben pasar por POST /api/v1/invoices y devuelven 403 METHOD_NOT_ALLOWED_HERE si se intentan acá.

URL parameters

ParámetroTipoReq.Descripción
:servicestringNombre del servicio. Ej: "wsfev1".
:methodstringMétodo SOAP. Debe estar en la whitelist.

Body (JSON)

ParámetroTipoReq.Descripción
cuitstringCUIT del emisor.
ambientestringNo"testing" o "production".
paramsobjectNoParámetros del método SOAP. Default: {}.
Request — cURL
curl -X POST "https://api.lafactureadora.com.ar/api/v1/afip/wsfev1/FEDummy" \
  -H "Authorization: Bearer lf_test_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{ "cuit": "20359403616", "ambiente": "testing" }'
Respuesta
{
  "success": true,
  "data": {
    "success": true,
    "service": "wsfev1",
    "method": "FEDummy",
    "result": {
      "AppServer": "OK",
      "DbServer": "OK",
      "AuthServer": "OK"
    }
  }
}

Crear una nueva API key

POST/api/v1/keys

Genera una API key. La key completa se muestra UNA SOLA VEZ en la respuesta. Después se ve solo el prefijo.

Atención:Requiere un plan con acceso a la API (Profesional o superior). Con un plan menor devuelve 403 API_ACCESS_REQUIRED. Las keys creadas antes de cambiar a un plan menor siguen funcionando.
Nota:Una key lf_test_ no puede crear keys de producción (403 TEST_KEY_PRODUCTION). Usá el dashboard o una key lf_live_.

Body (JSON)

ParámetroTipoReq.Descripción
namestringNombre descriptivo (ej: "Integración WooCommerce").
environmentstringNo"test" (genera lf_test_*) o "production" (genera lf_live_*). Default: "test".
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/keys \
  -H "Authorization: Bearer <firebase_id_token>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Mi integración", "environment": "production" }'
Respuesta
{
  "success": true,
  "data": {
    "key": "lf_live_a1b2c3d4e5f6...",
    "id": "abc123",
    "name": "Mi integración",
    "key_prefix": "lf_live_a1b2c3...",
    "environment": "production",
    "created_at": "2026-03-26T15:30:00Z",
    "warning": "Guardá esta key de forma segura. No se puede recuperar."
  }
}

Listar API keys

GET/api/v1/keys

Lista todas las keys del usuario. Solo se muestra el prefijo (no la key completa).

Este endpoint no requiere parámetros.

Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/keys \
  -H "Authorization: Bearer <firebase_id_token>"
Respuesta
{
  "success": true,
  "data": {
    "keys": [
      {
        "id": "abc123",
        "name": "Mi integración",
        "environment": "production",
        "key_prefix": "lf_live_a1b2c3...",
        "active": true,
        "created_at": "2026-03-26T15:30:00Z",
        "last_used_at": "2026-05-30T22:10:00Z",
        "usage": {
          "total_requests": 12450,
          "month_requests": 1850,
          "month_invoices": 47,
          "current_month": "2026-05"
        }
      }
    ]
  }
}

Revocar una API key

DELETE/api/v1/keys/:keyId

La key deja de funcionar inmediatamente. No es reversible — hay que crear una nueva.

URL parameters

ParámetroTipoReq.Descripción
:keyIdstringID de la key (no la key completa).
Request — cURL
curl -X DELETE https://api.lafactureadora.com.ar/api/v1/keys/abc123 \
  -H "Authorization: Bearer <firebase_id_token>"
Respuesta
{
  "success": true,
  "data": { "revoked": true }
}

Crear suscripción en MercadoPago

POST/api/v1/billing/subscribe

Crea una suscripción en MercadoPago y devuelve la URL de pago para redirigir al usuario. Si ya tenés una suscripción activa devuelve 400 (usá change-plan).

Body (JSON)

ParámetroTipoReq.Descripción
planstring"emprendedor" ($6.990), "profesional" ($14.990), "empresa" ($29.990) o "corporativo" ($49.990).
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/billing/subscribe \
  -H "Authorization: Bearer <firebase_id_token>" \
  -H "Content-Type: application/json" \
  -d '{ "plan": "profesional" }'
Respuesta
{
  "success": true,
  "data": {
    "init_point": "https://www.mercadopago.com.ar/subscriptions/checkout?preapproval_id=...",
    "subscription_id": "mp_sub_abc123"
  }
}

Estado de la suscripción

GET/api/v1/billing/status

Consulta el plan actual y el estado de la suscripción del usuario.

Este endpoint no requiere parámetros.

Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/billing/status \
  -H "Authorization: Bearer <firebase_id_token>"
Respuesta
{
  "success": true,
  "data": {
    "plan": "profesional",
    "subscription": {
      "mp_id": "mp_sub_abc123",
      "status": "authorized",
      "plan_requested": "profesional",
      "created_at": "2026-03-01T00:00:00Z"
    }
  }
}

Cambiar de plan

PUT/api/v1/billing/change-plan

Upgrade o downgrade. Crea una suscripción nueva en MP en estado pending y devuelve su init_point. La suscripción vieja sigue activa (cobrando el plan actual) hasta que MP confirma el pago de la nueva: recién ahí el webhook "authorized" cancela la anterior, activa el plan nuevo y reconcilia los CUITs (suspende excedentes en downgrade / reactiva en upgrade). Si el usuario abandona el pago, no cambia nada.

Nota:Devuelve 400 (BAD_REQUEST) si: ya estás en ese plan, estás en período de prueba (usá /subscribe), o no tenés una suscripción activa (usá /subscribe).

Body (JSON)

ParámetroTipoReq.Descripción
planstring"emprendedor", "profesional", "empresa" o "corporativo".
Request — cURL
curl -X PUT https://api.lafactureadora.com.ar/api/v1/billing/change-plan \
  -H "Authorization: Bearer <firebase_id_token>" \
  -H "Content-Type: application/json" \
  -d '{ "plan": "empresa" }'
Respuesta
{
  "success": true,
  "data": {
    "init_point": "https://www.mercadopago.com.ar/subscriptions/checkout?...",
    "subscription_id": "mp_sub_xyz789",
    "previous_plan": "profesional",
    "new_plan": "empresa",
    "is_downgrade": false
  }
}

Historial de pagos

GET/api/v1/billing/history

Devuelve el historial de pagos autorizados de la suscripción del usuario, consultado en vivo desde MercadoPago.

Este endpoint no requiere parámetros.

Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/billing/history \
  -H "Authorization: Bearer <firebase_id_token>"
Respuesta
{
  "success": true,
  "data": {
    "payments": [
      {
        "id": "mp_pay_123",
        "date": "2026-05-15T14:00:00.000Z",
        "amount": 14990,
        "status": "approved",
        "status_detail": "accredited",
        "payment_method": "visa"
      }
    ],
    "plan": "profesional",
    "subscription_status": "authorized"
  }
}

Cancelar suscripción

POST/api/v1/billing/cancel

Cancela en MercadoPago todas las suscripciones vivas de la cuenta (la actual y, si quedó una de un cambio de plan a medio camino, también esa). El plan baja a Free y se suspenden CUITs excedentes. Si alguna baja falla en MercadoPago, el plan NO se cambia: preferimos dejarte el servicio antes que bajarte a Gratis mientras el cobro sigue activo.

Este endpoint no requiere parámetros.

Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/billing/cancel \
  -H "Authorization: Bearer <firebase_id_token>"
Respuesta
{
  "success": true,
  "data": {
    "message": "Suscripción cancelada. Tu plan ahora es Gratis. 2 CUIT(s) fueron suspendidos por exceder el límite del plan.",
    "suspended_cuits": 2
  }
}

Webhook de MercadoPago

POST/api/v1/billing/webhookPública

Endpoint llamado automáticamente por MercadoPago. No llamar manualmente. Procesa eventos subscription_preapproval con validación HMAC-SHA256 + idempotencia por evento (mp_id + status + x-request-id de MP), de modo que las renovaciones mensuales con el mismo estado se procesan igual.

Nota:En producción exige headers x-signature y x-request-id válidos según MP. En dev/test se permiten requests sin firma para test notifications.
Request — cURL
# Configurado en el panel de MP. Recibe POST automático cuando cambia estado de suscripción.
Respuesta
OK

Registrar un webhook

POST/api/v1/webhooks

Registra una URL HTTPS tuya para recibir eventos de tu cuenta (POST con payload JSON firmado). Máximo 5 webhooks activos por cuenta.

Cuidado:El secret (whsec_...) se devuelve UNA SOLA VEZ en esta respuesta y no se puede recuperar después. Guardalo: lo necesitás para verificar la firma de cada entrega.
Nota:Cada entrega es un POST a tu URL con headers X-LF-Event, X-LF-Webhook-Id y X-LF-Signature: "t=<timestamp>,v1=<hmac>". Para verificar: calculá HMAC-SHA256 con tu secret sobre el string "<timestamp>.<body JSON crudo>" (el timestamp del header, un punto, y el body tal cual llegó) y comparalo con v1. Respondé 2xx en menos de 10s; cualquier otra cosa se reintenta.
Nota:Reintentos: un intento inmediato + cron cada 5 min con backoff (1, 4, 9, 16 min desde el último intento), máximo 5 intentos en total. Después queda failed_permanently. Las entregas repetidas llevan header X-LF-Retry.
Nota:Payload de cada evento: { "event": "...", "timestamp": 1750000000, "data": { ... } }. invoice.created: data es el mismo objeto que devuelve POST /invoices (cae, numero_comprobante, total, etc.). invoice.rejected: { cuit, punto_venta, tipo_comprobante, ambiente, error }. cert.expiring_soon: { cuit, ambiente, valid_until, days_remaining }.

Body (JSON)

ParámetroTipoReq.Descripción
urlstringURL HTTPS pública (puerto 443). Se rechazan http://, IPs privadas/localhost/metadata (anti-SSRF) y URLs ya registradas.
eventsstring[]Eventos a suscribir: invoice.created, invoice.rejected (AFIP rechazó el comprobante), subscription.payment_succeeded, subscription.payment_failed, subscription.cancelled, cert.expiring_soon (certificado vence en ≤30 días; un aviso por certificado, chequeo diario).
descriptionstringNoDescripción libre para identificarlo.
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/webhooks \
  -H "Authorization: Bearer lf_live_tu_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "url": "https://miapp.com/hooks/lafactureadora",
    "events": ["invoice.created"],
    "description": "Sync de facturas con mi ERP"
  }'
Respuesta
{
  "success": true,
  "data": {
    "id": "wh_abc123",
    "url": "https://miapp.com/hooks/lafactureadora",
    "events": ["invoice.created"],
    "description": "Sync de facturas con mi ERP",
    "secret": "whsec_1a2b3c4d5e6f...64 hex chars",
    "active": true,
    "warning": "Guardá este secret. Lo vas a usar para verificar la firma X-LF-Signature de cada webhook. No se puede recuperar despues."
  }
}

Listar webhooks

GET/api/v1/webhooks

Lista tus webhooks. El secret no se expone completo (solo un prefijo).

Este endpoint no requiere parámetros.

Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/webhooks \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "webhooks": [
      {
        "id": "wh_abc123",
        "url": "https://miapp.com/hooks/lafactureadora",
        "events": ["invoice.created"],
        "description": "Sync de facturas con mi ERP",
        "active": true,
        "secret_prefix": "whsec_1a2b3c...",
        "created_at": "2026-07-01T12:00:00.000Z"
      }
    ],
    "available_events": ["invoice.created", "invoice.rejected", "subscription.payment_succeeded", "subscription.payment_failed", "subscription.cancelled", "cert.expiring_soon"]
  }
}

Eliminar un webhook

DELETE/api/v1/webhooks/:id

Desactiva el webhook (soft delete: se conserva el historial de entregas). Deja de recibir eventos inmediatamente.

Este endpoint no requiere parámetros.

Request — cURL
curl -X DELETE https://api.lafactureadora.com.ar/api/v1/webhooks/wh_abc123 \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": { "id": "wh_abc123", "deactivated": true }
}

Historial de entregas

GET/api/v1/webhooks/:id/deliveries

Últimas entregas del webhook, para debug: estado, HTTP status del destino, intentos y error.

Query parameters

ParámetroTipoReq.Descripción
limitnumberNoCantidad de entregas. Default: 20. Máximo: 100.
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/webhooks/wh_abc123/deliveries?limit=20" \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "deliveries": [
      {
        "id": "dl_xyz",
        "event": "invoice.created",
        "status": "delivered",
        "http_status": 200,
        "attempts": 1,
        "duration_ms": 412,
        "error": null,
        "created_at": "2026-07-01T12:34:56.000Z",
        "delivered_at": "2026-07-01T12:34:56.500Z"
      },
      {
        "id": "dl_abc",
        "event": "invoice.created",
        "status": "pending_retry",
        "http_status": 500,
        "attempts": 2,
        "duration_ms": 9800,
        "error": "HTTP 500",
        "created_at": "2026-07-01T11:00:00.000Z",
        "delivered_at": null
      }
    ]
  }
}

Chat IA (Gemini)

POST/api/v1/chatPública

Proxy a Gemini IA (gemini-2.5-flash-lite) con prompts especializados. Endpoint público con rate-limit estricto.

Atención:Rate limits: 20 mensajes/min/IP (CHAT_RATE_LIMIT) y 200/hora/IP (CHAT_RATE_LIMIT_HOUR).

Body (JSON)

ParámetroTipoReq.Descripción
messagesarrayHistoria de mensajes: [{ role, text }]. role = "user" | "model".
contextstringNo"soporte" (técnico, default) o "ventas" (no menciona precios).
Request — cURL
curl -X POST https://api.lafactureadora.com.ar/api/v1/chat \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      { "role": "user", "text": "¿Cómo configuro un punto de venta en AFIP?" }
    ],
    "context": "soporte"
  }'
Respuesta
{
  "success": true,
  "data": {
    "reply": "Para crear un punto de venta web services en AFIP/ARCA..."
  }
}

Perfil del usuario autenticado

GET/api/v1/me

Devuelve el perfil, uso del mes, CUITs configurados y CUITs suspendidos por downgrades.

Nota:Con API key, usage refleja el consumo de ESA key (si tenés varias keys, cada una reporta lo suyo). Con Firebase token (dashboard), month_requests siempre es 0.
Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/me \
  -H "Authorization: Bearer lf_live_tu_api_key"
Respuesta
{
  "success": true,
  "data": {
    "user": {
      "email": "usuario@ejemplo.com",
      "display_name": "Juan Perez",
      "company": "Mi Empresa SRL",
      "plan": "profesional"
    },
    "usage": {
      "month_requests": 1850,
      "month_invoices": 47,
      "invoice_limit": 200,
      "cuits_configured": 1,
      "cuit_limit": 2
    },
    "environment": "production",
    "cuits": ["20359403616"],
    "suspended_cuits": []
  }
}

Health check

GET/api/v1/healthPública

Verifica que la API esté online. Endpoint público (sin auth).

Este endpoint no requiere parámetros.

Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/health
Respuesta
{
  "success": true,
  "data": {
    "status": "ok",
    "version": "1.0.0",
    "timestamp": "2026-05-30T22:10:33.000Z"
  }
}

Health check profundo

GET/api/v1/health/deepPública

Verifica la API y sus dependencias: Firestore siempre, AFIP wsfev1 solo si se pide con ?afip=1. Pensado para monitoreo externo (Better Stack, UptimeRobot, etc.): si Firestore falla responde 503. Endpoint público (sin auth).

Nota:Solo Firestore es crítico: si falla, status "degraded" + HTTP 503. AFIP caído NO tira 503 (se cae seguido y no es un problema de la API) — queda reflejado en checks.afip_wsfev1.status: "error".

Query parameters

ParámetroTipoReq.Descripción
afipstringNoPasar "1" para incluir el ping a AFIP wsfev1 (FEDummy público, timeout 5s). Si se omite, ese check viene "skipped".
Request — cURL
curl "https://api.lafactureadora.com.ar/api/v1/health/deep?afip=1"
Respuesta
{
  "success": true,
  "data": {
    "status": "ok",
    "version": "1.0.0",
    "timestamp": "2026-05-30T22:10:33.000Z",
    "checks": {
      "api": { "status": "ok" },
      "firestore": { "status": "ok", "latency_ms": 42 },
      "afip_wsfev1": { "status": "ok", "latency_ms": 850 }
    }
  }
}

Listar planes disponibles

GET/api/v1/plansPública

Lista los 5 planes públicos con precios, límites y features reales. Endpoint público (sin auth).

Nota:Período de prueba: toda cuenta nueva arranca con 14 días del plan Emprendedor sin cargo (50 facturas/mes). Al vencer, si no te suscribiste, la cuenta pasa a Gratis (10 facturas/mes) y se suspenden los CUITs que excedan el límite del plan.
Request — cURL
curl https://api.lafactureadora.com.ar/api/v1/plans
Respuesta
{
  "success": true,
  "data": {
    "plans": [
      { "id": "free", "name": "Gratis", "price": 0, "invoicesPerMonth": 10, "maxCuits": 1, "features": ["production", "chat_support"] },
      { "id": "emprendedor", "name": "Emprendedor", "price": 6990, "invoicesPerMonth": 50, "maxCuits": 1, "features": ["production", "pdf_qr", "clients", "chat_support"] },
      { "id": "profesional", "name": "Profesional", "price": 14990, "invoicesPerMonth": 200, "maxCuits": 2, "features": ["production", "pdf_qr", "clients", "api_access", "chat_support"] },
      { "id": "empresa", "name": "Empresa", "price": 29990, "invoicesPerMonth": 500, "maxCuits": 5, "features": ["production", "pdf_qr", "clients", "api_access", "chat_support"] },
      { "id": "corporativo", "name": "Corporativo", "price": 49990, "invoicesPerMonth": 1500, "maxCuits": 10, "features": ["production", "pdf_qr", "clients", "api_access", "chat_support"] }
    ]
  }
}

Tipos de comprobante

Códigos AFIP/ARCA aceptados en el campo tipo_comprobante al emitir facturas. Los comprobantes FCE MiPyMEs (201-213) no están soportados por ahora: la API los rechaza con 400 y details.code: "FCE_NOT_SUPPORTED".

CódigoTipo
1Factura A
6Factura B
11Factura C
3Nota de Crédito A
8Nota de Crédito B
13Nota de Crédito C
2Nota de Débito A
7Nota de Débito B
12Nota de Débito C
4Recibo A
9Recibo B
15Recibo C

Códigos de error

Todas las respuestas de error siguen el mismo formato:

{
  "success": false,
  "error": {
    "code": "INVALID_CUIT",
    "message": "Dígito verificador inválido",
    "details": { ... }
  }
}
HTTPCódigoDescripción
400BAD_REQUESTDatos de entrada inválidos o faltantes. En los errores de validación de facturas, el código específico viene en error.details.code (filas "↳" de abajo).
400↳ details.code: FCE_NOT_SUPPORTEDFCE MiPyMEs (tipos 201-213) no soportados. Usá comprobantes estándar A/B/C.
400↳ details.code: CLASE_A_REQUIRES_CUITComprobantes Clase A (1/2/3/4) requieren receptor con CUIT (tipo_documento 80).
400↳ details.code: CLASE_A_REQUIRES_RIReceptor de Clase A debe ser RI o Monotributista (condicion_iva 1, 6, 11, 13 o 16 — tabla RG 5616).
400↳ details.code: MONO_REQUIRES_CLASE_AReceptor monotributista (condicion_iva 6/13/16) no puede recibir Clase B: le corresponde Clase A (Ley 27618 / RG 5003).
400↳ details.code: INVALID_DOC_NUMBERcliente.numero_documento no cumple el formato esperado para ese tipo_documento (CUIT/CUIL/CDI 11 dígitos, DNI 7-8, tipo 99 exige 0 o vacío).
400↳ details.code: INVALID_DOC_CHECKSUMCUIT/CUIL/CDI del receptor no pasa validación módulo 11.
400↳ details.code: CONDICION_IVA_REQUIREDReceptor identificado con CUIT (tipo_documento 80): cliente.condicion_iva es obligatoria (consultala en GET /afip/padron).
400↳ details.code: MONEDA_REQUIRES_COTIZACIONCon moneda distinta de PES, cotizacion explícita > 0 es obligatoria (cotización oficial vía FEParamGetCotizacion).
400↳ details.code: INVALID_CAN_MIS_MON_EXTcancelacion_misma_moneda solo admite 'S' o 'N' (RG 5259, comprobantes en moneda extranjera).
400↳ details.code: INVALID_DATE_FORMATLas fechas de servicio no respetan el formato yyyy-mm-dd.
400↳ details.code: INVALID_DATEUna fecha de servicio no es válida (ej. 2026-02-30).
400↳ details.code: DATE_RANGE_INVALIDfecha_servicio_desde > fecha_servicio_hasta, fecha_vencimiento_pago < fecha_servicio_desde, o fecha_vencimiento_pago anterior a hoy (AFIP 1411).
400INVALID_CUITCUIT no pasa validación módulo 11.
400MISSING_CUITFalta el campo cuit requerido.
401UNAUTHORIZEDNo se envió ninguna credencial reconocible (ni API key ni token).
401MISSING_API_KEYNo se envió API key.
401INVALID_API_KEYAPI key inválida, revocada o de cuenta desactivada.
401API_KEY_REVOKEDSolo POST /invoices: la key fue revocada entre la autenticación y la reserva de cupo.
401MISSING_TOKENNo se envió header Authorization.
401TOKEN_EXPIREDFirebase token expirado.
401INVALID_TOKENToken malformado o inválido.
401USER_NOT_FOUNDUsuario no existe en el sistema.
403FORBIDDENGenérico de permisos: CUIT de otra cuenta (certs/cuits/afip/listados) o recurso ajeno (PDF, webhook). El límite de CUITs y el CUIT ya vinculado tienen ahora códigos propios.
403ACCOUNT_DISABLEDCuenta desactivada (con Firebase token).
403CUIT_NOT_AUTHORIZEDCUIT no pertenece a tu cuenta (endpoints con requireCuitAccess, ej. POST /invoices, /certs/upload).
403CUIT_LIMIT_EXCEEDEDLímite de CUITs del plan alcanzado. En POST /invoices con CUIT nuevo, y también en POST /certs/generate y POST /delegacion/start (antes devolvían FORBIDDEN).
403TEST_KEY_PRODUCTIONKey lf_test_* pidiendo ambiente production. Se aplica en todos los endpoints que aceptan ambiente.
403API_ACCESS_REQUIREDPOST /keys: tu plan no incluye acceso a la API (disponible desde Profesional). details.upgrade_url apunta al cambio de plan.
403METHOD_NOT_ALLOWED_HEREMétodo SOAP bloqueado en /afip/:service/:method (usa /invoices para emitir). Los métodos permitidos vienen en error.allowed_methods.
403WEBHOOK_LIMIT_EXCEEDEDMáximo 5 webhooks activos por cuenta.
400CUIT_ES_DELEGATARIOPOST /delegacion/start: intentaste delegar el CUIT de La Factureadora a sí mismo.
400NO_DELEGADO/delegacion/confirm y /delegacion/verify: el CUIT no está en modalidad delegada (llamá antes a /delegacion/start).
400INVALID_PUNTO_VENTAPOST /delegacion/verify: punto_venta tiene que ser un entero mayor a 0.
403CUIT_ALREADY_LINKEDEl CUIT ya pertenece a otra cuenta. Aplica a POST /certs/generate y POST /delegacion/start.
403CUIT_EN_MODO_DELEGADOPOST /certs/generate sobre un CUIT delegado. Salí de la modalidad con POST /delegacion/cancel antes de generar un certificado propio.
503DELEGACION_NOT_AVAILABLELa modalidad delegada no está habilitada en este deploy. Usá el certificado propio.
404NOT_FOUNDRecurso no encontrado.
409CERT_ALREADY_VALIDATEDNo se puede limpiar pending si ya hay cert validado activo (usa /regenerate).
409WEBHOOK_DUPLICATE_URLYa existe un webhook activo con esa URL.
409EXTERNAL_REFERENCE_IN_PROGRESSPOST /invoices: ya hay una emisión en curso con ese external_reference. Esperá unos minutos y reintentá con la MISMA clave (si terminó, recibís el comprobante original).
409EXTERNAL_REFERENCE_CONFLICTPOST /invoices: el external_reference ya se usó para un comprobante con OTRO total. Bug de integración — cada venta necesita su propia clave. Los datos del comprobante existente vienen en error.details.
429RATE_LIMIT_EXCEEDEDLímite de requests por minuto excedido.
429INVOICE_QUOTA_EXCEEDEDLímite mensual de facturas del plan alcanzado.
429CHAT_RATE_LIMIT/chat: 20 mensajes/min/IP alcanzado.
429CHAT_RATE_LIMIT_HOUR/chat: 200 mensajes/hora/IP alcanzado.
500INTERNAL_ERRORError interno del servidor.
502AFIP_ERRORError hablando con AFIP/ARCA. Incluye tanto caídas/timeouts (reintentable) como RECHAZOS definitivos del comprobante: si error.message empieza con "AFIP RECHAZO: [código]", NO reintentar — corregí los datos.

Rate limits & cuotas

La API aplica tres niveles de límite: global por IP, por plan/key, y cuota mensual de facturas.

Global por IP

200 / 15min

Anti-abuso, aplica a todos.

/chat (público)

20/min · 200/hora

Por IP.

Dashboard

Sin rate

Firebase Token skip rate-limit por plan.

Por plan (API Keys)

PlanPrecioRate limitFacturas/mesCUITs
Gratis$010 req/min101
Emprendedor$6.99030 req/min501
Profesional$14.990100 req/min2002
Empresa$29.990200 req/min5005
Corporativo$49.990500 req/min1.50010

Headers de respuesta

HeaderDescripción
RateLimit-LimitLímite de la ventana (por plan cuando usás API key).
RateLimit-RemainingRequests restantes en la ventana.
RateLimit-ResetSegundos hasta que se reinicia la ventana.
X-Request-IdID único de la request (útil para soporte).