PRÓXIMAMENTE afiPAPI ahora también como librería PHP — facturá ARCA desde tu propio hosting. Ver el adelanto →
Guía · /ping

Chequeá antes de facturar

El endpoint /ping explicado en criollo: qué es, todas las opciones que podés pedir, y cómo leer la respuesta para decidir si conviene conectarte o no.

¿Qué es y para qué sirve?

/ping te dice, antes de intentar facturar, si "hay línea" con los servidores que vas a necesitar. En vez de lanzar una operación contra ARCA y esperar a que falle porque no hay internet o porque ARCA está caído, primero preguntás "¿está todo accesible?" y con esa respuesta decidís si seguís o esperás.

Chequea dos cosas de cada servidor:

Pensalo como el semáforo antes de cruzar: verde → procedés a conectarte; rojo → mejor mostrás "sin conexión con ARCA, reintentá en un rato" en vez de colgar el programa.

La respuesta es instantánea

afiPAPI no hace el chequeo en el momento en que preguntás. Tiene un proceso interno que va midiendo la conectividad solo, cada 30 segundos, y guarda el último resultado. Cuando preguntás, te devuelve ese dato ya guardado, sin que esperes nada. Por eso podés consultarlo seguido sin penalización.

La única vez que "espera" es la primera vez que le pedís un servidor nuevo que nunca chequeó: ahí lo mide en el momento, lo guarda, y de ahí en más sale instantáneo. Si un servidor tuyo no se pide por 15 minutos, sale de la rotación (se deja de chequear hasta que lo vuelvas a pedir).

Dos formas de llamarlo

MétodoCuándoCómo
GETSolo querés chequear los servidores de ARCASin cuerpo, todo por la URL
POSTAdemás querés chequear servidores tuyos (ej. tu MySQL)Con un cuerpo JSON donde definís qué chequear

Los dos devuelven exactamente el mismo formato de respuesta. El GET es el atajo cómodo; el POST es el que te da las opciones.

Las opciones del request (POST)

El JSON que mandás tiene 3 campos, todos con un valor por defecto sensato:

POST /api/afip/ping
{
  "produccion": false,
  "incluirAfip": true,
  "destinos": [ ... ]
}

produccion — opcional, default false

Elige contra qué ambiente de ARCA se mide. false = homologación (pruebas); true = producción (el real). Importa porque homo y prod son máquinas distintas: puede estar arriba una y caída la otra.

incluirAfip — opcional, default true

Dice si en la respuesta querés que vengan los servidores de ARCA (WSAA + WSFE) o no. Ponelo en false cuando querés chequear únicamente algo tuyo, sin arrastrar el chequeo de ARCA.

destinos — opcional, una lista

Acá va la consulta personalizada: uno o varios servidores tuyos a chequear. Cada destino es un objeto con estos campos:

Campo¿Obligatorio?Qué es
hostLa dirección o IP del servidor (ej. "10.0.0.5" o "mibase.local")
puertoEl puerto TCP (ej. 3306 MySQL, 443 HTTPS, 1433 SQL Server…)
nombreNoUna etiqueta para reconocerlo en la respuesta. Si no la ponés, usa "host:puerto"
tipoNo"tcp" (default) o "mysql" — ver abajo
Sobre tipo:
"tcp" → solo prueba abrir la conexión al puerto. Sirve para cualquier servicio (una web, otra base, un servidor de correo, lo que sea).
"mysql" → además de conectar, lee el saludo inicial que manda MySQL/MariaDB. Eso confirma que el motor está realmente vivo (no solo "el puerto abierto") y de yapa te devuelve su versión. Todo sin usuario ni contraseña.
• Si no ponés tipo y el puerto es 3306, asume "mysql" solo.

Ejemplos de cada combinación

A) Solo ARCA, homologación — el caso típico

GET
GET /api/afip/ping?produccion=false

B) Solo ARCA, producción

GET
GET /api/afip/ping?produccion=true

C) ARCA + tu MySQL — las dos cosas de una

POST /api/afip/ping
{
  "destinos": [
    { "nombre": "MySQL caja", "host": "10.0.0.5", "puerto": 3306, "tipo": "mysql" }
  ]
}

D) Solo tu MySQL, sin ARCA

