HOLO API · V1.0.0

Conecta tu tienda a Holo

Una API HTTP con JSON para leer el catálogo público de Holo, mostrar fichas y descargar APK, iconos y OBB desde tu propia tienda Android.

Acceso por clave para API v1. Las rutas versionadas requieren una clave activa Lite o Full. El directorio público de Developers documentado más abajo no requiere clave y solo expone cuentas públicas con APK disponibles.

Empieza en cinco pasos

  1. 1. Define la integración. Indica el nombre de tu tienda, una URL o contacto y si quieres Lite o Full.
  2. 2. Contacta con el desarrollador de Holo. Solo el desarrollador de Holo puede aprobar la integración y generar una clave desde el panel privado; no existe un registro automático ni una clave pública.
  3. 3. Guarda la clave que recibas. La clave completa aparece una sola vez. No la metas en una APK pública ni en JavaScript del navegador: se puede extraer.
  4. 4. Consulta el catálogo. Llama a GET /api/v1/apps, guarda el JSON y pinta las aplicaciones.
  5. 5. Descarga con la misma clave. APK, iconos y OBB también requieren la cabecera.

Base URL: https://apkholo.duckdns.org. La versión actual es v1; integra siempre rutas versionadas.

Cómo pedir una clave API

Para conectarte a Holo tienes que ponerte en contacto con el desarrollador de Holo. Él revisa el uso, crea una clave individual para tu tienda y decide si corresponde Lite o Full. Sin esa clave no podrás leer el catálogo, abrir fichas ni descargar archivos.

En tu mensaje incluye estos datos:

Texto que puedes enviar

Hola, quiero integrar Holo en [nombre de mi tienda].
Solicito acceso [Lite / Full] porque [motivo].
La integración será [Android / web / servidor] y mi contacto técnico es [contacto].
La URL de mi proyecto es [URL, si existe].

Después de aprobarla: el desarrollador te entregará una clave que empieza por holo_. Guárdala en un lugar seguro en ese momento; Holo no vuelve a mostrar la clave completa. Si se filtra, solicita otra y pide revocar la anterior.

Lite y Full: la diferencia importante

El modo pertenece a tu clave, no se envía como parámetro. Dos tiendas pueden consultar la misma ruta y recibir catálogos distintos.

Lite

Incluye: aplicaciones sin una cuenta de desarrollador asociada en Holo.

Excluye: cualquier aplicación vinculada a una cuenta de desarrollador, aunque sea pública.

Úsalo para: catálogo comunitario, integración limitada o primera prueba.

Full

Incluye: todo el catálogo disponible para la API: aplicaciones sin cuenta asociada y aplicaciones publicadas por desarrolladores.

Excluye: nada adicional; usa las mismas rutas, formato y límite que Lite.

Úsalo para: una tienda que necesita el catálogo completo de Holo.

PreguntaLiteFull
¿Ve apps subidas sin cuenta de desarrollador?SíSí
¿Ve apps de cuentas de desarrollador?NoSí
¿Puede abrir sus fichas y descargar sus APK?Solo las apps LiteTodo lo visible en Full
¿La tienda elige el modo en el código?No; viene fijado en la claveNo; viene fijado en la clave

Ejemplo: una app subida por @estudioejemplo se ve con Full, pero no con Lite. Una app subida sin cuenta de desarrollador asociada se ve en ambos. El modo se aplica también al abrir una ficha o descargar un archivo.

Autenticación y seguridad

Envía una de estas cabeceras en todas las llamadas. La primera es la recomendada.

GET /api/v1/apps?limit=20&page=1 HTTP/1.1
Host: apkholo.duckdns.org
X-Holo-API-Key: holo_TU_CLAVE
Authorization: Bearer holo_TU_CLAVE

Rutas disponibles

PeticiónUsoCaché
GET /api/v1Descubrimiento: modo asignado, documentación y rutas.60 s
GET /api/v1/appsCatálogo paginado. Acepta q, android, page y limit.60 s
GET /api/v1/apps/{id}Ficha completa: datos, metadatos, changelog y OBB disponibles.60 s
GET /api/v1/apps/{id}/iconIcono cuando la aplicación dispone de él.1 día
GET /api/v1/apps/{id}/downloadAPK original; responde como adjunto de descarga.No almacenar
GET /api/v1/apps/{id}/obb/{filename}Archivo OBB asociado, si existe.No almacenar

Parámetros de catálogo

