Skip to main content
La referencia declara qué código de error devuelve cada operación. Esto es lo otro: de quién es el problema y si se reintenta.

La regla de oro

Un 4xx de validación nunca deja nada colgado. Un 409, un 500 o un 502 al emitir, sí. Ante los segundos, consultá los comprobantes sin resolver antes de reintentar.
Y la red de seguridad que sirve siempre: reintentar con la misma clave de idempotencia no puede duplicar nada.

La forma de todos los errores

Todos tienen la misma, y el id del pedido es el dato que conviene loguear: identifica el pedido exacto si hay que reportar algo.
message es estable y apto para mostrar; details es el que dice la causa concreta y puede cambiar. No parsees details; ramificá por errorCode.En producción, details no viaja cuando es material de diagnóstico: contá con errorCode y con lo que la guía de cada error dice cómo recuperar.
Qué está medido y qué no. Los códigos marcados con ✅ se provocaron contra la API y la respuesta publicada es la que devolvió. El resto sale del catálogo de errores del código —el estado HTTP y el mensaje son los declarados— pero no se ejecutaron: varios necesitan que ARCA se caiga o que venza un certificado, y no se pueden forzar a voluntad. La columna «qué hacer» es, en esos casos, la conducta que el propio código documenta.

Credenciales y permisos

Son todos tuyos, y ninguno se arregla reintentando — salvo el último.
Usá Retry-After, no un backoff inventado. Y las tres cabeceras X-RateLimit-* vienen en todas las respuestas, no sólo en el 429: mirando cuánto te queda podés bajar el ritmo antes de chocar.
Es el único límite duro que vas a encontrar operando normalmente. Sobre la búsqueda de comprobantes, con 135 pedidos seguidos:
Y el 429 trae todo lo que hace falta para reintentar bien:
El límite exacto depende de la operación: las de emisión tienen el suyo. El valor de X-RateLimit-Limit es el que rige para el pedido que acabás de hacer.

El alta de un contribuyente que ya existe

POST /v1/taxpayers con un CUIT que ya está dado de alta en ese ambiente devuelve 409 RESOURCE_ALREADY_EXISTS. Si el contribuyente incluye tu producto entre los suyos (puede ser de varios), la respuesta trae su id en details.taxpayerId, también en producción —es un dato contractual, no de diagnóstico—:
Si el contribuyente existe pero no incluye tu producto, no tiene ninguno o es de otra organización, el 409 viene sin id: el CUIT está tomado pero no es uno que tu key alcance, y el id de un contribuyente ajeno no se informa. El 409 tampoco te suma a ese contribuyente: sumar un producto a un contribuyente existente lo hace el dueño de la cuenta desde el panel. Con una key sin producto, el id viaja para los contribuyentes de tu organización. Ver la sección «Varios productos en una organización» de la guía de integración.

La cuenta

Dos códigos, los dos 402, y ninguno se reintenta.
Un 402 no es transitorio: no describe un pedido que salió mal sino una condición de la cuenta, así que reintentarlo en bucle sólo gasta cuota de rate limit. Los dos traen details con el motivo y cómo resolverlo, justamente para que se pueda distinguir eso sin parsear texto.

La mora es la única causal de bloqueo que existe

Excederse de la cuota no bloquea nada — ver la regla 3 de los planes. Lo único que bloquea es la mora sostenida, y llega con 15 días de aviso por correo. El ciclo completo está en cómo se te cobra.
Y bloquea poco: alcanza a emitir y anular, nada más. Consultar comprobantes, descargar PDF y leer el consumo siguen funcionando — lo que ya se facturó es evidencia del cliente, no una función premium que se apague por falta de pago.
No lo devuelve /v1: lo devuelve el panel, al crear la API key. Está puesto ahí a propósito.Una key se muestra una sola vez y se guarda; dejarla crear para después rechazar cada llamada haría descubrir el límite recién cuando la integración ya está escrita, que es el peor momento posible.Por eso lo vas a ver en el panel y no en una respuesta de la API: si llegaste hasta acá con una key en la mano, no es tu caso.

Antes de llegar a ARCA: lo que Emissa rechaza

Todos 4xx, y todos tienen la misma virtud: no consumen número de comprobante. Es más barato equivocarse acá que en ARCA.

Estado del comprobante

ARCA

Acá está el que importa. La tabla completa y ejecutada está en qué hacer cuando el CAE viene rechazado; ésta es la versión corta.
ARCA_CAE_UNKNOWN en dos frases. La respuesta de ARCA se perdió y no se sabe si el comprobante quedó autorizado. Reintentar con una clave nueva puede emitir un segundo comprobante fiscal por la misma venta — está demostrado, con la serie resultante, en la guía del CAE rechazado.La salida es reconciliar, que le pregunta al organismo.
Cómo encontrás el comprobante si details no viaja. En producción este 409 llega sin details: no trae el id del comprobante que quedó sin resolver. Hay dos caminos, y los dos funcionan sin ese dato:
  1. Si mandaste externalReference (recomendado): buscalo con GET /v1/invoices/search?externalReference=… y reconciliá con POST /v1/invoices/{id}/reconcile.
  2. Si no la mandaste: listá los irresueltos con GET /v1/invoices/unresolved?taxpayerId=… y reconciliá el que corresponda.
Una externalReference de un comprobante REJECTED no se puede reusar. Un rechazo fiscal libera el número, pero el comprobante rechazado sigue registrado con su referencia, así que mandarla de nuevo devuelve 409 EXTERNAL_REFERENCE_ALREADY_USED. Para reemitir corregido, mandá una referencia nueva —por ejemplo, la original con un sufijo de intento— y una Idempotency-Key nueva.

El motivo de un rechazo fiscal viaja siempre

Un 422 ARCA_WSFEV1_REJECTED no es un error técnico: ARCA contestó y dijo que no, y por qué es información tuya para corregir y reintentar. Por eso, a diferencia del resto de details, viaja también en producción (los textos del ejemplo son ilustrativos; los reales son los que devuelve ARCA):
  • El texto es el de ARCA, literal. Emissa no lo traduce ni lo reescribe: sólo lo recorta a 500 caracteres por mensaje y a 20 ítems por lista. Ramificá por codigo; el mensaje es para mostrárselo a quien tiene que corregir.
  • errores y observaciones son distintas. Un error es lo que impidió autorizar. Una observación es lo que ARCA marcó, y cuando no manda errores suele ser el único motivo: por eso a veces errores viene vacío.
  • No hay nada de Emissa adentro: ni el pedido, ni el XML, ni un stack.
  • El mismo motivo queda en el comprobante (rechazoArca en GET /v1/invoices/{id} y en la búsqueda) y llega en el webhook invoice.resolved cuando el estado final es REJECTED (data.rechazoArca). Con la misma forma.
  • No aplica a los demás errores. ARCA_CAE_UNKNOWN, los errores de validación de Emissa y los técnicos siguen sin details de diagnóstico en producción.

Y el que no dice lo que pasa

Un 500 INTERNAL_ERROR al emitir puede dejar un comprobante tomando número, y el mensaje no lo menciona: dice «Error interno del servidor» y nada más.
Medido: el comprobante quedó sin resolver, apareció en la lista de irresueltos y se destrabó reconciliando. Así que ante un 500 al emitir, mirá los sin resolver en vez de reintentar. Es la misma precaución que el 409, con un mensaje que no la sugiere.

Qué sigue

Cuando el CAE viene rechazado

Los cuatro desenlaces, ejecutados.

Referencia de la API

Qué código de error declara cada operación.