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.
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.
| 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>.
| 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.
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>"
}
GET /api/puntos-venta Authorization: Bearer <key de Contribuyente>
{
"puntos_venta": [
{ "id": 1, "numero": 1 }
]
}
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).
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 }
]
}
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.
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ó.