Referencia de la API
Lectura abierta, escritura con sesión GitHub o token ih_…. Todas las respuestas usan el envelope {success, data?, error?}.
01Base y autenticación
Base: https://indexlyhub.daida.net/api/v1
Auth: Authorization: Bearer <jwt-sesion> (web, tras login GitHub)
Authorization: Bearer ih_<secreto> (token personal, perfil → Tokens) Los tokens tienen scopes: read (defecto) y write (publicar, actualizar, borrar, favoritos, reportes). Crear tokens exige sesión web; el secreto se muestra una sola vez. Si se expone, revócalo en tu perfil.
curl "https://indexlyhub.daida.net/api/v1/packages?q=steam&sort=downloads&pageSize=5"
curl -H "Authorization: Bearer ih_TUSECRETO" \
-H "Content-Type: application/json" \
-d '{"name":"Mi paquete","data":{"items":[{"title":"A","url":"https://…"}]}}' \
https://indexlyhub.daida.net/api/v1/packages 02Playground
Prueba los endpoints de lectura sin salir de aquí. Para los que piden auth, pega tu sesión o token (se queda en tu navegador).
// pulsa Ejecutar… 03Paquetes
/packagesLista paginada. Params: q (máx 200), tag, tags (coma), author (login o id), sort (recent · downloads · name-asc · name-desc · items-desc), page, pageSize (máx 100). Responde data[] + meta{total,page,pageSize,hasMore}.
/packages/{slug}Metadatos + r2Url del fichero.
/packages/{slug}/fileJSON con r2_url. Con ?redirect=1 cuenta la descarga y redirige 302 al CDN.
/packages/{slug}/downloadCuenta una descarga/importación sin descargar el fichero.
/packages/{slug}/rawContenido: r2_url (filas R2, descarga del CDN) o rawData inline (legacy).
/packagesauth writeJSON {name, slug?, description?, tags?, version?, mapping?, data} o FormData. El servidor recalcula checksum/tamaño/items y aplica cuotas (5 MB/archivo, 50 MB y 30 paquetes/usuario, 10 subidas/hora, dedup SHA-256). → 201.
/packages/{slug}owner/adminCampos parciales + data opcional (sustituye fichero con key versionada). 409 si no hay cambios.
/packages/{slug}owner/adminBorra fila + fichero R2.
04Descubrir
/stats{totalPackages, totalItems, totalDownloads, topTags, generatedAt}.
/tags?limit=12Top tags con conteo.
/feedSeñal de frescura {maxUpdatedAt, total} para invalidar cachés (la web la consulta cada 5 min).
05Favoritos auth
/favoritesLos tuyos, recientes primero.
/favorites{package_slug, item_title, item_link, item_data?} → 201 (409 si ya estaba).
/favorites?item_link=…Quitar (también acepta JSON con item_link).
/favorites/check?item_link=…{favorited: boolean}.
06Tokens auth
/tokensLista (nombre, prefijo, scopes, usos, expiración). Nunca devuelve secretos.
/tokens{name, scopes?([read]|[read,write]), expiresInDays?}. Solo desde sesión web, máx 20 activos. El token vuelve una vez.
/tokens/{id}Revoca (borrado lógico).
# ejemplo CI: publicar cada noche
TOKEN=$(curl -s -H "Authorization: Bearer $SESSION_JWT" \
-H "Content-Type: application/json" \
-d '{"name":"nightly","scopes":["read","write"],"expiresInDays":90}' \
https://indexlyhub.daida.net/api/v1/tokens | python3 -c "import sys,json;print(json.load(sys.stdin)['data']['token'])") 07Reportes
/reportsauth write{slug, reason (máx 120), details? (máx 2000)} → 201.
/reports?status=openadminCola de moderación.
08Errores y límites
Todo error responde {success:false, error:{code,message,details?}} con su HTTP:
| HTTP | code | Cuándo |
|---|---|---|
400 | VALIDATION_ERROR | Parámetros o JSON inválidos (details por campo) |
401 | UNAUTHORIZED | Falta Bearer o sesión/token inválido/revocado |
403 | FORBIDDEN | Sin scope write, sin permiso o cuota llena |
404 | NOT_FOUND | Slug inexistente |
409 | CONFLICT | Slug o checksum duplicado · sin cambios |
413 | FILE_TOO_LARGE | > 5 MB comprimido |
429 | RATE_LIMITED | 300 lecturas/min · 60 escrituras/min · 10 subidas/hora (cabeceras RateLimit-* + Retry-After) |
500 | STORAGE_ERROR/INTERNAL_ERROR | R2 o Supabase no disponible |
09Changelog
- v1.0 — API v1: lecturas abiertas, escritura con sesión/token, tokens
ih_…, favoritos y reportes vía API, rate limits,openapi.json.