API de FacturAgil para integradores

Referencia para conectar un sistema externo (ERP, plugin de e-commerce, etc.) con FacturAgil: alta de cuentas y emisión de comprobantes por API, sin intervención humana.

URL base

https://facturagil.com.ar

Un solo dominio -- no hay subdominio api. separado. Todos los endpoints de este documento cuelgan de /api/... sobre esa misma base.

Autenticación -- dos niveles de key, no confundir

Key La tiene Sirve para
Key de Integrador La plataforma que se integra (vos, una sola vez) Únicamente POST /api/onboarding/contribuyentes -- dar de alta cuentas nuevas
Key de Contribuyente Cada cuenta/tenant creada en FacturAgil (una por cuenta) Todo lo demás: emitir facturas, notas de crédito/débito, listar puntos de venta, etc.

El onboarding (POST /api/onboarding/contribuyentes) se autentica con la key de Integrador, pero devuelve en la respuesta un campo api_key que es la key del Contribuyente recién creado -- esa es la que hay que guardar y usar para todo lo que venga después. Son dos keys distintas con alcances distintos; usar la de Integrador donde corresponde la de Contribuyente (o viceversa) devuelve 401.

En todos los casos, la key va en el header: Authorization: Bearer <key>.

Endpoints

Método Endpoint Auth Para qué
POST /api/onboarding/contribuyentes Key de Integrador Alta de un Contribuyente nuevo (auto-onboarding)
GET /api/puntos-venta Key de Contribuyente Lista los puntos de venta habilitados (para obtener el punto_venta_id)
POST /api/comprobantes Key de Contribuyente Emitir una Factura A/B/C
POST /api/comprobantes/{id}/nota-credito Key de Contribuyente Nota de Crédito (total o parcial) de una factura ya emitida
POST /api/comprobantes/{id}/nota-debito Key de Contribuyente Nota de Débito de una factura ya emitida
GET /api/comprobantes/{id}/pdf Key de Contribuyente Descarga el PDF de un comprobante con CAE

El {id} de estos tres últimos es el id interno del comprobante (el que devuelve FacturAgil en la respuesta de POST /api/comprobantes), no el número de AFIP.

1. Dar de alta un Contribuyente

Activo de inmediato, sin verificación de email -- pensado para un alta 100% automática.

POST /api/onboarding/contribuyentes
Authorization: Bearer <key de Integrador>
Content-Type: application/json

{
  "cuit": "20111111112",
  "razon_social": "Cliente Ejemplo SA",
  "condicion_iva": "Responsable Inscripto",
  "email": "admin@cliente-ejemplo.com",
  "nombre": "Nombre del administrador"
}

condicion_iva acepta: Responsable Inscripto, Monotributo, Exento. password es opcional (si no viene, se genera una al azar; el administrador puede recuperarla luego con "olvidé mi contraseña").

Respuesta (201):

{
  "contribuyente_id": 42,
  "cuit": "20111111112",
  "razon_social": "Cliente Ejemplo SA",
  "plan_estado": "trial",
  "api_key": "<key de Contribuyente -- guardar, no se vuelve a mostrar>"
}

2. Consultar los puntos de venta

GET /api/puntos-venta
Authorization: Bearer <key de Contribuyente>
{
  "puntos_venta": [
    { "id": 1, "numero": 1 }
  ]
}

3. Emitir una factura

POST /api/comprobantes
Authorization: Bearer <key de Contribuyente>
Content-Type: application/json

{
  "punto_venta_id": 1,
  "receptor": {
    "tipo_documento": "CUIT",
    "numero_documento": "20111111112",
    "razon_social": "Cliente Ejemplo SA",
    "condicion_iva_receptor": "Responsable Inscripto",
    "email": "cliente@ejemplo.com"
  },
  "items": [
    { "descripcion": "Producto X", "cantidad": 1, "precio_unitario": 1000, "alicuota_iva": 21 }
  ]
}

tipo_documento acepta: CUIT, DNI, CF (Consumidor Final, sin documento). condicion_iva_receptor acepta: Responsable Inscripto, Monotributo, Exento, Consumidor Final. alicuota_iva usa los valores habituales de AFIP (0, 10.5, 21, 27). email/whatsapp del receptor son opcionales -- si vienen, quedan cargados para poder enviarle el comprobante.

Respuesta (201 si AFIP aprobó, 422 si lo rechazó -- mismo formato en ambos casos, y también en Nota de Crédito/Débito):

{
  "id": 501,
  "estado": "emitida",
  "tipo": "A",
  "comprobante_asociado_id": null,
  "punto_venta": 1,
  "numero": 23,
  "numero_formateado": "0001-00000023",
  "cae": "72345678901234",
  "cae_vencimiento": "2026-08-18",
  "importe_total": 1210,
  "observaciones": null
}

Si AFIP rechaza el comprobante, estado/cae reflejan eso y observaciones trae el motivo (respuesta 422, no un error HTTP genérico -- el comprobante igual queda guardado en FacturAgil para reintentar o auditar).

4. Nota de Crédito / Nota de Débito

Sobre una factura ya emitida (identificada por su id interno, el que devolvió el paso anterior). Nota de Crédito sin items = anula el total; con items = parcial.

POST /api/comprobantes/501/nota-credito
Authorization: Bearer <key de Contribuyente>
Content-Type: application/json

{}

Nota de Débito exige items siempre (es un cargo nuevo, no una anulación):

POST /api/comprobantes/501/nota-debito
Authorization: Bearer <key de Contribuyente>
Content-Type: application/json

{
  "items": [
    { "descripcion": "Ajuste", "cantidad": 1, "precio_unitario": 100, "alicuota_iva": 21 }
  ]
}

5. Descargar el PDF

GET /api/comprobantes/501/pdf
Authorization: Bearer <key de Contribuyente>

Devuelve el PDF directo (Content-Type: application/pdf). 409 si el comprobante todavía no tiene CAE.

Errores

Todos los endpoints devuelven { "error": "..." } con el código HTTP correspondiente: 401 (key inválida o del tipo equivocado), 400 (datos faltantes o inválidos), 404/409 según el caso puntual, 502 si AFIP no respondió.