ParámetroTipoRegla
qtextoBusca por nombre, package, desarrollador, archivo o versión; máximo 120 caracteres.
androidenteroFiltra por versión principal de Android (1 a 16), usando minSdk; el total de paginación refleja el filtro.
pageenteroEmpieza en 1; máximo 10.000. Por defecto, 1.
limitenteroDe 1 a 100; por defecto, 20.

androidApi filtra por nivel API exacto (1–37): solo devuelve apps cuyo minSdk sea menor o igual al API indicado. Ejemplo: androidApi=7 representa Android 2.1. El total y los enlaces de paginación mantienen este filtro.

curl -H "X-Holo-API-Key: holo_TU_CLAVE" \
  "https://apkholo.duckdns.org/api/v1/apps?androidApi=7&page=1&limit=20"
curl -H "X-Holo-API-Key: holo_TU_CLAVE" \
  "https://apkholo.duckdns.org/api/v1/apps?q=editor&page=1&limit=20"

Directorio público de Developers

Estas dos rutas están pensadas para clientes ligeros como Market 2. No requieren clave API. Solo aparecen cuentas activas cuyo identificador empieza por @. appCount indica cuántas aplicaciones públicas tienen su APK disponible. La respuesta no incluye credenciales ni datos privados de la cuenta.

PeticiónRespuesta
GET /api/public/developers?limit=100Lista cuentas públicas: userId, companyName, description, appCount y avatarUrl. El límite admite valores de 1 a 100 y por defecto es 100.
GET /api/public/developers/{userId}/appsLista las aplicaciones públicas disponibles de esa cuenta, con nombre, package, versión, icono, ficha y URL de descarga.

Codifica el identificador como segmento de URL. Por ejemplo, @ejemplo se solicita como %40ejemplo. La ruta de apps devuelve un array JSON; un identificador inválido o una cuenta que ya no está activa responde 404. Cada app indica verified como booleano explícito, además de vtStatus.

curl "https://apkholo.duckdns.org/api/public/developers?limit=100"
curl "https://apkholo.duckdns.org/api/public/developers/%40ejemplo/apps"
[{"userId":"@ejemplo","companyName":"Ejemplo Studio","description":"","appCount":2,"avatarUrl":"/api/public/developers/%40ejemplo/avatar"}]

[{"id":42,"name":"Mi aplicación","packageName":"com.ejemplo.app","versionName":"1.0.0","minAndroid":"Android 7.0","shortDescription":"","downloadCount":120,"vtStatus":"verified","verified":true,"iconUrl":"/api/public/apps/42/icon","url":"/app/42","downloadUrl":"/api/public/files/mi-aplicacion.apk"}]

Contrato de respuesta

Las respuestas JSON incluyen apiVersion y el modo efectivo de la clave. El catálogo usa pagination y links; usa los enlaces para avanzar sin reconstruir URLs.

{
  "apiVersion": "1.0.0", "mode": "full",
  "apps": [{"id":42,"name":"Mi aplicación","packageName":"com.ejemplo.app","versionName":"1.0.0","versionCode":"100","minSdk":"24","targetSdk":"35","minAndroid":"Android 7.0","sizeBytes":12345678,"sha256":"…","description":"Descripción corta","developer":"Ejemplo Studio","developerId":"@ejemplo","source":"developer","verified":true,"verification":{"status":"verified","detections":0,"reportUrl":"…"},"downloadCount":120,"createdAt":"2026-09-24T10:00:00+00:00","iconUrl":"https://…/icon","detailsUrl":"https://…/42","downloadUrl":"https://…/42/download","browserDownloadUrl":"https://…/api/public/files/mi-aplicacion.apk"}],
  "pagination": {"page":1,"limit":20,"total":123,"totalPages":7,"hasPreviousPage":false,"hasNextPage":true},
  "links": {"self":"…","first":"…","previous":null,"next":"…","last":"…"}
}

La ficha individual añade metadata, longDescription, category, license, projectUrl, contact, changelogs y obb. Cada OBB incluye nombre, tamaño, SHA-256 y downloadUrl.

browserDownloadUrl es una URL pública directa del APK para abrir con un navegador y no necesita la cabecera de la API. downloadUrl conserva la ruta autenticada para clientes API.

sourceanonymous si no hay cuenta de desarrollador asociada; developer si la hay. Lite devuelve solo anonymous.
verified y verificationverified es true solo cuando el estado de Holo es verified; es false si está pendiente, en análisis o no verificada. verification incluye estado, detecciones y enlace del informe. No sustituye tu propia política de seguridad.
sha256Huella del archivo. Tras descargar un APK u OBB, verifica que coincide antes de instalarlo o distribuirlo.

