Servicio REST en PHP que consulta datos de un RUC paraguayo (principalmente razón social). Desplegado en https://api.avatar.com.py/ruc.
La respuesta siempre incluye un campo fuente indicando de dónde salió el dato:
Valor de fuente | Origen | Estado |
|---|---|---|
dnit | Servicio web oficial de DNIT (ex-SET), "Consulta RUC" | Implementado, pendiente apiKey (a obtener vía Marangatú) |
turuc.com.py | Tercero no oficial (espeja datos de RUC), sin auth | Activo — se usa como fallback automático mientras no haya apiKey de DNIT |
El fallback no tiene SLA ni términos de uso documentados. No usar para nada con implicancia legal o contable hasta migrar a la fuente oficial.
Todas las requests requieren el header:
Authorization: Bearer <TOKEN>
Token del servicio:
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Está definido en config/config.php (clave service_token) o vía
variable de entorno RUC_SERVICE_TOKEN (tiene prioridad sobre el valor del archivo).
Sin el header correcto, la API responde 401.
| Método | Ruta | Descripción |
|---|---|---|
| GET | /ruc/{ruc}-{dv} | Datos del contribuyente (RUC + dígito verificador pegados con guion). |
| GET | /ruc/{ruc}?dv={dv} | Igual, con el DV como query param separado. |
{
"ok": true,
"fuente": "dnit" | "turuc.com.py",
"ruc": "80012345-6",
"encontrado": true,
"razonSocial": "NOMBRE DE LA EMPRESA",
"estado": "ACTIVO",
"detalle": { ... datos crudos específicos de la fuente ... }
}
Si el RUC no existe en la fuente consultada: "encontrado": false,
"razonSocial": null. Si fallan ambas fuentes: HTTP 502 con
{"ok": false, "error": "upstream", "errores": {"dnit": "...", "turuc.com.py": "..."}}.
Si el RUC existe pero el DV no coincide: HTTP 400 con
{"ok": false, "error": "dv_incorrecto", "fuente": "...", "ruc": "...", "dvProvisto": "...", "dvReal": "..."}
— usá dvReal para reintentar con el DV correcto.
Consulta con RUC y DV pegados:
curl -s -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://api.avatar.com.py/ruc/80012345-6"
Consulta con DV separado:
curl -s -H "Authorization: Bearer xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \ "https://api.avatar.com.py/ruc/80012345?dv=6"
| Ítem | Valor |
|---|---|
| URL base de RUC | https://api.avatar.com.py/ruc (HTTP redirige a HTTPS) |
| Directorio en el server | /var/www/ruc-paraguay-api (dueño www-data) |
| DocumentRoot | /var/www/ruc-paraguay-api/public |
| Vhost Apache | compartido con el resto del dominio (Alias /ruc en api-avatar.conf + api-avatar-le-ssl.conf) — ver /root/api-avatar-hub/CLAUDE.md |
| Directorio fuente | /root/ruc-paraguay-api — editar acá y sincronizar al deploy |
rsync -a --exclude '.git' --exclude '.claude' /root/ruc-paraguay-api/ /var/www/ruc-paraguay-api/ sudo chown -R www-data:www-data /var/www/ruc-paraguay-api sudo chmod 600 /var/www/ruc-paraguay-api/config/config.php sudo chmod 640 /var/www/ruc-paraguay-api/docs/ruc.html
ruc y dv por separado; esta app acepta ambos formatos en la URL y los separa antes de llamar.turuc.com.py devuelve HTTP 400 (no 200) cuando el RUC no existe — se trata como respuesta válida de "no encontrado", no como error.ap001 (apikey inválido/inactivo/límite superado), ap010/ap011/ap012 (parámetro faltante).apiKey oficial de DNIT vía suscripción en Marangatú (https://marangatu.set.gov.py/eset → "Comunicar Uso de Consultas Públicas"). Requiere acceso con el RUC de la empresa, no uno personal. No bloquea el uso del servicio — mientras tanto responde vía el fallback./ruc) coincide con la keyword de ruteo interna (ruc): pegarle a /ruc/ (raíz, sin RUC) da 400 en vez de la página de info del servicio. No afecta al uso real.400 dv_incorrecto con el dvReal correcto en la respuesta.