POST /api/afip/ping
{
  "incluirAfip": false,
  "destinos": [
    { "nombre": "MySQL caja", "host": "10.0.0.5", "puerto": 3306 }
  ]
}

Acá omití tipo: como el puerto es 3306, lo toma como mysql igual.

E) Varios servidores tuyos a la vez

POST /api/afip/ping
{
  "incluirAfip": false,
  "destinos": [
    { "nombre": "MySQL",            "host": "10.0.0.5",     "puerto": 3306, "tipo": "mysql" },
    { "nombre": "Mi web",           "host": "miapp.com",    "puerto": 443,  "tipo": "tcp" },
    { "nombre": "Impresora fiscal", "host": "192.168.1.50", "puerto": 9100 }
  ]
}

La respuesta, campo por campo

respuesta · ejemplo
{
  "ok": true,
  "data": {
    "fecha": "2026-07-23T10:15:03",
    "produccion": false,
    "afipAccesible": true,
    "objetivos": [
      {
        "nombre": "WSAA", "grupo": "afip",
        "host": "wsaahomo.afip.gov.ar", "puerto": 443, "tipo": "tcp",
        "accesible": true, "latenciaMs": 84, "servidor": null, "error": null,
        "fechaChequeo": "2026-07-23T10:14:51", "edadSegundos": 12
      },
      {
        "nombre": "MySQL caja", "grupo": "custom",
        "host": "10.0.0.5", "puerto": 3306, "tipo": "mysql",
        "accesible": true, "latenciaMs": 3, "servidor": "MySQL 8.0.36", "error": null,
        "fechaChequeo": "2026-07-23T10:14:51", "edadSegundos": 12
      }
    ]
  }
}

A nivel general

CampoQué te dice
okLa regla de siempre: true = la consulta salió bien. Si es false, mirá data.error.
fechaEl momento en que se armó esta respuesta.
produccionTe recuerda contra qué ambiente se midió.
afipAccesibleEl resumen clave: true solo si WSAA y WSFE están accesibles. Es tu semáforo directo para "¿puedo facturar?".
objetivosLa lista con el detalle de cada servidor.

De cada objetivo

CampoQué te dice
nombreLa etiqueta (la que pusiste, o "WSAA"/"WSFE" para los de ARCA).
grupo"afip" (servidor de ARCA, fijo) o "custom" (uno tuyo).
host / puertoA qué apuntó exactamente.
tipo"tcp" o "mysql".
accesibletrue/false: lo más importante. ¿Se pudo conectar?
latenciaMsCuánto tardó, en milisegundos. Es null si no se pudo conectar.
servidorInfo extra del servidor (ej. la versión de MySQL). null si no aplica.
errorSi accesible es false, acá está el motivo (ej. "Connection refused", "Timeout tras 3000 ms"). null si anduvo.
fechaChequeoCuándo se midió realmente (no cuándo preguntaste).
edadSegundosQué tan viejo es el dato. Como viene de cache, te dice hace cuántos segundos se chequeó. Normalmente 0-30 s.
El par fechaChequeo + edadSegundos existe justamente porque la respuesta sale de cache: te deja saber si el dato es fresco. Si vieras un edadSegundos muy alto (minutos), sería señal de que el chequeo de fondo se frenó.

Cuando algo está mal en el request

Si mandás un destino incompleto o inválido, la API te lo dice con ok:false y un status HTTP:

StatusMotivo
400Falta el host de un destino.
400Puerto fuera de rango (no entre 1 y 65535).
403Un host no permitido por la allowlist. Hoy está abierta en *, así que no salta; es un candado para el día que quieras restringir qué puede chequear la API.

Cómo lo usás en la práctica

En tu programa, típicamente:

  1. Antes de una tanda de facturación, llamás a /ping.
  2. Mirás afipAccesible: si es true, seguís con login/emitir. Si es false, mostrás "sin conexión con ARCA" y reintentás.
  3. Si además dependés de tu propia base para facturar, la sumás en destinos y chequeás su accesible en la misma llamada — así, en un solo request, sabés si todo el circuito (ARCA + tu base) está listo.
En una frase: /ping es el chequeo rápido y barato que hacés antes de operar, para no lanzar facturación a ciegas cuando no hay línea.

Seguir

Referencia técnica de /ping Todos los endpoints › Guía de integración ›