Emitir factura
Emitir factura A, B o C con CAE mediante WSFEv1.
Emite una factura electrónica (tipo A, B o C) y devuelve el CAE asignado por ARCA.
Endpoint
POST /api/wsfe/facturasRequest
curl -X POST https://arca.api.com.ar/api/wsfe/facturas \
-H "Authorization: Bearer ak_TuSecretoAqui" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: pedido-uuid-1234" \
-d '{
"environment": "homologacion",
"representada": "27111111118",
"cbteTipo": 6,
"ptoVta": 1,
"docTipo": 80,
"docNro": "30999888777",
"concepto": 1,
"condicionIvaReceptorId": 1,
"email": "cliente@empresa.com",
"items": [
{
"cantidad": 2,
"descripcion": "Servicio de consultoría",
"precioUnitario": 10000.00,
"alicuotaIva": 21
}
]
}'Parámetros
| Campo | Tipo | Descripción |
|---|---|---|
environment | "homologacion" | "produccion" | Entorno de ARCA |
representada | string (11 dígitos) | CUIT representado que emite |
cbteTipo | number | Tipo de comprobante: 1 (Fac A), 6 (Fac B), 11 (Fac C) |
ptoVta | number (opcional) | Punto de venta. Si lo omitís usamos el configurado para ese CUIT; la respuesta siempre informa cuál se usó |
docTipo | number | Tipo de documento del receptor (ej. 80 = CUIT, 96 = DNI) |
docNro | string | Número de documento del receptor |
concepto | number | 1 = Productos, 2 = Servicios, 3 = Productos y servicios |
condicionIvaReceptorId | number | Condición IVA del receptor |
items | array | Lista de ítems (ver debajo) |
clienteId | string (opcional) | Id de un cliente guardado. Completa docTipo, docNro, condicionIvaReceptorId y email: ver Emitir por referencia |
email | string (opcional) | Destinatario al que se le envía el comprobante por email al aprobarse |
cbteFch | string (opcional) | Fecha del comprobante YYYYMMDD (default: hoy) |
moneda | string (opcional) | Código de moneda (default: "PES") |
cotizacion | number (opcional) | Cotización (default: 1) |
fchServDesde | string (obligatorio si concepto = 2 o 3) | Fecha inicio servicio YYYYMMDD |
fchServHasta | string (obligatorio si concepto = 2 o 3) | Fecha fin servicio YYYYMMDD |
fchVtoPago | string (obligatorio si concepto = 2 o 3) | Fecha vencimiento de pago YYYYMMDD |
Ítems (items[])
| Campo | Tipo | Descripción |
|---|---|---|
cantidad | number | Cantidad de unidades. Siempre la mandás vos |
descripcion | string | Descripción del ítem |
precioUnitario | number | Precio unitario neto (sin IVA) |
alicuotaIva | number | Alícuota de IVA en porcentaje: 0, 2.5, 5, 10.5, 21, 27 |
productoId | string (opcional) | Id de un producto guardado. Completa descripcion, precioUnitario y alicuotaIva: ver Emitir por referencia |
El sistema calcula automáticamente ImpNeto, ImpIVA, ImpTotal y el desglose de IVA por alícuota. Para factura tipo C, no se discrimina IVA y alicuotaIva es ignorado.
Punto de venta
ptoVta es opcional. Si lo omitís, lo resolvemos así, deteniéndonos en lo primero que aplique:
- El punto de venta configurado para ese CUIT en el dashboard (Certificados → editar el CUIT).
- Lo que ARCA informa como habilitado: si hay uno solo, ese.
- El punto de venta
1.
La respuesta siempre incluye el ptoVta con el que se emitió, así que nunca quedás sin saber cuál se usó.
Si mandás el campo, tu valor gana siempre: no lo pisa el configurado ni la consulta a ARCA. Y no
lo completamos con un 1 por default a propósito — es justo el número que en la mayoría de las
cuentas no está habilitado para web services (ver
el punto de venta no está habilitado).
Esto vale para WSFEv1. En WSFEX (exportación) ptoVta sigue siendo obligatorio: los puntos
de venta de exportación se declaran por separado en ARCA y no son los mismos que los del mercado
interno, así que no podemos deducirlos del que configuraste acá.
Envío por email
Si mandás email y el comprobante resulta aprobado, se le envía al destinatario con el PDF
adjunto, sin que hagas nada más. El envío ocurre después de la respuesta, así que no le suma
latencia a la emisión, y su estado viaja en el campo email de la respuesta. Ver
Envío por email.
Idempotencia
Podés enviar el header Idempotency-Key con cualquier string único (UUID, ID de tu sistema, etc.). Si reenviás la misma solicitud con la misma key, el sistema devuelve el comprobante ya emitido sin volver a llamar a ARCA y sin reenviar el email.
Idempotency-Key: pedido-uuid-1234Emitir por referencia (clienteId / productoId)
Si guardaste el receptor en tu agenda de clientes o el ítem en tu catálogo de productos, podés referenciarlos en lugar de repetir sus datos en cada request:
| Campo | Dónde va | Qué completa |
|---|---|---|
clienteId | En el comprobante | docTipo, docNro, condicionIvaReceptorId y email |
productoId | En cada ítem | descripcion, precioUnitario y alicuotaIva |
El mismo request de arriba, con referencias:
curl -X POST https://arca.api.com.ar/api/wsfe/facturas \
-H "Authorization: Bearer ak_TuSecretoAqui" \
-H "Content-Type: application/json" \
-d '{
"environment": "homologacion",
"representada": "27111111118",
"cbteTipo": 6,
"ptoVta": 1,
"concepto": 1,
"clienteId": "8f1c2b3a-4d5e-6f70-8192-a3b4c5d6e7f8",
"items": [
{ "productoId": "c3e5a7b9-1d2f-4068-8a9b-0c1d2e3f4a5b", "cantidad": 2 }
]
}'La respuesta es idéntica a la de la emisión escrita a mano: las referencias son una comodidad de escritura del request, no un modo distinto de emitir.
Podés mezclar libremente: un comprobante puede llevar clienteId con ítems escritos a mano, o un receptor explícito con ítems del catálogo, o cualquier combinación ítem por ítem.
cantidad siempre la mandás vos. No es un atributo del catálogo: el mismo producto se vende en cantidades distintas.
El campo explícito siempre gana
La referencia es un default que completa lo que el request no trae, nunca un candado que pisa lo que escribiste. Si mandás los dos, vale el tuyo:
{
"clienteId": "8f1c2b3a-4d5e-6f70-8192-a3b4c5d6e7f8",
"email": "otra-direccion@empresa.com",
"items": [
{
"productoId": "c3e5a7b9-1d2f-4068-8a9b-0c1d2e3f4a5b",
"cantidad": 2,
"precioUnitario": 8500
}
]
}Ese comprobante sale con el documento y la condición frente al IVA del cliente guardado, pero con el email del request; y con la descripción y la alícuota del producto, pero con el precio del request. Es la forma de aplicar un descuento puntual o mandar el comprobante a otra dirección sin tener que editar la agenda ni el catálogo.
El comprobante guarda valores, no punteros
Las referencias se resuelven en el momento de emitir. El comprobante persiste los datos resueltos, así que editar después el cliente o cambiar el precio del producto no altera nada de lo ya emitido —cosa que además sería ilegal: un comprobante con CAE es inmutable.
Dicho al revés: actualizar el catálogo es cómo subís precios hacia adelante, no cómo reescribís el pasado.
Errores de resolución
Una referencia que no se puede resolver devuelve 400, antes de llamar a ARCA: no consume cuota ni avanza la numeración, así que corregís y reintentás sin costo.
| Mensaje | Causa |
|---|---|
No se encontró el cliente <id> en tu cuenta | El id no existe, es de otra cuenta o lo diste de baja. Los tres casos son indistinguibles a propósito |
No se encontró el producto <id> en tu cuenta | Ídem, para un productoId de algún ítem |
El cliente <id> no tiene condición frente al IVA cargada | El cliente existe pero le falta condicionIvaReceptorId, que la emisión exige |
El producto <id> no tiene alícuota de IVA cargada | El producto existe pero le falta alicuotaIva |
Los dos últimos ocurren porque el modelo guardado es más laxo que el de emisión: esos campos son opcionales al guardar y obligatorios al emitir. Nunca los inferimos. Un 21% supuesto o una condición frente al IVA adivinada producen un comprobante fiscalmente incorrecto con CAE, y eso no se puede deshacer; un 400 cuesta un reintento.
Se resuelven de cualquiera de las dos formas: completando el dato en el recurso guardado, o mandándolo explícito en el body.
Ver No pudimos resolver una referencia.
clienteId no aplica a WSFEX: el cliente guardado modela un receptor argentino (documento de ARCA y condición frente al IVA), y un receptor de exportación necesita país de destino e identificación del exterior. productoId sí funciona en WSFEX, pero sólo completa descripcion y precioUnitario: cantidad y unidadMedida los seguís mandando vos, y la alícuota de IVA no aplica a la exportación.
Respuesta exitosa
{
"resultado": "A",
"cae": "75050000000001",
"caeFchVto": "20251225",
"cbteNro": 42,
"ptoVta": 1,
"cbteTipo": 6,
"observaciones": [],
"errores": [],
"pdfUrl": null,
"email": { "to": "cliente@empresa.com", "status": "pending" }
}El campo email sólo aparece si mandaste un destinatario. Su status en la respuesta de emisión es
pending (el envío arranca recién después de responderte) o skipped en homologación, que nunca
envía mails. El estado final se consulta después: ver Envío por email.
Comprobante rechazado
Si ARCA rechaza el comprobante devuelve HTTP 422:
{
"resultado": "R",
"cae": null,
"caeFchVto": null,
"cbteNro": null,
"ptoVta": 1,
"cbteTipo": 6,
"observaciones": [
{ "code": 10048, "msg": "El importe no coincide con el calculado" }
],
"errores": [],
"pdfUrl": null
}Un comprobante rechazado no consume cuota de tu plan: sólo se cuentan las facturas que obtuvieron CAE. Corregí lo que indica observaciones[].code y reintentá sin costo. Ver ARCA rechazó el comprobante.
Errores
Antes de reintentar una emisión, leé Reintentar sin duplicar el comprobante: un 502 no significa que el comprobante no se haya emitido.