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.
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.
GET /api/v1/apps, guarda el JSON y pinta las aplicaciones.Base URL: https://apkholo.duckdns.org. La versión actual es v1; integra siempre rutas versionadas.
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:
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.
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.
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.
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.
| Pregunta | Lite | Full |
|---|---|---|
| ¿Ve apps subidas sin cuenta de desarrollador? | Sí | Sí |
| ¿Ve apps de cuentas de desarrollador? | No | Sí |
| ¿Puede abrir sus fichas y descargar sus APK? | Solo las apps Lite | Todo lo visible en Full |
| ¿La tienda elige el modo en el código? | No; viene fijado en la clave | No; 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.
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
| Petición | Uso | Caché |
|---|---|---|
GET /api/v1 | Descubrimiento: modo asignado, documentación y rutas. | 60 s |
GET /api/v1/apps | Catá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}/icon | Icono cuando la aplicación dispone de él. | 1 día |
GET /api/v1/apps/{id}/download | APK original; responde como adjunto de descarga. | No almacenar |
GET /api/v1/apps/{id}/obb/{filename} | Archivo OBB asociado, si existe. | No almacenar |
| Parámetro | Tipo | Regla |
|---|---|---|
q | texto | Busca por nombre, package, desarrollador, archivo o versión; máximo 120 caracteres. |
android | entero | Filtra por versión principal de Android (1 a 16), usando minSdk; el total de paginación refleja el filtro. |
page | entero | Empieza en 1; máximo 10.000. Por defecto, 1. |
limit | entero | De 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"
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ón | Respuesta |
|---|---|
GET /api/public/developers?limit=100 | Lista 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}/apps | Lista 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"}]
GET /api/search no requiere clave y devuelve un array JSON paginado. Acepta q, android, page y limit. La cabecera X-Total-Count indica el número total de resultados que coinciden con esos filtros, antes de aplicar la página; puede usarse para mostrar el total sin descargar todas las páginas.
curl -i "https://apkholo.duckdns.org/api/search?q=&android=2&page=1&limit=30"
# X-Total-Count: 123
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.| Estado | Cuándo ocurre | Qué hacer |
|---|---|---|
401 | Falta la clave, es inválida, caducó o fue revocada. | Comprueba la cabecera y solicita otra si corresponde. |
404 | Ruta, app, icono, APK u OBB no existe o no es visible para tu modo. | No reintentes indefinidamente; actualiza el catálogo. |
429 | Se superó el límite de 120 peticiones por minuto por clave e IP. | Espera Retry-After y aplica espera progresiva. |
5xx | Error 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.
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(); }
}
| Parte | Explicación sencilla |
|---|---|
HOLO | Es la dirección base del servidor de Holo. Se reutiliza para no escribirla completa en cada llamada. |
apiKey | Es 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. |
HttpURLConnection | Abre una conexión HTTP desde Android. GET significa que solo está leyendo información. |
X-Holo-API-Key | Identifica 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. |
InputStream | Lee 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. |
apps para mostrar name, iconUrl, versionName y description.browserDownloadUrl; para descargar dentro de la app, pide downloadUrl con la cabecera X-Holo-API-Key.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.
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