La regla de oro
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.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.El rate limit, medido
El rate limit, medido
Es el único límite duro que vas a encontrar operando normalmente. Sobre la
búsqueda de comprobantes, con 135 pedidos seguidos:Y el El límite exacto depende de la operación: las de emisión tienen el suyo. El valor
de
429 trae todo lo que hace falta para reintentar bien: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—:
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 dos402, 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.
Por qué el del plan llega antes de que la key exista
Por qué el del plan llega antes de que la key exista
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.
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:
- Si mandaste
externalReference(recomendado): buscalo conGET /v1/invoices/search?externalReference=…y reconciliá conPOST /v1/invoices/{id}/reconcile. - 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
Un422 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; elmensajees para mostrárselo a quien tiene que corregir. erroresyobservacionesson 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 veceserroresviene vacío.- No hay nada de Emissa adentro: ni el pedido, ni el XML, ni un stack.
- El mismo motivo queda en el comprobante (
rechazoArcaenGET /v1/invoices/{id}y en la búsqueda) y llega en el webhookinvoice.resolvedcuando el estado final esREJECTED(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 sindetailsde diagnóstico en producción.
Y el que no dice lo que pasa
Un500 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.
Qué sigue
Cuando el CAE viene rechazado
Los cuatro desenlaces, ejecutados.
Referencia de la API
Qué código de error declara cada operación.