Inicio rápido
Tu cuenta hoy; el contrato pago después.
La clave free de tu cuenta ya funciona para integraciones de servidor, la consulta web sigue disponible y la API comercial paga espera la autorización escrita de la fuente.
API free · clave de tu cuenta
Seleccioná el espacio personal y abrí Cuenta → Mis claves API (/panel/claves-personales). Abrir la sección solo consulta el estado. Ingresá un nombre único por aplicación y usá Crear clave para revelar su secreto una sola vez. Las aplicaciones, la web y los lotes personales comparten las mismas 100 consultas diarias de Free100, con reinicio a medianoche de Paraguay.
curl --request GET \
--include \
--url https://app.controlaria.online/api/v1/ruc/80121686 \
--header 'X-API-Key: od_test_TU_CLAVE_FREE' \
--header 'Accept: application/json'{
"data": {
"ruc": "80121686",
"fullRuc": "80121686-9",
"dv": "9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"equivalenceRaw": "",
"stateRaw": "ACTIVO"
},
"requestId": "req_1f0c2a9d4b7e4c8f9a0b1d2e",
"meta": {
"environment": "test",
"quota": { "limit": 100, "used": 1, "remaining": 99, "day": "2026-10-03", "resetAfter": 54000 },
"accounting": { "alreadyConsulted": false, "charged": true, "cacheEnabled": true },
"provenance": {
"source": "dnit_official_snapshot",
"sourcePage": "https://www.dnit.gov.py/en/web/portal-institucional/listado-de-ruc-con-sus-equivalencias",
"publicationDate": "2026-10-01",
"publishedText": "Publicación oficial de ejemplo",
"importedAt": "2026-10-02T00:00:00Z",
"snapshotHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
}
}await fetch("/api/account/app-api-keys", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ action: "rotate", keyId: "<key-id-from-metadata>" }),
});Gestión por aplicación: /api/account/app-api-keys (sesión y contexto personal). La rotación y revocación afectan solo a la aplicación seleccionada.
Web · sesión de cuenta
Pegá este código en la consola del navegador con tu sesión iniciada.
await fetch("/api/account/ruc", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ruc: "80121686-9" }),
});{
"data": {
"ruc": "80121686",
"fullRuc": "80121686-9",
"dv": "9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"equivalenceRaw": "",
"stateRaw": "ACTIVO",
"sourcePartition": 0
},
"provenance": {
"source": "dnit_official_snapshot",
"sourcePage": "https://www.dnit.gov.py/en/web/portal-institucional/listado-de-ruc-con-sus-equivalencias",
"publicationDate": "2026-10-01",
"publishedText": "Publicación oficial de ejemplo",
"importedAt": "2026-10-02T00:00:00Z",
"snapshotHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
},
"fullRuc": "80121686-9",
"alreadyConsulted": false,
"charged": true,
"cacheEnabled": true,
"allowance": {
"visitorUsed": 1,
"visitorLimit": 100,
"remaining": 99,
"day": "2026-10-03",
"resetTimeZone": "America/Asuncion",
"resetAtLocal": "00:00",
"blocked": false
}
}Comercial · X-API-Key
Contrato congelado. Hoy el endpoint responde 503 COMMERCIAL_API_DISABLED para claves de organización; no hay claves comerciales emitidas.
Autenticación
- Formato: od_<test|live>_<8 hex>_<32 caracteres>.
- Entornos test y live separados; alcance ruc:read.
- Solo se guarda el hash y el texto plano se revela una vez; la emisión sigue pendiente de autorización.
X-API-Key: od_test_0123abcd_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXcurl --request GET \
--url https://app.controlaria.online/api/v1/ruc/80121686-9 \
--header 'X-API-Key: od_test_TU_CLAVE' \
--header 'Accept: application/json'{
"data": {
"ruc": "80121686",
"fullRuc": "80121686-9",
"dv": "9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"equivalenceRaw": "",
"stateRaw": "ACTIVO"
},
"requestId": "req_1f0c2a9d4b7e4c8f9a0b1d2e",
"meta": {
"environment": "test",
"quota": { "limit": 300, "used": 1, "remaining": 299, "day": "2026-10-03", "resetAfter": 54000 },
"accounting": { "alreadyConsulted": false, "charged": true },
"provenance": {
"source": "dnit_official_snapshot",
"sourcePage": "https://www.dnit.gov.py/en/web/portal-institucional/listado-de-ruc-con-sus-equivalencias",
"publicationDate": "2026-10-01",
"publishedText": "Publicación oficial de ejemplo",
"importedAt": "2026-10-02T00:00:00Z",
"snapshotHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
}
}Qué está disponible y qué no
| Acceso | Ruta | Estado actual |
|---|---|---|
| Prueba pública | /api/demo/public-ruc | Disponible, anónima y limitada. |
| Cuenta Free100 | /api/account/ruc | Disponible desde el alta de la cuenta personal; 100 consultas web por día. La verificación de correo se recomienda, pero no bloquea el cupo. |
| API free de la cuenta | /api/v1/ruc/{ruc} | Disponible con la clave free de la cuenta; 100 consultas por día compartidas con Free100. |
| API comercial | /api/v1/ruc/{ruc} | Deshabilitada por defecto hasta la autorización de la fuente. Sin acceso pago. |
| Contrato | /api/v1/openapi.json | Documento OpenAPI publicado, versión 1.2.0. |
Límite comercial: la clave free es personal y no habilita planes, cobros ni redistribución. Las claves comerciales no se emiten y su endpoint sigue deshabilitado hasta que exista autorización escrita; los ejemplos comerciales describen el contrato congelado, no un servicio activo.
{
"error": {
"code": "COMMERCIAL_API_DISABLED",
"message": "The commercial API is not enabled for this deployment."
},
"meta": { "environment": "test", "accounting": { "alreadyConsulted": false, "charged": false } }
}Consulta web disponible
Usa la sesión del navegador y el mismo origen; no lleva X-API-Key. Free100 cobra resultados completos y 404 válidos nuevos. Con la caché habilitada, el mismo RUC, cuenta y día Paraguay no vuelve a descontar, incluso entre web y API: alreadyConsulted=true y charged=false. cacheEnabled=false indica que aún funciona sin deduplicación; su activación requiere una migración autorizada. DV inválido y errores propios no cobran.
Demo pública
10 consultas/día por visitante, 10/día por IP y 10/día compartidas; 20/mes compartidas. Reset a medianoche de Paraguay.
Free100
100 consultas/día por cuenta personal desde el alta y 30 consultas por IP por minuto. Verificar el correo se recomienda para recuperación y avisos, pero no bloquea el cupo. La búsqueda por nombre está limitada a 10 resultados por página.
await fetch("/api/account/ruc", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ ruc: "80121686-9" }),
});{
"data": {
"ruc": "80121686",
"fullRuc": "80121686-9",
"dv": "9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"equivalenceRaw": "",
"stateRaw": "ACTIVO",
"sourcePartition": 0
},
"provenance": {
"source": "dnit_official_snapshot",
"sourcePage": "https://www.dnit.gov.py/en/web/portal-institucional/listado-de-ruc-con-sus-equivalencias",
"publicationDate": "2026-10-01",
"publishedText": "Publicación oficial de ejemplo",
"importedAt": "2026-10-02T00:00:00Z",
"snapshotHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
},
"fullRuc": "80121686-9",
"alreadyConsulted": false,
"charged": true,
"cacheEnabled": true,
"allowance": {
"visitorUsed": 1,
"visitorLimit": 100,
"remaining": 99,
"day": "2026-10-03",
"resetTimeZone": "America/Asuncion",
"resetAtLocal": "00:00",
"blocked": false
}
}{
"fullRuc": "80121686-9",
"canonicalPath": "/ruc/80121686-9",
"data": {
"fullRuc": "80121686-9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"stateRaw": "ACTIVO"
},
"allowance": {
"blocked": false,
"visitorUsed": 1,
"visitorLimit": 10,
"remaining": 9,
"dailyUsed": 1,
"dailyLimit": 10,
"monthlyUsed": 1,
"monthlyLimit": 20,
"day": "2026-10-03",
"month": "2026-10",
"resetTimeZone": "America/Asuncion",
"resetAtLocal": "00:00",
"accounting": "Reserved demo lookups, including not-found and unavailable data. Independent demo allowance."
}
}Con GET en las rutas web de cuenta y demo consultás el cupo sin consumirlo. Desde tu servidor, usá GET /api/v1/ruc/{ruc} con X-API-Key y una clave personal free: esta ruta consulta el RUC y puede consumir cupo; no requiere activar la API comercial paga. La consulta web depende de la sesión del navegador.
API comercial v1 (deshabilitada)
El endpoint acepta un RUC completo o su base registrada y responde con datos publicados, cuota y procedencia. La autorización legal de redistribución es la dependencia de lanzamiento: hasta entonces no se habilita ni se emiten claves.
curl --request GET \
--url https://app.controlaria.online/api/v1/ruc/80121686-9 \
--header 'X-API-Key: od_test_TU_CLAVE' \
--header 'Accept: application/json'{
"data": {
"ruc": "80121686",
"fullRuc": "80121686-9",
"dv": "9",
"nameOfficial": "EMPRESA DE EJEMPLO S.A.",
"equivalenceRaw": "",
"stateRaw": "ACTIVO"
},
"requestId": "req_1f0c2a9d4b7e4c8f9a0b1d2e",
"meta": {
"environment": "test",
"quota": { "limit": 300, "used": 1, "remaining": 299, "day": "2026-10-03", "resetAfter": 54000 },
"accounting": { "alreadyConsulted": false, "charged": true },
"provenance": {
"source": "dnit_official_snapshot",
"sourcePage": "https://www.dnit.gov.py/en/web/portal-institucional/listado-de-ruc-con-sus-equivalencias",
"publicationDate": "2026-10-01",
"publishedText": "Publicación oficial de ejemplo",
"importedAt": "2026-10-02T00:00:00Z",
"snapshotHash": "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef"
}
}
}- Cobra una vez cada intento válido: encontrado, sin registro o base no disponible.
- No reintenta automáticamente. La demo mantiene su cobro por intento; una reconsulta personal en caché no descuenta de nuevo.
- No uses claves comerciales desde el navegador; son de servidor.
Claves personales y comerciales
La clave va en el encabezado X-API-Key desde tu servidor. Las claves personales free son independientes por aplicación y comparten el cupo de tu cuenta. Tienen alcance ruc:read, vencimiento obligatorio, rotación con solapamiento y revocación inmediata. Solo se guarda el hash: el texto plano se muestra una única vez al crearla o rotarla. Las claves comerciales pertenecen a una empresa y entorno; su uso sigue deshabilitado.
Hay dos niveles: la clave free de la cuenta se emite y se revela una vez desde la propia cuenta, sin verificación de correo; las claves comerciales las gestiona un propietario o administrador de la empresa activa.
Clave free
Uso personal, 100/día compartido con Free100, sin planes ni cobros.
Entornos
test y live son independientes: una clave solo autentica en su entorno.
Rotación y revocación
La rotación mantiene la clave anterior durante un solapamiento acordado y deja auditoría durable de cada evento.
La gestión por empresa (crear, rotar, revocar, definir cupo) requiere una sesión verificada con rol propietario o administrador en la empresa activa.
Contrato OpenAPI congelado
El documento OpenAPI 3.1 describe las rutas, las respuestas, los encabezados de cuota y los códigos estables. Cambiar un campo o un código publicado es una decisión de versión, no un refactor.
curl --request GET \
--url https://app.controlaria.online/api/v1/openapi.json \
--header 'Accept: application/json'{
"openapi": "3.1.0",
"info": { "title": "OwnData Commercial RUC API", "version": "1.2.0" },
"paths": {
"/api/v1/ruc/{ruc}": {
"get": { "operationId": "getRucV1", "security": [{ "ApiKey": [] }] }
}
},
"components": {
"securitySchemes": {
"ApiKey": { "type": "apiKey", "in": "header", "name": "X-API-Key" }
}
},
"x-owndata-legal-gate": { "status": "disabled-by-default" }
}Versión publicada: 1.2.0. El interruptor de habilitación y el límite legal están documentados dentro del propio contrato.
Cuotas y límites
La API free comparte 100 consultas diarias por cuenta entre claves, web y lotes personales. La API comercial, aún deshabilitada, define 300, 1.000 o un cupo a medida por empresa. El día se reinicia a medianoche en America/Asuncion. Solo un resultado completo o 404 válido nuevo cobra una unidad; DV inválido y errores propios o del dataset no cobran. Con cacheEnabled=true, las reconsultas personales del mismo RUC y día no cobran, incluso con el cupo agotado; cacheEnabled=false no deduplica. meta.accounting informa charged y alreadyConsulted.
| Plan | Consultas por día | Alcance |
|---|---|---|
| starter300 | 300 | Cupo diario por empresa. |
| growth1000 | 1.000 | Cupo diario por empresa. |
| custom | A medida | Valor acordado, por ejemplo 3.000. No implica precio ni SLA. |
Encabezados de cuota
Cada respuesta cobrada incluye RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset; un 429 agrega Retry-After con los segundos hasta el reinicio.
Contadores y reconciliación
Cada reserva queda en un registro durable y se puede reconciliar contra el contador sin inventar ni borrar consumos.
La consulta web no se cobra con estas cuotas: Free100 usa 100 por día y la demo tiene su propio límite compartido.
La clave free de la cuenta tampoco usa estas cuotas: comparte el cupo Free100 de 100 consultas por día. Sus respuestas incluyen RateLimit-Limit, RateLimit-Remaining y RateLimit-Reset, y un 429 con Retry-After cuando se agota.
Errores estables de la API free y comercial
El código es el contrato; el mensaje es informativo. Los rechazos de autenticación, formato, alcance, plan y cuota no se cobran. Un 404 válido puede ser un resultado nuevo o una reconsulta en caché: revisá meta.accounting.charged. Un 429 DAILY_QUOTA_REACHED incluye Retry-After en segundos; esperá el reinicio y no reintentes automáticamente. Los ejemplos hacen una sola solicitud y no prueban una integración externa productiva.
400
INVALID_RUC_FORMATINVALID_RUC_DVNo cobra
401
API_KEY_REQUIREDAPI_KEY_INVALIDAPI_KEY_REVOKEDAPI_KEY_EXPIREDAPI_KEY_ENVIRONMENT_MISMATCHNo cobra
403
INSUFFICIENT_SCOPEPLAN_REQUIREDNo cobra
404
REGISTERED_RUC_NOT_FOUNDCobra 1 consulta nueva; reconsulta personal en caché no cobra
405
METHOD_NOT_ALLOWEDNo cobra
409
ACCOUNT_PERIOD_CHANGEDNo cobra; actualizar período
429
DAILY_QUOTA_REACHEDNo cobra de nuevo
503
FREE_API_DISABLEDCOMMERCIAL_API_DISABLEDCOMMERCIAL_API_UNAVAILABLENo cobra
503
DNIT_DATA_UNAVAILABLENo cobra
{
"error": {
"code": "REGISTERED_RUC_NOT_FOUND",
"message": "No record exists for that RUC in the active dataset."
},
"meta": {
"environment": "test",
"quota": { "limit": 300, "used": 2, "remaining": 298, "day": "2026-10-03", "resetAfter": 53999 },
"accounting": { "alreadyConsulted": false, "charged": true }
}
}Errores de la consulta web
401
AUTH_REQUIREDNo hay sesión: no reserva ni cobra.
403
SAME_ORIGIN_REQUIREDOrigen ajeno: no reserva ni cobra. La verificación de correo se recomienda, pero no bloquea Free100.
400
INVALID_RUC_DVDV inválido: no reserva ni consulta el dataset, tanto en cuenta como en demo.
404
REGISTERED_RUC_NOT_FOUNDSin registro: cuenta 1 consulta nueva; reconsulta personal en caché no cobra.
409
SEARCH_UNAVAILABLEBúsqueda por nombre sin índice: no reserva ni cobra.
409
ACCOUNT_PERIOD_CHANGEDEl período del cupo cambió: actualice antes de volver a consultar. No se reservó ninguna consulta.
429
ACCOUNT_ALLOWANCE_REACHED · RATE_LIMITEDCupo diario o límite por minuto agotado: no cobra.
429
DEMO_ALLOWANCE_REACHEDCupo de la demo agotado: no vuelve a cobrar.
503
ACCOUNT_LOOKUP_UNAVAILABLE · DNIT_DATA_UNAVAILABLE · PUBLIC_DEMO_DISABLEDCuenta: los fallos propios o de base no cobran. Demo anónima: conserva su contrato de intentos reservados.
Procedencia y actualización
La respuesta conserva la publicación oficial que la originó. La hora de respuesta no es la fecha de publicación: usá provenance para saber qué copia respondió.
- source
- dnit_official_snapshot
- Origen oficial de la base importada.
- sourcePage
- https://www.dnit.gov.py/…
- Página oficial de la publicación usada.
- publicationDate
- 2026-10-01
- Fecha de publicación DNIT (YYYY-MM-DD).
- publishedText
- Publicación oficial
- Etiqueta oficial conservada textualmente.
- importedAt
- 2026-10-02T00:00:00Z
- Momento de importación de la copia OwnData.
- snapshotHash
- 0123…def
- Hash de la base importada; permite verificar la misma copia.
No se promete intervalo de actualización, cobertura, resultado de posicionamiento ni SLA. Esas afirmaciones requieren autorización escrita y comportamiento medido.
Nombres normalizados
La v1 solo expone los campos publicados: nameOfficial y stateRaw. Los campos normalizados de personas todavía no están disponibles y no deben inferirse del ejemplo.
Cuando se agreguen, los nombres compuestos, las partículas, la falta de coma, los bloques vacíos o los datos mal formados deberán producir un estado de interpretación y una señal de revisión en lugar de una conjetura silenciosa. La confianza de interpretación nunca demuestra identidad legal.
JSON y exportaciones futuras
La respuesta activa conserva solo el valor oficial. Una revisión futura podrá agregar campos revisados de nombre natural y columnas de exportación sin crear una versión nueva solo por formato.
Secuencia de integración
- 1
Separá las credenciales: la web usa sesión; tu servidor usa X-API-Key con una clave personal free. Las claves comerciales por empresa siguen deshabilitadas.
- 2
Validá el RUC completo con su dígito verificador antes de enviarlo.
- 3
Esperá el cupo: respetá Retry-After y no reintentes automáticamente. Solo los resultados completos y 404 válidos nuevos cobran; la caché personal evita un segundo descuento.
- 4
Guardá la procedencia junto al dato: fuente, fecha de publicación, texto publicado y hash de la base.
- 5
No derives identidad ni nombres normalizados: en v1 solo existen los campos publicados.
Campos de la respuesta v1
Los campos del contrato comercial, sin endpoints ni nombres inventados.
- ruc
- string
- Base registrada sin el dígito verificador.
- fullRuc
- string
- Par canónico de base y dígito verificador.
- dv
- string
- Dígito verificador.
- nameOfficial
- string
- Nombre o razón social oficial conservado exactamente como se publicó.
- equivalenceRaw
- string
- Bloque de equivalencia de la fuente, conservado textualmente.
- stateRaw
- string
- Estado publicado conservado textualmente; sin afirmar activo o inactivo por inferencia.
- meta.quota
- object
- Límite, usado, disponible, día de Paraguay y segundos hasta el reinicio.
- meta.provenance
- object
- Fuente, fecha de publicación, texto publicado, fecha de importación y hash de la base.
- requestId
- string
- Identificador estable para soporte y reconciliación.