Documentación de la API
api-arca convierte los Web Services oficiales de ARCA y los procesos de portal en una API REST limpia. Emití comprobantes con CAE real, dá de alta tenants desde el panel de administración con su Clave Fiscal, y olvidate del portal.
https://api.tu-dominio.com Entornos
ARCA distingue dos ambientes: homologación (testing, comprobantes sin validez fiscal) y producción (CAE real). api-arca apunta a uno u otro según las credenciales y la configuración del servidor — la URL de la API no cambia, lo que cambia es contra qué WS de ARCA pega cada tenant.
| Entorno | Para qué | Comprobantes |
|---|---|---|
| Homologación | Probar la integración | CAE de testing, sin validez fiscal |
| Producción | Facturar de verdad | CAE real ante ARCA |
Antes de integrar, confirmá contra qué entorno está configurado tu tenant. Para chequear
que el servicio está vivo: GET /api/v1/health → {"status":"ok"}
(público, sin API key — útil para liveness/readiness probes).
Autenticación
Todos los endpoints de /api/v1/* (excepto GET /api/v1/health)
requieren autenticación con API key. Enviá la key en el header:
x-api-key: TU_API_KEY
La API key se obtiene al dar de alta un tenant desde el panel de administración
(/admin). No hay auto-registro: es el operador del servidor quien crea tenants,
con sus propias credenciales de admin (ADMIN_USER / ADMIN_PASSWORD).
Cada tenant tiene su propia key, aislada del resto.
Quickstart
1. Iniciá sesión en el panel de admin
curl -X POST https://api.tu-dominio.com/admin/login \
-H 'content-type: application/json' \
-d '{ "user": "admin", "password": "••••••••" }'
Respuesta: {"token": "..."}. Usá ese token como
Bearer en el siguiente paso.
2. Dá de alta un tenant
curl -X POST https://api.tu-dominio.com/admin/tenants \
-H 'authorization: Bearer TOKEN_DE_ADMIN' \
-H 'content-type: application/json' \
-d '{
"cuit": "20111111112",
"password": "••••••••",
"alias": "miempresa",
"environment": "homo",
"perfil": {
"razonSocial": "Mi Empresa S.A.",
"domicilioComercial": "Av. Siempreviva 742",
"condicionIva": "Responsable Inscripto",
"ingresosBrutos": "901-123456-7",
"inicioActividades": "01/01/2020"
}
}'
Respuesta: {"tenantId": "miempresa", "apiKey": "ark_live_...", "cuit": "20111111112", "environment": "homo"}
422 (todavía no soportamos 2FA en este flujo). La Clave Fiscal
(password) es efímera: se usa para el alta y no se persiste.
3. Emití una factura
curl -X POST https://api.tu-dominio.com/api/v1/invoices \
-H 'x-api-key: ark_live_...' \
-H 'content-type: application/json' \
-d '{
"tipoComprobante": 11,
"condicionIvaReceptor": 5,
"issuer": { "razonSocial": "Mi Empresa S.A.",
"domicilioComercial": "Av. Siempreviva 742",
"condicionIva": "Responsable Inscripto",
"ingresosBrutos": "901-123456-7",
"inicioActividades": "01/01/2020" },
"receptor": { "razonSocial": "Consumidor Final", "domicilio": "-",
"condicionIva": "Consumidor Final",
"docTipo": 99, "docNro": "0", "condicionVenta": "Contado" },
"items": [{ "descripcion": "Servicio de consultoría",
"cantidad": 1, "precioUnitario": 10000 }]
}'
Respuesta: {"comprobante": 37, "cae": "86250296302175", "vencimiento": "2026-06-28", "resultado": "A"}
Si incluís items (líneas de detalle), el comprobante se persiste para poder
re-descargar el PDF legal por CAE. Sin items, se emite solo el CAE.
¿Necesitás el PDF? Mirá PDF legal.
PDF legal
Una vez que emitiste con POST /api/v1/invoices incluyendo el detalle (emisor,
receptor y líneas), descargás el PDF legal (RG 1415, con QR oficial de AFIP RG 4892)
usando el CAE en GET /api/v1/invoices/by-cae/{cae}/pdf.
¿Por qué por CAE? El PDF lleva datos que los Web Services de AFIP no almacenan (los renglones no existen del lado de ARCA). Entonces persistimos el documento legal al emitir y lo re-renderizamos cuando lo pedís por CAE. Si la persistencia falla, la emisión igual devuelve el CAE (best-effort) y se loguea el error.
Descargar el PDF por CAE
curl https://api.tu-dominio.com/api/v1/invoices/by-cae/86250296302175/pdf \
-H 'x-api-key: ark_live...' \
-o factura.pdf content-type: application/pdf). El cuit del emisor se toma
siempre del tenant autenticado, no del body.
En Factura A/B el campo alicuotaIva es obligatorio (id de alícuota AFIP,
p. ej. 5 = 21%). En Factura C no va, porque no discrimina IVA. Mirá la
tabla de alícuotas.
Notas de crédito y débito
Las notas se emiten por el mismo POST /api/v1/invoices, cambiando el
tipoComprobante (p. ej. 3 = Nota de Crédito A,
13 = Nota de Crédito C). Lo que las distingue de una factura es que
deben referenciar el comprobante original en
comprobantesAsociados.
curl -X POST https://api.tu-dominio.com/api/v1/invoices \
-H 'x-api-key: ark_live_...' \
-H 'content-type: application/json' \
-d '{ "tipoComprobante": 13, "total": 12100,
"condicionIvaReceptor": 5,
"comprobantesAsociados": [
{ "tipo": 11, "puntoVenta": 1, "numero": 37 }
] }' comprobantesAsociados es un array de
{ tipo, puntoVenta, numero } (y opcionalmente cuit).
Es obligatorio para notas de crédito/débito: sin él, ARCA rechaza el
comprobante. La letra de la nota debe coincidir con la de la factura original.
Padrón y puntos de venta
Constancia de inscripción
GET /api/v1/taxpayers/{cuit} devuelve la razón social, condición frente al
IVA y domicilio del CUIT consultado.
curl https://api.tu-dominio.com/api/v1/taxpayers/20111111112 \
-H 'x-api-key: ark_live_...'
Respuesta: {"cuit": "...", "razonSocial": "...", "condicionIva": "...", "domicilio": "..."}
Puntos de venta
GET /api/v1/points-of-sale lista los puntos de venta habilitados para el CUIT
del tenant.
curl https://api.tu-dominio.com/api/v1/points-of-sale \
-H 'x-api-key: ark_live_...'
Respuesta: [{"numero": 1, "tipo": "...", "estado": "..."}]
Constatar un comprobante
GET /api/v1/vouchers/{puntoVenta}/{tipo}/{numero} consulta a AFIP los
datos de un comprobante ya emitido (CAE, vencimiento, resultado). Útil para verificar
que un comprobante quedó autorizado.
curl https://api.tu-dominio.com/api/v1/vouchers/1/11/37 \
-H 'x-api-key: ark_live_...'
Respuesta: {"tipo": 11, "puntoVenta": 1, "numero": 37, "cae": "...", "vencimiento": "...", "resultado": "A"}
Errores y códigos de estado
Todos los errores vuelven en JSON. Para errores de validación de contrato (Zod) viene el
detalle por campo en issues; para el resto, un error con el
mensaje.
// 400 — validación de contrato
{ "error": "Validación fallida",
"issues": [ { "path": "total", "message": "Required" } ] }
// 401 — API key inválida o ausente
{ "error": "API key inválida o ausente" } | Código | Significado | Cuándo |
|---|---|---|
| 200 | OK | La operación se completó (CAE emitido, consulta resuelta). |
| 400 | Bad Request | El body no cumple el contrato, o params inválidos. Mirá issues. |
| 401 | Unauthorized | Falta o es inválida la x-api-key. |
| 422 | Unprocessable | El CUIT pide 2FA en el alta de tenant sincrónica (aún no soportado). |
| 503 | Service Unavailable | Capacidad no cableada: alta de tenants sin Postgres+vault, o PDF sin Playwright. |
POST /admin/tenants requiere Postgres + vault;
GET /api/v1/invoices/by-cae/{cae}/pdf requiere Playwright instalado en el server.
Referencia API
La referencia interactiva completa vive en el playground: cada endpoint, con sus modelos y autenticación por API key, para probar en vivo desde el navegador.
Tablas de referencia
Tipos de comprobante
| Código | Tipo | Letra |
|---|---|---|
| 1 | Factura | A |
| 2 | Nota de Débito | A |
| 3 | Nota de Crédito | A |
| 6 | Factura | B |
| 7 | Nota de Débito | B |
| 8 | Nota de Crédito | B |
| 11 | Factura | C |
| 12 | Nota de Débito | C |
| 13 | Nota de Crédito | C |
Condición IVA del receptor (condicionIvaReceptor)
El número que va en condicionIvaReceptor — en los ejemplos verás 5 (Consumidor Final).
| Código | Condición |
|---|---|
| 1 | IVA Responsable Inscripto |
| 4 | IVA Sujeto Exento |
| 5 | Consumidor Final |
| 6 | Responsable Monotributo |
| 7 | Sujeto No Categorizado |
| 8 | Proveedor del Exterior |
| 9 | Cliente del Exterior |
| 10 | IVA Liberado (Ley 19.640) |
| 13 | Monotributista Social |
| 15 | IVA No Alcanzado |
IDs de alícuota de IVA (alicuotaIva)
Ojo con la diferencia: en POST /api/v1/invoices sin detalle, el array
iva usa alicuota como porcentaje (p. ej.
21). Cuando mandás items para generar PDF,
alicuotaIva es el id AFIP de la alícuota (la tabla de abajo).
| Id | Alícuota |
|---|---|
| 3 | 0% |
| 4 | 10,5% |
| 5 | 21% |
| 6 | 27% |
| 8 | 5% |
| 9 | 2,5% |