Errores y límites
Formato
Sección titulada «Formato»Todos los errores tienen la misma forma: un objeto con una sola clave error,
cuyo mensaje está en español y es apto para mostrarle a una persona.
{ "error": "No se encontró el CUIT solicitado." }Códigos
Sección titulada «Códigos»| Código | Cuándo | Qué hacer |
|---|---|---|
400 |
Parámetros inválidos | Corregí el pedido. El mensaje dice qué campo falla. |
401 |
Token ausente o inválido | Revisá el header Authorization. Ver Autenticación. |
403 |
Tu suscripción no está activa, o tu cuenta no tiene habilitada la escritura por API | Ver Sobre el 403. |
404 |
El CUIT no existe o no es tuyo | Verificá el CUIT y que esté cargado en tu cuenta. |
409 |
El pedido choca con el estado actual de tu cuenta | Aparece en POST y en DELETE. Reintentarlo igual no cambia nada. |
415 |
El cuerpo no viajó como application/json |
Solo aparece en POST y PATCH. Agregá el header Content-Type. |
429 |
Se superó un límite de uso | Esperá lo que indique Retry-After. |
500 |
Error interno | Reintentá; si persiste, escribinos. |
Sobre el 403
Sección titulada «Sobre el 403»Un 403 tiene dos motivos y el mensaje te dice cuál es.
Si tu suscripción no está activa, lo vas a ver en todos los endpoints, también en los de lectura. El mensaje cambia según por qué se cortó. Si Mercado Pago no pudo cobrar el último pago:
{ "error": "Mercado Pago pausó tu suscripción porque no pudimos procesar el último pago. Reactivala en https://app.afippi.com/dashboard/subscription para volver a acceder a tus datos." }Y si la suscripción terminó o nunca se activó:
{ "error": "Tu suscripción no está activa. Suscribite en https://app.afippi.com/dashboard/subscription para volver a acceder a tus datos." }En los dos casos se arregla desde el panel de Afippi, y el acceso vuelve en el pedido siguiente: no hace falta generar un token nuevo.
El otro motivo es que tu cuenta no tenga habilitada la escritura por API. Ese solo aparece en los endpoints de escritura y no se activa desde el panel: lo habilita el equipo de Afippi. Ver Escritura.
Sobre el 404
Sección titulada «Sobre el 404»Un CUIT que no existe y un CUIT que existe pero pertenece a otra cuenta responden exactamente lo mismo. Es deliberado: si respondiéramos distinto, cualquiera podría usar la API para averiguar qué CUITs administran otros estudios.
Sobre el 409
Sección titulada «Sobre el 409»POST /v1/cuits responde 409 cuando el CUIT ya está cargado en tu cuenta:
{ "error": "El CUIT ya está registrado" }Es lo que hace innecesaria una idempotency key: si un POST se corta por timeout
y lo reintentás, el segundo pedido responde 409 en vez de duplicar el cliente.
Un 409 después de un reintento significa que el primero funcionó.
DELETE /v1/cuits/{cuit} responde 409 cuando el cliente representa a alguna
sociedad cargada en tu cuenta: borrala, o cambiale el representante, y reintentá.
Validación
Sección titulada «Validación»Cuando fallan varios campos, los mensajes se concatenan en un solo error:
{ "error": "'from_date' debe tener formato YYYY-MM-DD. 'offset' debe ser un entero mayor o igual a 0." }Límites de uso
Sección titulada «Límites de uso»Hay dos límites y se aplican por usuario, no por token: generar un token nuevo no reinicia ninguno de los dos contadores.
| Límite | Ventana |
|---|---|
| 100 pedidos | por minuto |
| 200.000 pedidos | por mes calendario |
El mes calendario se calcula en UTC: el contador vuelve a cero el día 1 a las 00:00 UTC, no a la medianoche argentina.
Cuando te pasás
Sección titulada «Cuando te pasás»{ "error": "Se superó el límite de solicitudes. Intentá nuevamente más tarde." }Con status 429 y estos headers:
| Header | Qué dice |
|---|---|
Retry-After |
Segundos a esperar antes de reintentar |
X-RateLimit-Limit |
El límite que se superó (100 o 200000) |
X-RateLimit-Remaining |
Siempre 0 en un 429 |
X-RateLimit-Reset |
Timestamp Unix en el que se libera el límite |
Mirá X-RateLimit-Limit para saber cuál de los dos límites tocaste: si dice
200000, esperar unos segundos no te va a servir.
Reintentos
Sección titulada «Reintentos»Ante un 429, esperá lo que diga Retry-After en vez de reintentar de una. Ante
un 500, un backoff exponencial con algo de jitter es lo razonable. No reintentes
400, 401, 403, 404, 409 ni 415: el resultado va a ser el mismo.
Estado del servicio
Sección titulada «Estado del servicio»GET /healthcheck responde OK en texto plano si la API está en servicio. Es
público, no consume cuota y no requiere token.