Errores, límites y caché

EstadoCuándo ocurreQué hacer
401Falta la clave, es inválida, caducó o fue revocada.Comprueba la cabecera y solicita otra si corresponde.
404Ruta, app, icono, APK u OBB no existe o no es visible para tu modo.No reintentes indefinidamente; actualiza el catálogo.
429Se superó el límite de 120 peticiones por minuto por clave e IP.Espera Retry-After y aplica espera progresiva.
5xxError temporal del servidor.Reintenta con backoff exponencial y conserva la última respuesta válida.
{"apiVersion":"1.0.0","error":{"code":"api_key_required","message":"Necesitas una clave API de Holo válida en X-Holo-API-Key."},"requestId":"a1b2c3…"}

Incluye X-Request-Id al informar un problema. Las respuestas autenticadas llevan X-Holo-API-Version, X-Holo-API-Mode, X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset (segundos restantes de la ventana).

Las respuestas JSON correctas incluyen ETag. Guarda ese valor y manda If-None-Match después: si no cambió, Holo responde 304 Not Modified sin reenviar el JSON.

Ejemplo Android en Java

Ejecuta red fuera del hilo principal. Este ejemplo usa HttpURLConnection. En una app pública, la clave debe vivir en tu backend, no como constante en la APK.

private static final String HOLO = "https://apkholo.duckdns.org";

String cargarCatalogo(String apiKey) throws IOException {
  URL url = new URL(HOLO + "/api/v1/apps?page=1&limit=20");
  HttpURLConnection c = (HttpURLConnection) url.openConnection();
  c.setRequestMethod("GET"); c.setRequestProperty("Accept", "application/json");
  c.setRequestProperty("X-Holo-API-Key", apiKey);
  c.setConnectTimeout(15000); c.setReadTimeout(30000);
  int status = c.getResponseCode();
  if (status == HttpURLConnection.HTTP_NOT_MODIFIED) return null;
  if (status == 429) throw new IOException("Espera " + c.getHeaderField("Retry-After") + " segundos");
  if (status != HttpURLConnection.HTTP_OK) throw new IOException("Holo respondió " + status);
  try (InputStream in = c.getInputStream(); ByteArrayOutputStream out = new ByteArrayOutputStream()) {
    byte[] b = new byte[8192]; for (int n; (n = in.read(b)) != -1;) out.write(b, 0, n);
    return out.toString("UTF-8"); // Analiza con org.json, Gson o Moshi.
  } finally { c.disconnect(); }
}

Qué hace este código, línea por línea

ParteExplicación sencilla
HOLOEs la dirección base del servidor de Holo. Se reutiliza para no escribirla completa en cada llamada.
apiKeyEs la clave entregada por el desarrollador de Holo. Se envía en la cabecera, nunca dentro de la URL.
new URL(.../apps?page=1&limit=20)Pide la primera página del catálogo y un máximo de 20 apps. Cambia page para cargar más resultados.
HttpURLConnectionAbre una conexión HTTP desde Android. GET significa que solo está leyendo información.
X-Holo-API-KeyIdentifica a tu tienda ante Holo y determina automáticamente si recibes Lite o Full.
getResponseCode()Comprueba el resultado antes de leer datos: 200 es correcto, 401 es clave no válida y 429 pide esperar.
InputStreamLee el texto JSON que devuelve Holo. Después puedes usar org.json, Gson o Moshi para convertirlo en objetos Java.
disconnect()Cierra la conexión al terminar, incluso si ocurre un error.

Cómo usar los datos que devuelve

  1. Convierte el texto JSON en un objeto.
  2. Recorre apps para mostrar name, iconUrl, versionName y description.
  3. Para una descarga en el navegador, abre browserDownloadUrl; para descargar dentro de la app, pide downloadUrl con la cabecera X-Holo-API-Key.
  4. Antes de instalar, compara el SHA-256 descargado con el campo sha256 de la ficha.

Permiso necesario: <uses-permission android:name="android.permission.INTERNET" />. browserDownloadUrl abre la descarga pública directamente; downloadUrl requiere la clave y devuelve la APK al cliente API.

Soporte de integración

Al pedir acceso, incluye el nombre de la tienda, el modo deseado, cómo se usará el catálogo y un contacto técnico. Para un fallo, aporta ruta, hora aproximada y X-Request-Id; nunca la clave.

¿Listo para integrar Holo? Ponte en contacto con el desarrollador de Holo para obtener tu clave API.

← Volver a Holo