Evogb Docs
3.0.0

Evogb Cloud

Infraestructura de almacenamiento híbrida con gestión avanzada.

Infraestructura Híbrida

Bienvenido a la documentación de Evogb Cloud. Este sistema proporciona almacenamiento en Nube Compartida y Privada, accesible mediante un Panel de Control Web interactivo y una API REST.

Resumen

Esta documentación cubre desde la gestión básica sobre Evogb Cloud hasta la integración avanzada (Bots, Apps, Scripts), incluyendo detalles sobre planes, límites y preferencias.

Arquitectura del Sistema

Evogb Cloud opera bajo un modelo de Ciclo de Vida Gestionado. Dependiendo de tu plan, tus archivos se almacenan y comportan de manera diferente.

Nube Compartida

Free / Lite / Go / Basic
  • Almacenamiento: Contenedores compartidos de alta disponibilidad.
  • Retención: Caducidad variable (30 días Free; permanente Plan Lite o superior).
  • Limpieza: 04:00 AM Hora Colombia
  • Ruta Interna: free/ (URL pública).
  • Limitaciones: Sin Contenedores privados, enlaces largos, y otros de acuerdo al plan.

Nube Privada

Plus / Pro / Ultra / Business
  • Almacenamiento: Infraestructura aislada y prioritaria.
  • Retención: Permanente (mientras la suscripción este vigente).
  • Privacidad: Opciones hide_user y hide_filename.
  • Ruta Interna: premium/ (URL pública limpia en raíz).
  • Ventajas: Soporte cualquier formato MIME */* y Dominios Personalizados (Plan Pro o superior).

Nota Técnica

El sistema usa una base de datos aislada en un sitio aparte y seguro para rastrear uso (almacenamiento, operaciones diarias) y archivos subidos, con resets diarios automáticos.

Planes y Límites

Variables del sistema que rigen tu cuenta (consultables vía /api/cdn/stats).

Atributo JSONNombre PanelDescripción y Efecto al Límite
storage_total_mbAlmacenamientoCapacidad total. Bloqueo (403): No podrás subir más hasta liberar espacio o mejorar plan.
upload_ops_limitSubidas DiariasMáx. archivos/24h. Temp (429): Reinicia a las 04:00 AM Colombia
download_ops_limitDescargas DiariasMáx. accesos/24h. Temp (429): Ilimitado en Business.
max_file_size_mbPeso MáximoRechazo (413): Subida cancelada inmediatamente.
allowed_mime_typesFormatosLista blanca. Rechazo (415) si no permitido.
retention_daysRetenciónVida útil. Eliminación: Se borra al cumplirse el plazo (30 días).
expiring_linksLinks TemporalesEn Desarrollo: No disponible actualmente.
custom_domainDominio PropioRequiere configuración CNAME y Plan Pro o superior.
PlanPrecios & Descuentos (USD)AlmacenamientoSubidas / DíaDescargas / DíaMáx. por ArchivoFormatosCuota IA Diaria
Free$0 (7d)100 MB11/día3005 MBImágenes básicas10 req/d
Lite$0.60 (15d)2.1 GB (2,100 MB)40/día3,00015 MBImg, PDF20 req/d
Go$0.99 (30d)
$1.14 (60d)
$1.29 (90d)
4.1 GB (4,100 MB)70/día8,00030 MBImg, PDF, Audio30 req/d
Basic Popular$1.69 (30d)
$1.95 (60d)
$2.20 (90d)
6.1 GB (6,100 MB)130/día20,00040 MBImg, PDF, Audio, Video40 req/d
Plus $3.39 (30d)
$3.90 (60d) -15% OFF
$4.41 (90d) -15% OFF
10.1 GB (10,100 MB)275/día55,00075 MBTodos (*/*)50 req/d
Pro $5.94 (60d)
$6.83 (90d)
$7.73 (365d)
25.5 GB (25,500 MB)600/día150,000125 MBTodos (*/*)80 req/d
Ultra $8.99 (60d)
$10.34 (90d)
$11.69 (365d)
50.5 GB (50,500 MB)1,500/día450,000500 MBTodos (*/*)100 req/d
Business $17.99 (60d)
$20.69 (90d)
$23.39 (365d) -40% OFF
100.5 GB (100,500 MB)7,500/díaIlimitado2 GB (2,000 MB)Todos (*/*)150 req/d

Nota Importante

Precios y duraciones varían por variante. Planes Premium incluyen preferencias de URL y retención permanente. Para mayor información visita la tienda

Guía del Panel Web (Cloud)

El panel ubicado en cloud.evogb.org es tu centro de comando visual, con un diseño responsivo (soporte móvil) y efectos animados.

Anillos de Estado

Visualiza consumo en tiempo real:

🟢 Normal 🟡 > 50% 🔴 > 85%

Upload Token

Llave maestra para APIs. Incluye botones para mostrar, copiar, regenerar y configurar permisos del token.

Permisos del Token

Filtros Avanzados

Busca por rango de peso, tipo, fecha o patrones de nombre (empieza/termina).

Prefs. Premium

Opciones de Personalización de Enlaces para ocultar usuario/archivo en URL.

Dominio Propio

Vincula tu marca (ej. cloud.tu-web.com). Incluye gestión DNS y SSL automático.

Gestión Masiva

Interfaz optimizada para grandes volúmenes. Paginación dinámica y carga fluida.

Tiempo Real (Sockets)

Sincronización instantánea de carpetas, archivos y consumo de tráfico.

  • Tiempo Real: Todas las operaciones (crear, renombrar, mover, borrar archivos/carpetas y consumo de descargas/disco) se sincronizan instantáneamente en vivo vía WebSockets sin recargar la web.
  • Navegación: Al cargar se sincronizan stats. Usa botones superiores para navegar en otros sitios de Evogb.
  • Monitoreo: Si un anillo está amarillo/rojo, revisa los iconos para instrucciones.
  • Gestión: Búsqueda , paginación (5-100 items) , y vista lista para detalles.
  • Seguridad: Cuida tu Upload Token. Permite acceso total a subidas/eliminar/ajustar. Ver Permisos del Token
  • Subidas: Soporte Drag & Drop, Ctrl+V. Usa el token para automatización masiva.
  • Gracia (7 días): Si expira el plan, entras en Gracia. No se borra nada por 7 días.
  • Dominios en Gracia: Siguen sirviendo archivos durante los 7 días, y solo se desconectan si no renuevas tu plan. Ir a la Tienda
  • Inspector: Clic en archivo para ver metadatos y copiar snippets HTML/MD/JSON.

Integración y API REST

Documentación técnica detallada para desarrolladores. Todas las peticiones requieren autenticación.

Base URL: https://api.evogb.org

Métodos de Autenticación CDN

El CDN soporta autenticación flexible para adaptarse a cualquier entorno:

  • Header (Recomendado): x-upload-token: <TU_UPLOAD_TOKEN>
  • Bearer Token: Authorization: Bearer <TU_UPLOAD_TOKEN>
  • Query Param: ?upload_token=<TU_UPLOAD_TOKEN> (Aislado de ?key= para evitar colisiones con la API global)
  • Body JSON/FormData: upload_token: "<TU_UPLOAD_TOKEN>"

Seguridad Granular del Upload Token

Por seguridad, las operaciones destructivas o críticas vía API (como eliminar archivos o carpetas recursivamente) vienen desactivadas por defecto para tu Upload Token. Puedes habilitar o personalizar permisos en cualquier momento desde el Panel CDN > Ajustes del Token.

POST /api/cdn/upload (Subida de Archivos y URLs)

Permite subir archivos locales (Buffer/Stream) y URLs a tu almacenamiento cloud, con soporte de carpetas virtuales recursivas, metadatos y dos modalidades de subida según el tamaño del archivo:

1. Subida Directa (Hasta 90 MB)

Envías el archivo completo en una única petición HTTP multipart/form-data. Ideal para fotos, audios, documentos y vídeos estándar.

2. Subida por Chunks (90 MB a 2,000 MB)

Para archivos gigantes (ej: 300 MB, 500 MB o 2 GB). El cliente divide el archivo en fragmentos de 25 MB y el servidor los une automáticamente.

¿Cómo funciona la subida de archivos gigantes (> 90 MB)?

Las infraestructuras de red y proxies perimetrales de Internet rechazan peticiones HTTP individuales mayores a 100 MB con el error 413 Payload Too Large. Por esta razón:

  • En el Cliente (Tu código / Frontend): Lees el archivo y lo cortas en trozos de 25 MB (usando Blob.slice() en la web o streams/buffers en backend). Generas un uploadId único y envías los fragmentos uno tras otro.
  • En el Servidor (CDN): Concatena de forma segura cada pedazo en el almacenamiento temporal. Al recibir el último fragmento (chunkIndex === totalChunks - 1), ensambla el archivo completo automáticamente, valida el tipo MIME y el peso de tu plan, y lo guarda en el CDN entregándote la URL definitiva.

Tabla de Parámetros (Query o FormData)

ParámetroTipoModalidadDescripción y Comportamiento
fileBinary / FileREQEl archivo binario completo o el fragmento (chunk) actual de 25 MB.
urlStringOpcionalURL pública de un archivo remoto para que el CDN lo descargue e ingeste automáticamente.
chunkIndexIntegerModo ChunksÍndice base 0 del fragmento actual (ej: 0 para el 1er chunk, 1 para el 2do, etc.).
totalChunksIntegerModo ChunksNúmero total de fragmentos en los que se dividió el archivo (ej: 12 para un archivo de 300 MB en bloques de 25 MB).
uploadIdStringModo ChunksIdentificador de sesión único compartido por todos los fragmentos del mismo archivo (ej: "up_1723849102" o UUID).
folder_idIntegerOpcionalID numérico de la carpeta de destino donde se guardará el archivo.
folder_path / pathStringOpcionalRuta virtual de carpetas (ej: "videos/2026/render"). Si no existen, el CDN las crea automáticamente.
custom_nameStringOpcionalSobrescribe el nombre del archivo en la URL final (ej: "video_final").
hide_userBooleanOpcional (Planes Pro+)true: URL en la raíz (cdn.evogb.org/Xy9K2.mp4).
false: Con usuario (cdn.evogb.org/usuario/Xy9K2.mp4).
hide_filenameBooleanOpcional (Planes Pro+)true: Oculta el nombre original y genera un enlace 100% aleatorio (ej: 7hKxS.webp).

Modo 1: Ejemplos de Subida Directa (Archivos < 90 MB)

Node.js (Subida Directa)
const axios = require("axios");
const FormData = require("form-data");
const fs = require("fs");
async function uploadFileDirect() {
const form = new FormData();
form.append("file", fs.createReadStream("./foto.jpg"));
form.append("folder_path", "proyectos/2026");
try {
const res = await axios.post("https://api.evogb.org/api/cdn/upload", form, {
headers: {
"x-upload-token": "TU_UPLOAD_TOKEN",
...form.getHeaders()
}
});
console.log("✅ Archivo Subido:", res.data);
console.log("🔗 URL Pública:", res.data.url);
} catch (err) {
console.error("❌ Error en subida:", err.response?.data || err.message);
}
}
uploadFileDirect();
Python (Subida Directa)
import requests
url = "https://api.evogb.org/api/cdn/upload"
headers = { "x-upload-token": "TU_UPLOAD_TOKEN" }
payload = { "folder_path": "proyectos/2026" }
with open("./foto.jpg", "rb") as f:
files = { "file": ("foto.jpg", f, "image/jpeg") }
res = requests.post(url, data=payload, files=files, headers=headers)
if res.status_code == 200:
print("✅ Archivo subido exitosamente:", res.json())
else:
print("❌ Error:", res.text)
cURL (Subida Directa)
curl -X POST "https://api.evogb.org/api/cdn/upload" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-F "file=@./foto.jpg" \
-F "folder_path=proyectos/2026"

Modo 2: Subida por Chunks para Archivos Gigantes (300 MB a 2,000 MB)

Divide el archivo en fragmentos de 25 MB y envíalos secuencialmente con el mismo uploadId. Al enviar el último fragmento, el servidor lo ensamblará automáticamente:

Node.js (Subida por Lotes de 25 MB)
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const path = require('path');
const CHUNK_SIZE = 25 * 1024 * 1024; // 25 MB por fragmento
const TOKEN = 'TU_UPLOAD_TOKEN';
async function uploadLargeFile(filePath) {
const fileStats = fs.statSync(filePath);
const totalBytes = fileStats.size;
const fileName = path.basename(filePath);
const totalChunks = Math.ceil(totalBytes / CHUNK_SIZE);
const uploadId = `up_${Date.now()}_${Math.random().toString(36).substring(2, 7)}`;
console.log(`🚀 Iniciando subida de: ${fileName} (${(totalBytes / 1024 / 1024).toFixed(2)} MB en ${totalChunks} chunks)`);
const fd = fs.openSync(filePath, 'r');
const buffer = Buffer.alloc(CHUNK_SIZE);
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const bytesRead = fs.readSync(fd, buffer, 0, CHUNK_SIZE, chunkIndex * CHUNK_SIZE);
const chunkBuffer = buffer.subarray(0, bytesRead);
const form = new FormData();
form.append('file', chunkBuffer, { filename: fileName });
form.append('chunkIndex', chunkIndex.toString());
form.append('totalChunks', totalChunks.toString());
form.append('uploadId', uploadId);
form.append('folder_path', 'videos/grandes');
const res = await axios.post('https://api.evogb.org/api/cdn/upload', form, {
headers: {
'x-upload-token': TOKEN,
...form.getHeaders()
},
maxContentLength: Infinity,
maxBodyLength: Infinity
});
// Auditoría y progreso a partir de las propiedades devueltas por el servidor
if (chunkIndex < totalChunks - 1) {
const currentChunk = res.data.current_chunk || (chunkIndex + 1);
const maxChunks = res.data.total_chunks || totalChunks;
const percent = Math.round((currentChunk / maxChunks) * 100);
console.log(`📦 Progreso confirmado: ${percent}% (Chunk ${currentChunk}/${maxChunks}) - ${res.data.message}`);
} else {
// El último chunk devuelve la respuesta completa con la URL pública
console.log('🎉 ¡Archivo ensamblado con éxito en el CDN!');
console.log('🔗 URL Pública:', res.data.url);
console.log('📄 ID en Base de Datos:', res.data.id);
}
}
fs.closeSync(fd);
}
uploadLargeFile('./video_de_300mb.mp4');
Python (Subida en Fragmentos de 25 MB)
import os
import math
import time
import requests
CHUNK_SIZE = 25 * 1024 * 1024  # 25 MB
TOKEN = "TU_UPLOAD_TOKEN"
API_URL = "https://api.evogb.org/api/cdn/upload"
def upload_large_file(file_path):
file_size = os.path.getsize(file_path)
file_name = os.path.basename(file_path)
total_chunks = math.ceil(file_size / CHUNK_SIZE)
upload_id = f"up_{int(time.time())}"
print(f"🚀 Subiendo {file_name} ({file_size / 1024 / 1024:.2f} MB) en {total_chunks} fragmentos...")
with open(file_path, "rb") as f:
for chunk_index in range(total_chunks):
chunk_data = f.read(CHUNK_SIZE)
payload = {
"chunkIndex": str(chunk_index),
"totalChunks": str(total_chunks),
"uploadId": upload_id,
"folder_path": "archivos/grandes"
}
files = {
"file": (file_name, chunk_data, "application/octet-stream")
}
headers = {
"x-upload-token": TOKEN
}
res = requests.post(API_URL, data=payload, files=files, headers=headers)
res.raise_for_status()
res_data = res.json()
if chunk_index < total_chunks - 1:
current_chunk = res_data.get("current_chunk", chunk_index + 1)
max_chunks = res_data.get("total_chunks", total_chunks)
percent = int((current_chunk / max_chunks) * 100)
print(f"📦 Progreso confirmado: {percent}% (Fragmento {current_chunk}/{max_chunks}) - {res_data.get('message')}")
else:
print("🎉 ¡Archivo completado y guardado en CDN!")
print("🔗 URL:", res_data.get("url"))
upload_large_file("./archivo_pesado.zip")
Frontend Web (Blob.slice con Barra de Progreso)
async function uploadFileFromBrowser(fileInput, onProgress) {
const file = fileInput.files[0];
if (!file) return alert("Selecciona un archivo primero");
const CHUNK_SIZE = 25 * 1024 * 1024; // 25 MB
const totalChunks = Math.ceil(file.size / CHUNK_SIZE);
const uploadId = `up_${Date.now()}_${Math.random().toString(36).substring(2, 6)}`;
const TOKEN = "TU_UPLOAD_TOKEN";
for (let chunkIndex = 0; chunkIndex < totalChunks; chunkIndex++) {
const start = chunkIndex * CHUNK_SIZE;
const end = Math.min(start + CHUNK_SIZE, file.size);
const chunkBlob = file.slice(start, end);
const formData = new FormData();
formData.append("file", chunkBlob, file.name);
formData.append("chunkIndex", chunkIndex);
formData.append("totalChunks", totalChunks);
formData.append("uploadId", uploadId);
const res = await fetch("https://api.evogb.org/api/cdn/upload", {
method: "POST",
headers: { "x-upload-token": TOKEN },
body: formData
});
const data = await res.json();
if (!res.ok) throw new Error(data.error || "Fallo en la subida");
if (chunkIndex < totalChunks - 1) {
const currentChunk = data.current_chunk || (chunkIndex + 1);
const maxChunks = data.total_chunks || totalChunks;
const percent = Math.round((currentChunk / maxChunks) * 100);
if (onProgress) onProgress(percent, data);
} else {
console.log("✅ Archivo subido con éxito:", data.url);
if (onProgress) onProgress(100, data);
return data;
}
}
}

Respuestas JSON de Ejemplo

1. Respuesta de Chunk Intermedio (ej: Chunk 1 al 11)
{
"status": true,
"code": 200,
"current_chunk": 1,
"total_chunks": 12,
"message": "Chunk 1/12 procesado."
}
2. Respuesta Final del Último Chunk (Ensamblado y Guardado en CDN)
{
"status": true,
"code": 200,
"id": 204,
"url": "https://cdn.evogb.org/Xy9K2.mp4",
"filename": "Xy9K2.mp4",
"original_name": "video_de_300mb.mp4",
"size_mb": 298.45,
"mime_type": "video/mp4",
"folder_id": 5
}
GET /api/cdn/files (Listar Archivos de la Cuenta)

Devuelve un Array JSON con la lista completa de archivos alojados en tu cuenta. Incluye metadatos técnicos, sociales (likes, tags) y de privacidad.

Parámetros de Consulta (Query Params)

ParámetroTipoObligatorioDescripción
folder_idInteger / StringOpcionalFiltra los archivos por carpeta. Pasa el ID numérico (ej: 5), "root" o "null" para ver solo archivos en la raíz, o déjalo vacío para listar todos.
Node.js (Axios)
const axios = require("axios");
async function listMyFiles() {
const res = await axios.get("https://api.evogb.org/api/cdn/files", {
headers: { "x-upload-token": "TU_UPLOAD_TOKEN" },
});
console.log(`📦 Total archivos: ${res.data.length}`);
console.log(res.data);
}
listMyFiles().catch((err) => {
console.error("❌ Error:", err.response?.data || err.message);
});
Python (Requests)
import requests
url = "https://api.evogb.org/api/cdn/files"
headers = { "x-upload-token": "TU_UPLOAD_TOKEN" }
res = requests.get(url, headers=headers)
res.raise_for_status()
files = res.json()
print(f"📦 Total archivos: {len(files)}")
print(files)
cURL
curl -X GET "https://api.evogb.org/api/cdn/files" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Respuesta Real (Array JSON)
[
{
"id": 108,
"file_uuid": "Xy9K2.jpg",
"original_name": "foto_portada.jpg",
"size_mb": 0.32,
"mime_type": "image/jpeg",
"upload_date": "2026-08-15T10:15:30.000Z",
"public_url": "https://cdn.evogb.org/Xy9K2.jpg",
"storage_path": "premium/Xy9K2.jpg",
"folder_id": 5,
"is_public": 1,
"likes": 12,
"is_pinned": 0,
"tags": "[\"banner\",\"portada\",\"2026\"]",
"is_sensitive": 0,
"is_public_suspended": 0
},
{
"id": 109,
"file_uuid": "7hKxS.webp",
"original_name": "grafico_reporte.webp",
"size_mb": 0.58,
"mime_type": "image/webp",
"upload_date": "2026-08-15T18:45:00.000Z",
"public_url": "https://cdn.evogb.org/7hKxS.webp",
"storage_path": "premium/7hKxS.webp",
"folder_id": null,
"is_public": 0,
"likes": 0,
"is_pinned": 1,
"tags": "[]",
"is_sensitive": 0,
"is_public_suspended": 0
}
]

Descripción de Campos del Objeto Archivo

CampoTipoDescripción Técnica
idIntegerIdentificador numérico único del archivo en la base de datos.
file_uuidStringIdentificador único / nombre seguro del archivo en el sistema de almacenamiento.
original_nameStringNombre original del archivo proporcionado en el momento de la subida.
size_mbFloatPeso total del archivo medido en Megabytes (MB).
mime_typeStringTipo MIME validado del archivo (ej: image/jpeg, video/mp4, application/pdf).
upload_dateString (ISO 8601)Fecha y hora exacta en la que se completó la subida.
public_urlStringEnlace HTTPS público directo servido a través de la red perimetral del CDN.
storage_pathStringRuta física interna del archivo en el almacenamiento seguro (ej: premium/Xy9K2.jpg).
folder_idInteger / nullID de la carpeta virtual en la que está ubicado (o null si está en la raíz).
is_publicInteger (0 o 1)1 si está publicado y visible en la Galería comunitaria, 0 si es privado.
likesIntegerCantidad acumulada de "me gusta" recibidos por la comunidad.
is_pinnedInteger (0 o 1)1 si el archivo está fijado en la parte superior del perfil público.
tagsString (JSON Array)Array serializado de etiquetas indexadas asociadas al archivo.
is_sensitiveInteger (0 o 1)1 si el archivo contiene contenido marcado como sensible/NSFW.
is_public_suspendedInteger (0 o 1)1 si la visibilidad pública en la galería fue pausada temporalmente por límite de ancho de banda.
GET /api/cdn/files/:id (Detalles de Archivo por ID)

Obtén la metadata completa de un solo archivo mediante su ID numérico en la ruta URL.

Node.js (Axios)
const axios = require("axios");
async function getFileDetails(id) {
try {
const res = await axios.get(`https://api.evogb.org/api/cdn/files/${id}`, {
headers: { "x-upload-token": "TU_UPLOAD_TOKEN" },
});
const file = res.data.file;
console.log(`📂 Archivo: ${file.original_name}`);
console.log(`🔗 URL: ${file.public_url}`);
console.log(res.data);
} catch (err) {
console.error("❌ Error:", err.response?.data || err.message);
}
}
getFileDetails(108);
Python (Requests)
import requests
file_id = 108
url = f"https://api.evogb.org/api/cdn/files/{file_id}"
headers = { "x-upload-token": "TU_UPLOAD_TOKEN" }
res = requests.get(url, headers=headers)
if res.status_code == 200:
data = res.json()
file_info = data.get("file", {})
print(f"📂 Archivo: {file_info.get('original_name')}")
print(f"🔗 URL: {file_info.get('public_url')}")
else:
print(f"❌ Error {res.status_code}:", res.text)
cURL
curl -X GET "https://api.evogb.org/api/cdn/files/108" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Respuesta Real (JSON)
{
"status": true,
"code": 200,
"file": {
"id": 108,
"file_uuid": "Xy9K2.jpg",
"original_name": "foto_portada.jpg",
"size_mb": 0.32,
"mime_type": "image/jpeg",
"upload_date": "2026-08-15T10:15:30.000Z",
"public_url": "https://cdn.evogb.org/Xy9K2.jpg",
"storage_path": "premium/Xy9K2.jpg",
"folder_id": 5,
"is_public": 1,
"likes": 12,
"is_pinned": 0,
"tags": "[\"banner\",\"portada\",\"2026\"]",
"is_sensitive": 0,
"is_public_suspended": 0
}
}
GET /api/cdn/stats (Consumo, Cuotas de IA y Límites)

Consulta en tiempo real para monitorear el consumo de almacenamiento en disco, operaciones diarias de subida y descarga, estado del dominio personalizado y cuotas de Inteligencia Artificial.

Esquema Completo de Propiedades (JSON)

BloqueCampoTipoDescripción Técnica
RootusernameStringNombre de usuario del titular de la cuenta.
planStringNombre comercial o ID del plan activo del usuario.
typePlanStringIdentificador técnico del plan (ej: free, lite, basic, pro, ultra, business).
limitsstorage_total_mbIntegerCapacidad máxima de disco asignada al plan (en MB).
upload_ops_limitIntegerTope diario de archivos que se pueden subir (se reinicia a las 04:00 AM).
download_ops_limitInteger / StringTope diario de descargas/visualizaciones permitidas (o "unlimited").
max_file_size_mbIntegerPeso máximo permitido por archivo individual (ej: 5 MB en Free, 125 MB en Pro, 2000 MB en Business).
allowed_mime_typesArrayFormatos de archivo permitidos. ["*/*"] indica sin restricción.
private_bucketsBooleanIndica si el almacenamiento es aislado y dedicado.
expiring_linksBooleanIndica si el plan tiene acceso a generación de enlaces temporales.
custom_domainBooleanIndica si el plan permite vincular un dominio personalizado propio con SSL automático.
retention_daysInteger / nullDías de retención automática de archivos (o null para almacenamiento permanente).
ai_quotausedIntegerPeticiones de Inteligencia Artificial consumidas en el ciclo actual.
maxIntegerLímite máximo de peticiones de IA asignadas según el plan.
remainingIntegerPeticiones de IA restantes disponibles para usar.
usageemailStringCorreo electrónico del usuario.
storage_used_mbFloatEspacio en disco consumido actualmente (en MB).
upload_ops_dailyIntegerContador de archivos subidos durante el día actual.
download_ops_dailyIntegerContador de descargas/visualizaciones registradas hoy.
custom_domainString / nullDominio propio configurado (ej: "cdn.midominio.com") o null.
domain_statusStringEstado del dominio propio: configured, pending (validando SSL) o active (en producción).
last_reset_dateString (YYYY-MM-DD)Fecha del último reinicio de contadores diarios.
Solicitud (Node.js)
const axios = require("axios");
async function checkStats() {
const res = await axios.get("https://api.evogb.org/api/cdn/stats", {
headers: { "x-upload-token": "TU_UPLOAD_TOKEN" },
});
console.log(`📊 Almacenamiento: ${res.data.usage.storage_used_mb} MB / ${res.data.limits.storage_total_mb} MB`);
console.log(`🧠 Cuota de IA: ${res.data.ai_quota.used} / ${res.data.ai_quota.max} peticiones`);
console.log(`📥 Descargas Hoy: ${res.data.usage.download_ops_daily} / ${res.data.limits.download_ops_limit}`);
}
checkStats();
Ejemplo Respuesta JSON (/api/cdn/stats)
{
"status": true,
"code": 200,
"username": "usuario_dev",
"plan": "Pro",
"typePlan": "pro",
"limits": {
"storage_total_mb": 25500,
"upload_ops_limit": 600,
"download_ops_limit": 150000,
"max_file_size_mb": 125,
"allowed_mime_types": ["*/*"],
"private_buckets": true,
"expiring_links": true,
"custom_domain": true,
"retention_days": null
},
"ai_quota": {
"used": 14,
"max": 80,
"remaining": 66
},
"usage": {
"email": "[email protected]",
"storage_used_mb": 4210.55,
"upload_ops_daily": 35,
"download_ops_daily": 1240,
"last_reset_date": "2026-08-16",
"custom_domain": "cdn.midominio.com",
"domain_status": "active"
}
}
POST /api/cdn/delete (Eliminar Archivo)

Eliminación definitiva de un archivo tanto de la base de datos como del almacenamiento en la nube y purga instantánea de la red de distribución global (CDN). Libera espacio en storage_used_mb inmediatamente.

Parámetros (Body JSON)

ParámetroTipoObligatorioDescripción
idIntegerREQID numérico del archivo que se desea eliminar (ej: 108).
Solicitud cURL
curl -X POST "https://api.evogb.org/api/cdn/delete" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 108 }'
Respuesta JSON
{
"status": true,
"code": 200,
"message": "Archivo eliminado correctamente."
}
POST /api/user/cdn-prefs
& GET /api/user/cdn-prefs (Preferencias de Enlace)

Permite consultar y configurar si los enlaces públicos generados deben ocultar el nombre de usuario o el nombre original del archivo (disponible para planes con soporte de personalización y privacidad).

Parámetros (Body JSON para POST)

ParámetroTipoDescripción
hide_usernameBooleantrue para omitir la subcarpeta de usuario en la URL generada (ej: cdn.evogb.org/Xy9K2.jpg).
hide_filenameBooleantrue para usar únicamente un identificador único aleatorio en lugar del nombre original.
Guardar y Consultar Preferencias (Node.js)
const axios = require('axios');
// 1. Actualizar preferencias
await axios.post('https://api.evogb.org/api/user/cdn-prefs', {
hide_username: true,
hide_filename: false
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
// 2. Consultar preferencias actuales
const res = await axios.get('https://api.evogb.org/api/user/cdn-prefs', {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("Preferencias CDN:", res.data);
cURL
# Actualizar preferencias
curl -X POST "https://api.evogb.org/api/user/cdn-prefs" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"hide_username": true, "hide_filename": false}'
# Obtener preferencias
curl -X GET "https://api.evogb.org/api/user/cdn-prefs" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Respuesta JSON (GET /api/user/cdn-prefs)
{
"status": true,
"code": 200,
"prefs": {
"hide_username": true,
"hide_filename": false
}
}

Descripción de Propiedades de Preferencias

PropiedadTipoDescripción
statusBooleanIndica si la solicitud fue procesada exitosamente (true / false).
codeIntegerCódigo de estado HTTP de la respuesta (200).
prefs.hide_usernameBooleantrue si los enlaces públicos generados se crean en la raíz del CDN sin la carpeta del usuario.
prefs.hide_filenameBooleantrue si los enlaces públicos generados ocultan el nombre original del archivo con un hash aleatorio.

Gestión de Carpetas & Rutas

Organiza tus archivos en estructuras jerárquicas virtuales ilimitadas mediante código. Las carpetas permiten organizar proyectos, categorizar recursos y realizar operaciones recursivas en lote.

GET /api/cdn/folders (Listar Carpetas)

Devuelve todas las carpetas del usuario con su ruta calculada (path), cantidad de archivos contenidos (file_count) y peso acumulado en MB (total_size_mb).

Node.js (Axios)
const axios = require('axios');
async function listFolders() {
const res = await axios.get('https://api.evogb.org/api/cdn/folders', {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log(`📁 Total carpetas: ${res.data.total_folders}`);
console.log(res.data.folders);
}
listFolders();
Python (Requests)
import requests
res = requests.get('https://api.evogb.org/api/cdn/folders', headers={'x-upload-token': 'TU_UPLOAD_TOKEN'})
data = res.json()
print(f"📁 Total carpetas: {data.get('total_folders')}")
for f in data.get('folders', []):
print(f" - [{f['id']}] {f['path']} ({f['file_count']} archivos, {f['total_size_mb']} MB)")
cURL
curl -X GET "https://api.evogb.org/api/cdn/folders" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Respuesta JSON (GET /api/cdn/folders)
{
"status": true,
"code": 200,
"total_folders": 2,
"folders": [
{
"id": 1,
"name": "proyectos",
"color": "#3b82f6",
"parent_id": null,
"path": "proyectos",
"file_count": 5,
"total_size_mb": 12.45,
"created_at": "2026-01-10T12:00:00.000Z"
},
{
"id": 2,
"name": "assets",
"color": "#10b981",
"parent_id": 1,
"path": "proyectos/assets",
"file_count": 8,
"total_size_mb": 4.10,
"created_at": "2026-01-11T15:30:00.000Z"
}
]
}

Descripción de Propiedades de Carpetas

PropiedadTipoDescripción Técnica
statusBooleanIndica si la consulta fue procesada con éxito (true / false).
codeIntegerCódigo de estado HTTP de la respuesta (200).
total_foldersIntegerCantidad total de carpetas existentes en la cuenta.
folders[].idIntegerID numérico único de la carpeta.
folders[].nameStringNombre asignado a la carpeta.
folders[].parent_idInteger / nullID de la carpeta padre contenedora (o null si está en la raíz).
folders[].colorString (Hex)Color HEX distintivo asignado en el panel web.
folders[].pathStringRuta jerárquica virtual calculada (ej: "proyectos/assets").
folders[].file_countIntegerTotal de archivos almacenados directamente en esta carpeta.
folders[].total_size_mbFloatPeso total acumulado en MB de todos los archivos dentro de la carpeta.
folders[].created_atString (ISO 8601)Fecha y hora de creación de la carpeta.
POST /api/cdn/folders (Crear Carpeta o Ruta)

Crea una carpeta individual o resuelve automáticamente una ruta anidada completa (ej: "app/frontend/icons").

ParámetroTipoObligatorioDescripción
nameStringCondicionalNombre de la carpeta simple (ej: "imagenes"). Requerido si no se envía path.
pathStringCondicionalRuta jerárquica (ej: "docs/2026/pdf"). Crea todos los ancestros inexistentes de forma automática.
parent_idInteger / nullOpcionalID de la carpeta padre si se usa name. Enviar null para la raíz.
colorString (Hex)OpcionalColor HEX de identificación en el panel web (por defecto: #3b82f6).
Ejemplo cURL (Creación por Ruta)
curl -X POST "https://api.evogb.org/api/cdn/folders" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "path": "sitio_web/v2/banners", "color": "#8b5cf6" }'
Respuesta JSON (POST /api/cdn/folders)
{
"status": true,
"code": 200,
"folder": {
"id": 5,
"name": "banners",
"color": "#8b5cf6",
"parent_id": 2,
"created_at": "2026-08-16T00:00:00.000Z"
},
"created_by_path": true
}
PUT /api/cdn/folders/:id
o POST /api/cdn/folders/edit (Editar Carpeta)

Permite renombrar la carpeta, cambiar su color o moverla de jerarquía mediante parent_id.

Node.js (PUT RESTful)
const axios = require('axios');
const res = await axios.put('https://api.evogb.org/api/cdn/folders/12', {
name: 'documentos_finales',
color: '#f59e0b',
parent_id: null // Mover a la raíz o a otra carpeta
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("Respuesta:", res.data);
Respuesta JSON (Edición de Carpeta)
{
"status": true,
"code": 200,
"message": "Carpeta actualizada exitosamente.",
"folder": {
"id": 12,
"name": "documentos_finales",
"color": "#f59e0b",
"parent_id": null
}
}
DELETE /api/cdn/folders/:id
o POST /api/cdn/folders/delete (Borrado Recursivo)

CUIDADO Elimina la carpeta indicada, todas sus subcarpetas de manera recursiva, y purga todos los archivos contenidos en ella de forma permanente del almacenamiento en la nube y de la red de distribución global (CDN), liberando el espacio de disco automáticamente.

cURL (Borrado Recursivo)
curl -X DELETE "https://api.evogb.org/api/cdn/folders/12" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Respuesta JSON (Borrado Recursivo)
{
"status": true,
"code": 200,
"message": "Carpeta y todos sus archivos eliminados correctamente.",
"deleted_folders_count": 3,
"deleted_files_count": 14,
"freed_storage_mb": 28.50
}
POST /api/cdn/move
& POST /api/cdn/folders/move (Mover Archivos y Carpetas)

Permite reubicar archivos o subárboles completos de carpetas con protección estricta contra ciclos infinitos.

Mover Archivo (POST /api/cdn/move)

// Mover archivo por ID de carpeta o por ruta
const res = await axios.post('https://api.evogb.org/api/cdn/move', {
id: 108,                 // ID del archivo
folder_id: 5             // O pasar 'path': "proyectos/produccion"
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
Respuesta JSON (/api/cdn/move)
{
"status": true,
"code": 200,
"message": "Archivo movido correctamente.",
"file_id": 108,
"folder_id": 5
}

Mover Carpeta (POST /api/cdn/folders/move)

const res = await axios.post('https://api.evogb.org/api/cdn/folders/move', {
id: 15,                  // ID de la carpeta a mover
parent_id: 3             // Nueva carpeta padre (o null para raíz)
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
Respuesta JSON (/api/cdn/folders/move)
{
"status": true,
"code": 200,
"message": "Carpeta movida exitosamente.",
"id": 15,
"parent_id": 3
}

Árbol Jerárquico del CDN

Obtén en una sola consulta toda la estructura anidada de tus proyectos. Ideal para renderizar exploradores de archivos en tus propias aplicaciones, sincronizar sistemas locales o inspeccionar el CDN de forma completa.

GET /api/cdn/tree (Árbol Completo)

Parámetros Query

ParámetroTipoPor DefectoDescripción
include_filesBooleanfalseSi es true, incluye el array files dentro de cada nodo de carpeta y root_files en la raíz.
folder_idInteger / nullnull (Raíz)Filtra el árbol para obtener únicamente el subárbol a partir de una carpeta específica.
limitInteger2000 (Max 5000)Límite máximo de archivos retornados cuando include_files=true para optimizar rendimiento.
Node.js (Axios)
const axios = require('axios');
async function getCdnTree() {
const res = await axios.get('https://api.evogb.org/api/cdn/tree?include_files=true', {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("📊 Estadísticas del CDN:", res.data.stats);
console.log("🌳 Árbol Jerárquico:", JSON.stringify(res.data.tree, null, 2));
}
getCdnTree();
Python (Requests)
import requests
res = requests.get('https://api.evogb.org/api/cdn/tree?include_files=true', headers={'x-upload-token': 'TU_UPLOAD_TOKEN'})
tree_data = res.json()
print("Stats:", tree_data['stats'])
cURL
curl -X GET "https://api.evogb.org/api/cdn/tree?include_files=true" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Estructura de Respuesta JSON (/api/cdn/tree)
{
"status": true,
"code": 200,
"stats": {
"total_folders": 3,
"total_files": 42,
"root_files_count": 10,
"storage_used_mb": 85.32,
"storage_limit_mb": 2048,
"files_included": true
},
"tree": [
{
"id": 1,
"name": "frontend",
"color": "#3b82f6",
"path": "frontend",
"file_count": 12,
"total_size_mb": 25.10,
"children": [
{
"id": 2,
"name": "icons",
"color": "#10b981",
"path": "frontend/icons",
"file_count": 5,
"total_size_mb": 1.20,
"children": [],
"files": [
{
"id": 108,
"file_uuid": "7hKxS.svg",
"storage_path": "premium/7hKxS.svg",
"original_name": "logo.svg",
"public_name": "logo.svg",
"size_mb": 0.04,
"size_bytes": 41943,
"mime_type": "image/svg+xml",
"public_url": "https://cdn.evogb.org/7hKxS.svg",
"folder_id": 2,
"folder_path": "/frontend/icons",
"is_public": true,
"is_sensitive": false,
"tags": ["brand", "vector"]
}
]
}
],
"files": []
}
],
"root_files": [
{
"id": 101,
"file_uuid": "3mPqW.txt",
"storage_path": "premium/3mPqW.txt",
"original_name": "readme.txt",
"public_name": "readme.txt",
"size_mb": 0.01,
"mime_type": "text/plain",
"public_url": "https://cdn.evogb.org/3mPqW.txt",
"folder_id": null,
"folder_path": "/",
"is_public": true,
"is_sensitive": false,
"tags": ["documentation"]
}
]
}

Esquema de Propiedades del Árbol (Tree JSON)

Sección / PropiedadTipoDescripción Técnica
stats.total_foldersIntegerTotal de carpetas creadas en la cuenta.
stats.total_filesIntegerTotal acumulado de archivos en todas las carpetas y raíz.
stats.root_files_countIntegerCantidad de archivos ubicados en la raíz del CDN.
stats.storage_used_mbFloatEspacio de almacenamiento consumido actualmente en MB.
stats.storage_limit_mbIntegerLímite total de almacenamiento según el plan activo.
tree[].childrenArraySubcarpetas anidadas recursivamente dentro del nodo actual.
tree[].filesArrayLista de archivos contenidos en esta carpeta (si include_files=true).
root_filesArrayLista de archivos ubicados en la raíz (si include_files=true y folder_id=null).
GET /api/cdn/file (Consulta JSON de Archivo Individual)

Permite obtener la metadata completa de un archivo individual utilizando cualquiera de sus 3 identificadores soportados: id (numérico), file_uuid (nombre seguro) o storage_path (ruta física).

ParámetroTipoObligatorioDescripción
idIntegerCondicionalID numérico del archivo en la base de datos (ej: 108).
file_uuidStringCondicionalUUID único del archivo (ej: "Xy9K2.jpg").
storage_pathStringCondicionalRuta interna del archivo en el almacenamiento seguro (ej: "premium/Xy9K2.jpg" o "free/Xy9K2.jpg").
Node.js (Axios)
const axios = require('axios');
async function getFileInfo() {
// Consulta por ID, UUID o Storage Path
const res = await axios.get('https://api.evogb.org/api/cdn/file?id=108', {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("📄 Metadata del Archivo:", res.data.file);
}
getFileInfo();
Python (Requests)
import requests
res = requests.get('https://api.evogb.org/api/cdn/file?file_uuid=Xy9K2.jpg', headers={'x-upload-token': 'TU_UPLOAD_TOKEN'})
print(res.json())
cURL
curl -X GET "https://api.evogb.org/api/cdn/file?id=108" \
-H "x-upload-token: TU_UPLOAD_TOKEN"
Ejemplo Respuesta JSON (Archivo Individual)
{
"status": true,
"code": 200,
"file": {
"id": 108,
"file_uuid": "Xy9K2.jpg",
"storage_path": "premium/Xy9K2.jpg",
"original_name": "factura_enero.png",
"public_name": "factura_enero.png",
"size_mb": 0.45,
"size_bytes": 471859,
"mime_type": "image/png",
"upload_date": "2026-08-15T18:00:00.000Z",
"public_url": "https://cdn.evogb.org/Xy9K2.jpg",
"folder_id": 5,
"folder_path": "/Documentos/Facturas",
"is_public": true,
"is_sensitive": false,
"tags": ["factura", "contabilidad", "2026"]
}
}

CDN IA Suite

Aprovecha los modelos de inteligencia artificial multimodal de última generación integrados directamente con tu almacenamiento. Analiza imágenes, extrae texto mediante OCR, transcribe audios y videos, audita código fuente, extrae paletas cromáticas, modera contenidos y realiza búsquedas semánticas sin salir del CDN.

Facturación, Cuotas de IA y Privacidad

Las funciones de IA del CDN consumen la cuota diaria de peticiones asignada a tu plan (requests_ai). El procesamiento se realiza de forma privada y segura sobre tu almacenamiento cloud, permitiendo analizar archivos privados sin necesidad de exponerlos públicamente a internet.

Tabla de Consumo de Peticiones de IA

Conoce con exactitud qué funciones descuentan de tu cuota diaria de IA y cuáles son totalmente ilimitadas:

Endpoint / FunciónCosto de CuotaMétricasDescripción
POST /api/cdn/ai/analyze
(describe, ocr, transcribe, code_refactor, summarize, palette, moderation, tags, custom)
1 Request IARegistradoSuite multimodal: Visión artificial, OCR, transcripción de audio/video, refactorización de código, paletas, resúmenes y moderación.
POST /api/cdn/ai/tag
(Auto-etiquetado)
1 Request IARegistradoGenera etiquetas semánticas y las guarda directamente en los metadatos del archivo para indexación.
POST /api/cdn/ai/chat
(Chat Neuronal)
1 Request IARegistradoInteractúa con el asistente conversacional para desarrolladores autenticando con tu x-upload-token.
POST /api/cdn/ai/search
(Búsqueda Inteligente)
0 Requests (Gratis)Sin consumoBúsqueda indexada de alta velocidad sobre nombres, carpetas, tipos de archivo y etiquetas generadas.
GET /api/cdn/tree
(Árbol de Carpetas/Archivos)
0 Requests (Gratis)Sin consumoEstructuración y cálculo de árboles jerárquicos y estadísticas de carpetas.
Operaciones de Almacenamiento
(upload, files, folders, move, delete, zip)
0 Requests (Gratis)Sin consumoTodas las operaciones estándar de gestión de archivos y carpetas en la nube.
Límites de Tamaño por Tarea

• Auditoría de Código (code_refactor): Máximo 3 MB.
• Transcripción (transcribe): Audios y videos hasta 10 MB.
• Imágenes y Documentos: Máximo 10 MB.
• Objetivo de Análisis: Las tareas de IA aplican exclusivamente a archivos individuales. Enviar una carpeta retornará 400 Bad Request.

Moderación Automática NSFW (Galería)

Al publicar un archivo en la Galería (POST /api/cdn/toggle-public), el sistema de moderación automática evalúa el archivo. Si detecta contenido explícito o sensible, activa is_sensitive = 1 difuminando el contenido para proteger la visualización pública.

Respuesta al Agotar Cuota Diaria de IA (HTTP 429)
{
"status": false,
"code": 429,
"error": "Has alcanzado el límite diario de peticiones de IA de tu plan.",
"details": {
"type": "user_limit_reached",
"current": 50,
"limit": 50,
"hours_until_reset": 6,
"plan": "lite",
"next_recommended_plan": "go"
}
}
POST /api/cdn/ai/analyze (Suite Multimodal de Tareas de IA)

Ejecuta tareas inteligentes contextuales adaptadas al tipo de archivo almacenado en tu cuenta (imágenes, código, audios, videos y documentos) y retorna un JSON estructurado con el resultado del análisis.

Matriz de Tareas Soportadas

Tarea (task)Formatos CompatiblesLímite MáximoResultado Devuelto en JSON
describeImágenes y Videos (PNG, JPG, WEBP, MP4, GIF, SVG)Max 10 MBTítulo conciso, descripción visual técnica, resumen de 1 frase, sujetos principales, colores dominantes y tono.
ocrImágenes y Documentos (PNG, JPG, WEBP, PDF, TIFF, BMP)Max 10 MBExtracción completa de texto (OCR), idioma detectado, array de líneas/párrafos y nivel de confianza.
transcribe (o transcription)Audio y Video (MP3, WAV, OGG, M4A, MP4, WEBM, MKV, FLAC)Max 10 MBTranscripción completa de voz a texto, idioma detectado, resumen temático, estimación de ritmo y temas clave.
code_refactor (o code_review, refactor)Archivos de Código (JS, TS, PY, HTML, CSS, JSON, SQL, SH, PHP, CPP, RS, etc.)Max 3 MBDiagnóstico de arquitectura, detección de fallas (seguridad/rendimiento/estilo), código refactorizado y complejidad temporal.
summarizeDocumentos, Textos y Código (PDF, TXT, MD, CSV, Scripts)Max 10 MBTítulo representativo, resumen ejecutivo estructurado, puntos clave destacados (takeaways), tiempo de lectura y keywords.
paletteImágenes (PNG, JPG, WEBP, SVG, BMP)Max 10 MBPaleta cromática con valores HEX, nombres, porcentajes y roles (primary, secondary, accent, background), armonía y accesibilidad WCAG.
moderationImágenes, Videos, Audios y DocumentosMax 10 MBEvaluación de seguridad, banderas is_safe y is_sensitive, score NSFW (0.0 a 1.0), categorías y motivo descriptivo.
tagsTodos los formatos soportadosMax 10 MBGeneración de 6 a 15 etiquetas semánticas para indexación. Si save_tags: true, se guardan en los metadatos del archivo.
customTodos los formatos soportadosMax 10 MBEjecuta un prompt libre personalizado enviado en el parámetro prompt directamente contra el archivo multimedia o de texto.

Parámetros de la Petición

ParámetroTipoObligatorioDescripción
id / file_idIntegerCondicionalID numérico del archivo individual registrado en tu cuenta de CDN.
file_uuidStringCondicionalUUID del archivo (ej: "k9xL2pQ.jpg").
storage_pathStringCondicionalRuta del archivo en el almacenamiento (ej: "usuario/k9xL2pQ.jpg").
taskStringOpcionalTarea a ejecutar (por defecto: "describe"). Valores válidos: "describe", "ocr", "transcribe", "code_refactor", "summarize", "palette", "moderation", "tags", "custom".
promptStringOpcionalInstrucción personalizada requerida cuando task="custom" o para añadir contexto adicional a la tarea.
save_tagsBooleanOpcionalSi es true y la tarea genera etiquetas (o task="tags"), las guarda automáticamente en el registro del archivo.

Ejemplos de Implementación para Desarrolladores

Node.js (Ejecución de Tareas de IA)
const axios = require('axios');
const CDN_API = 'https://api.evogb.org/api/cdn/ai/analyze';
const UPLOAD_TOKEN = 'TU_UPLOAD_TOKEN';
// Instancia configurada de Axios
const cdnClient = axios.create({
headers: {
'x-upload-token': UPLOAD_TOKEN,
'Content-Type': 'application/json'
}
});
async function runAiTasks() {
try {
// 1. Refactorización y Auditoría de Código
const codeAnalysis = await cdnClient.post(CDN_API, {
id: 310,
task: 'code_refactor'
});
console.log("🛠️ Código Refactorizado:\n", codeAnalysis.data.result.refactored_code);
console.log("📊 Cuota Restante:", codeAnalysis.data.ai_quota.remaining_today);
// 2. Transcripción de Audio / Video
const audioTrans = await cdnClient.post(CDN_API, {
id: 205,
task: 'transcribe'
});
console.log("🎙️ Idioma detectado:", audioTrans.data.result.detected_language);
console.log("📝 Transcripción:\n", audioTrans.data.result.transcription);
// 3. Extracción de Texto OCR desde Imagen o Factura
const ocrResult = await cdnClient.post(CDN_API, {
id: 142,
task: 'ocr'
});
console.log("📄 Texto OCR:\n", ocrResult.data.result.text);
// 4. Extracción de Paleta de Colores y Estilo
const paletteResult = await cdnClient.post(CDN_API, {
file_uuid: 'banner-hero.png',
task: 'palette'
});
console.log("🎨 Colores Dominantes:", paletteResult.data.result.dominant_palette);
// 5. Prompt Libre Personalizado
const customResult = await cdnClient.post(CDN_API, {
id: 520,
task: 'custom',
prompt: 'Enumera los 3 elementos visuales más llamativos y redacta un post promocional para esta imagen.'
});
console.log("✨ Resultado Personalizado:\n", customResult.data.result.output);
} catch (error) {
if (error.response) {
console.error(`❌ Error (${error.response.status}):`, error.response.data);
} else {
console.error("❌ Error de Conexión:", error.message);
}
}
}
runAiTasks();
Python (Requests)
import requests
CDN_API = "https://api.evogb.org/api/cdn/ai/analyze"
HEADERS = {
"x-upload-token": "TU_UPLOAD_TOKEN",
"Content-Type": "application/json"
}
# 1. Moderación y Auditoría de Seguridad de Imagen/Video
mod_payload = {
"id": 618,
"task": "moderation"
}
res_mod = requests.post(CDN_API, json=mod_payload, headers=HEADERS)
data_mod = res_mod.json()
print("🛡️ ¿Es seguro?:", data_mod.get("result", {}).get("is_safe"))
print("⚠️ Score NSFW:", data_mod.get("result", {}).get("nsfw_score"))
# 2. Resumen Ejecutivo de un PDF o Documento
sum_payload = {
"file_uuid": "informe-anual.pdf",
"task": "summarize"
}
res_sum = requests.post(CDN_API, json=sum_payload, headers=HEADERS)
data_sum = res_sum.json()
print("📑 Resumen Ejecutivo:\n", data_sum.get("result", {}).get("executive_summary"))
print("🔑 Puntos Clave:", data_sum.get("result", {}).get("key_takeaways"))
# 3. Auto-etiquetado con guardado automático en metadatos
tags_payload = {
"id": 720,
"task": "tags",
"save_tags": True
}
res_tags = requests.post(CDN_API, json=tags_payload, headers=HEADERS)
print("🏷️ Tags Generados:", res_tags.json().get("result", {}).get("tags"))
JavaScript (Fetch API)
async function analyzeFileInBrowser(fileId, taskName = 'describe') {
const response = await fetch('https://api.evogb.org/api/cdn/ai/analyze', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-upload-token': 'TU_UPLOAD_TOKEN'
},
body: JSON.stringify({
id: fileId,
task: taskName,
save_tags: true
})
});
if (!response.ok) {
const errorData = await response.json();
throw new Error(errorData.error || `HTTP ${response.status}`);
}
const data = await response.json();
console.log("✅ Análisis completado:", data);
return data.result;
}
// Ejemplo de uso:
// analyzeFileInBrowser(108, 'ocr').then(result => console.log(result.text));
Terminal (cURL - 9 Tareas Multimodales)
# 1. Tarea: describe (Descripción visual profunda de imagen/video)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 135, "task": "describe" }'
# 2. Tarea: palette (Extracción de paleta cromática de colores HEX)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 163, "task": "palette" }'
# 3. Tarea: ocr (Extracción de texto en documentos o fotos)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 135, "task": "ocr" }'
# 4. Tarea: transcribe (Transcripción inteligente de audio o video)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 137, "task": "transcribe" }'
# 5. Tarea: code_refactor (Auditoría y optimización de código fuente)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 156, "task": "code_refactor" }'
# 6. Tarea: summarize (Resumen ejecutivo y puntos clave)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 156, "task": "summarize" }'
# 7. Tarea: moderation (Detección de contenido sensible y NSFW score)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 165, "task": "moderation" }'
# 8. Tarea: tags (Generación de etiquetas contextuales en memoria)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 163, "task": "tags" }'
# 9. Tarea: custom (Instrucción / Prompt libre sobre cualquier archivo)
curl -X POST "https://api.evogb.org/api/cdn/ai/analyze" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 156, "task": "custom", "prompt": "Explica la arquitectura de este archivo y sus dependencias." }'

Ejemplos de JSON Devuelto por Cada Tarea (Schemas & Outputs)

Selecciona la tarea para inspeccionar la estructura exacta del JSON devuelto en la propiedad result:

Respuesta JSON: task="describe"
{
"status": true,
"code": 200,
"task": "describe",
"file_id": 108,
"original_name": "hero-dashboard-banner.png",
"mime_type": "image/png",
"result": {
"title": "Banner promocional futurista de panel de control en la nube",
"description": "Una composición digital moderna que muestra una interfaz gráfica holográfica en modo oscuro con paneles de analítica, gráficos de línea en tono violeta y cian brillante, métricas de rendimiento del servidor y partículas de datos flotantes.",
"summary": "Banner publicitario de alta tecnología enfocado en soluciones de computación en la nube y monitoreo en tiempo real.",
"subjects": [
"interfaz de usuario dark mode",
"gráficos interactivos",
"nube de datos conectada",
"paneles de analítica"
],
"dominant_colors": [
"#0f172a",
"#3b82f6",
"#8b5cf6",
"#06b6d4"
],
"mood": "tecnológico, sofisticado, dinámico y profesional"
},
"ai_quota": {
"remaining_today": 49,
"daily_limit": 50
}
}
Respuesta JSON: task="ocr"
{
"status": true,
"code": 200,
"task": "ocr",
"file_id": 142,
"original_name": "recibo-servicio-hosting.png",
"mime_type": "image/png",
"result": {
"text": "INVOICE #INV-2026-8819\nFecha de emisión: 15 de Agosto de 2026\nCliente: Tech Solutions Latam S.A.\nRUT/ID: 1792348910001\nDescripción: Suscripción Plan Pro Anual Almacenamiento Cloud\nSubtotal: $120.00 USD\nIVA (15%): $18.00 USD\nTotal Pagado: $138.00 USD\nEstado: COMPLETADO (Aprobado)",
"detected_language": "es",
"lines": [
"INVOICE #INV-2026-8819",
"Fecha de emisión: 15 de Agosto de 2026",
"Cliente: Tech Solutions Latam S.A.",
"RUT/ID: 1792348910001",
"Descripción: Suscripción Plan Pro Anual Almacenamiento Cloud",
"Subtotal: $120.00 USD",
"IVA (15%): $18.00 USD",
"Total Pagado: $138.00 USD",
"Estado: COMPLETADO (Aprobado)"
],
"confidence": "alto"
},
"ai_quota": {
"remaining_today": 48,
"daily_limit": 50
}
}
Respuesta JSON: task="transcribe"
{
"status": true,
"code": 200,
"task": "transcribe",
"file_id": 205,
"original_name": "reunion-sincronizacion.mp3",
"mime_type": "audio/mpeg",
"result": {
"transcription": "Hola equipo. En la sesión de hoy confirmamos que la integración de la suite de IA del CDN ya soporta procesamiento directo sobre archivos privados sin necesidad de exponerlos a internet. Todos los desarrolladores pueden autenticar con su upload token mediante headers o query params. La cuota diaria se descuenta por cada petición exitosa y la respuesta incluye el balance en tiempo real.",
"detected_language": "es",
"summary": "Reunión técnica confirmando la arquitectura de seguridad y autenticación de la suite de IA sobre almacenamiento cloud.",
"duration_estimate": "45 segundos",
"speakers_count": 1,
"key_topics": [
"Almacenamiento Seguro",
"Suite de IA CDN",
"Upload Token",
"Cuotas Diarias",
"Archivos Privados"
]
},
"ai_quota": {
"remaining_today": 47,
"daily_limit": 50
}
}
Respuesta JSON: task="code_refactor"
{
"status": true,
"code": 200,
"task": "code_refactor",
"file_id": 310,
"original_name": "data-processor.js",
"mime_type": "application/javascript",
"result": {
"language": "javascript",
"analysis": "El script original contenía variables no declaradas en el scope global, búsquedas anidadas ineficientes de complejidad cuadrática O(N^2) y falta de control de excepciones en llamadas asíncronas.",
"issues": [
{
"type": "performance",
"severity": "high",
"description": "Bucle con búsqueda recursiva Array.find() en cada iteración provocando cuello de botella de CPU.",
"line_reference": 18
},
{
"type": "security",
"severity": "medium",
"description": "Falta de sanitización en el parámetro de entrada antes de procesar los registros.",
"line_reference": 34
}
],
"refactored_code": "export async function processRecords(items = [], lookupMap = new Map()) {\n  if (!Array.isArray(items)) throw new TypeError('items must be an array');\n  \n  return items.map(item => ({\n    id: item.id,\n    name: String(item.name).trim(),\n    metadata: lookupMap.get(item.id) || null,\n    processedAt: new Date().toISOString()\n  }));\n}",
"improvements": [
"Optimización de complejidad temporal de O(N^2) a O(N) mediante Map lookup",
"Manejo defensivo de tipos y parámetros por defecto seguros",
"Migración estricta a sintaxis moderna ES Modules"
],
"time_complexity": "Original: O(N^2) -> Refactorizado: O(N)"
},
"ai_quota": {
"remaining_today": 46,
"daily_limit": 50
}
}
Respuesta JSON: task="summarize"
{
"status": true,
"code": 200,
"task": "summarize",
"file_id": 415,
"original_name": "reporte-optimizacion-web.pdf",
"mime_type": "application/pdf",
"result": {
"title": "Informe de Optimización y Entrega Global de Medios 2026",
"executive_summary": "Evaluación técnica de la adopción de arquitecturas de entrega rápida en el borde para activos digitales. La optimización redujo los tiempos de carga en un 68% y mejoró las tasas de conversión mediante compresión inteligente de imágenes y distribución Anycast.",
"key_takeaways": [
"Distribución de contenidos en el borde para mínima latencia.",
"Aceleración de carga de medios a través de nodos de presencia global.",
"Procesamiento inteligente de IA para catalogación automática.",
"Capacidad de almacenamiento escalable con alta redundancia."
],
"estimated_reading_time": 3,
"language": "es",
"keywords": [
"optimizacion",
"rendimiento web",
"latencia",
"entrega global",
"ia multimodal"
]
},
"ai_quota": {
"remaining_today": 45,
"daily_limit": 50
}
}
Respuesta JSON: task="palette"
{
"status": true,
"code": 200,
"task": "palette",
"file_id": 512,
"original_name": "branding-logo-dark.png",
"mime_type": "image/png",
"result": {
"dominant_palette": [
{
"hex": "#0a0e1a",
"name": "Deep Space Navy",
"percentage_approx": 48,
"role": "background"
},
{
"hex": "#3b82f6",
"name": "Electric Royal Blue",
"percentage_approx": 26,
"role": "primary"
},
{
"hex": "#8b5cf6",
"name": "Neon Violet",
"percentage_approx": 16,
"role": "accent"
},
{
"hex": "#f8fafc",
"name": "Pure Snow White",
"percentage_approx": 10,
"role": "secondary"
}
],
"color_harmony": "análoga / fría de alto contraste",
"aesthetic_style": "dark mode moderno / fintech futurista",
"accessibility_notes": "Excelente ratio de contraste (13.8:1) entre el fondo #0a0e1a y el texto #f8fafc, cumpliendo con la certificación WCAG AAA para legibilidad web."
},
"ai_quota": {
"remaining_today": 44,
"daily_limit": 50
}
}
Respuesta JSON: task="moderation"
{
"status": true,
"code": 200,
"task": "moderation",
"file_id": 618,
"original_name": "avatar-comunidad-usuario.jpg",
"mime_type": "image/jpeg",
"result": {
"is_safe": true,
"is_sensitive": false,
"nsfw_score": 0.02,
"categories": {
"adult": "unlikely",
"violence": "unlikely",
"racy": "unlikely"
},
"reason": "La imagen corresponde a un retrato fotográfico convencional en exteriores sin elementos sugerentes, armas ni violencia explícita."
},
"ai_quota": {
"remaining_today": 43,
"daily_limit": 50
}
}
Respuesta JSON: task="tags"
{
"status": true,
"code": 200,
"task": "tags",
"file_id": 720,
"original_name": "wallpaper-cyberpunk-city.webp",
"mime_type": "image/webp",
"result": {
"tags": [
"cyberpunk",
"cityscape",
"neon lights",
"futuristic",
"wallpaper 4k",
"night city",
"digital art",
"scifi",
"dark aesthetic",
"ciudad nocturna",
"luces de neon"
]
},
"ai_quota": {
"remaining_today": 42,
"daily_limit": 50
}
}
Respuesta JSON: task="custom"
{
"status": true,
"code": 200,
"task": "custom",
"file_id": 810,
"original_name": "database-schema.sql",
"mime_type": "text/plain",
"result": {
"output": "El esquema de base de datos analizado define adecuadamente 4 tablas relacionales con claves foráneas en cascada. Se recomienda agregar un índice compuesto en (usuario_id, fecha_registro) para optimizar las consultas analíticas y el filtrado temporal frecuente."
},
"ai_quota": {
"remaining_today": 41,
"daily_limit": 50
}
}
Respuestas de Error Estándar de la Suite de IA
// Error 400: Se intentó analizar una carpeta en lugar de un archivo individual
{
"status": false,
"code": 400,
"error": "Las funciones de IA y análisis profundo solo aplican para archivos individuales, no para carpetas.",
"supported_target": "file_id | file_uuid | storage_path"
}
// Error 400: Tarea incompatible con el tipo de archivo (ej. transcribe en imagen)
{
"status": false,
"code": 400,
"error": "La tarea 'transcribe' solo es compatible con archivos de audio o video (ej. MP3, WAV, OGG, MP4, WEBM). El archivo actual es de categoría 'image'."
}
// Error 401: Token de autenticación ausente o incorrecto
{
"status": false,
"code": 401,
"error": "Upload token inválido o no existe."
}
// Error 403: Cuenta suspendida o acceso restringido
{
"status": false,
"code": 403,
"error": "Tu acceso a la IA ha sido bloqueado."
}
// Error 404: El archivo solicitado no existe en tu cuenta
{
"status": false,
"code": 404,
"error": "Archivo no encontrado o no tienes permisos para acceder a él."
}
// Error 413: Archivo excede el límite de tamaño permitido para IA
{
"status": false,
"code": 413,
"error": "El archivo es demasiado pesado para el análisis de IA. El límite actual es de 10 MB."
}
// Error 429: Cuota diaria de peticiones de IA de tu plan agotada
{
"status": false,
"code": 429,
"error": "Has alcanzado el límite diario de peticiones de IA de tu plan.",
"details": {
"type": "user_limit_reached",
"current": 50,
"limit": 50,
"hours_until_reset": 6,
"plan": "lite",
"next_recommended_plan": "go"
}
}
// Error 500: Fallo temporal del motor de procesamiento de IA
{
"status": false,
"code": 500,
"error": "Error al procesar el archivo con el motor de IA.",
"message": "Todos los modelos de la suite de IA fallaron al procesar el archivo."
}
POST /api/cdn/ai/tag (Auto-Etiquetado Inteligente de Archivos)

Atajo directo para clasificar y generar entre 6 y 15 etiquetas semánticas y guardarlas automáticamente en los metadatos del archivo para acelerar la búsqueda indexada.

ParámetroTipoObligatorioDescripción
id / file_idIntegerCondicionalID del archivo individual en el CDN.
file_uuidStringCondicionalUUID del archivo (ej: "k9xL2pQ.jpg").
storage_pathStringCondicionalRuta en almacenamiento seguro (ej: "usuario/k9xL2pQ.jpg").
Node.js (Auto-Tagging)
const axios = require('axios');
async function autoTagFile(fileId) {
try {
const res = await axios.post('https://api.evogb.org/api/cdn/ai/tag', {
id: fileId
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("🏷️ Tags guardados:", res.data.result.tags);
console.log("📊 Cuota restante:", res.data.ai_quota.remaining_today);
} catch (error) {
console.error("❌ Error en auto-tag:", error.response?.data || error.message);
}
}
autoTagFile(108);
Python (Auto-Tagging)
import requests
res = requests.post('https://api.evogb.org/api/cdn/ai/tag',
json={'id': 108},
headers={'x-upload-token': 'TU_UPLOAD_TOKEN'}
)
if res.status_code == 200:
print("🏷️ Tags guardados:", res.json()['result']['tags'])
else:
print("❌ Error:", res.json())
Browser (Fetch)
fetch('https://api.evogb.org/api/cdn/ai/tag', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-upload-token': 'TU_UPLOAD_TOKEN'
},
body: JSON.stringify({ id: 108 })
})
.then(res => res.json())
.then(data => {
if (data.status) console.log("Tags:", data.result.tags);
else console.error("Error:", data.error);
});
cURL
curl -X POST "https://api.evogb.org/api/cdn/ai/tag" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "id": 108 }'
Ejemplo Respuesta JSON (/api/cdn/ai/tag)
{
"status": true,
"code": 200,
"task": "tags",
"file_id": 108,
"original_name": "paisaje-montana-4k.webp",
"mime_type": "image/webp",
"result": {
"tags": [
"paisaje",
"naturaleza",
"montañas",
"atardecer",
"wallpaper",
"outdoor",
"sunset",
"4k wallpaper",
"turismo"
]
},
"ai_quota": {
"remaining_today": 49,
"daily_limit": 50
}
}

Descripción de Propiedades de Respuesta (/api/cdn/ai/tag)

CampoTipoDescripción Técnica
statusBooleanIndica si el proceso de auto-etiquetado se ejecutó exitosamente (true / false).
codeIntegerCódigo de estado HTTP devuelto (ej: 200).
taskStringTipo de tarea de IA ejecutada ("tags").
file_idIntegerID numérico del archivo analizado y enriquecido.
original_nameStringNombre original del archivo procesado.
mime_typeStringTipo MIME validado del archivo.
result.tagsArray (Strings)Lista de etiquetas semánticas inferidas por el modelo neuronal y guardadas en la base de datos.
ai_quota.remaining_todayIntegerPeticiones de IA restantes disponibles para el día en curso.
ai_quota.daily_limitIntegerLímite máximo de peticiones de IA asignadas según el plan activo.
POST /api/cdn/ai/search (Búsqueda Semántica Inteligente de Archivos)

Permite buscar archivos y recursos mediante lenguaje natural. El motor escanea de forma simultánea los nombres de archivo, nombres de carpetas, formatos MIME y todas las etiquetas generadas previamente por la IA. No consume cuota diaria de IA (0 requests / Gratis) ya que opera sobre índices de búsqueda optimizados de tu cuenta.

ParámetroTipoObligatorioDescripción
queryStringREQTérmino, palabra clave o concepto a buscar (ej: "factura electronica pdf", "dark mode ui").
limitIntegerOpcionalCantidad máxima de resultados (1 a 100, por defecto: 30).
Node.js (Búsqueda Semántica)
const axios = require('axios');
async function searchCdn(queryText) {
try {
const res = await axios.post('https://api.evogb.org/api/cdn/ai/search', {
query: queryText,
limit: 20
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log(`🔍 Coincidencias encontradas: ${res.data.count}`);
res.data.results.forEach(file => {
console.log(`- [${file.id}] ${file.original_name} (${file.folder_name || 'Raíz'}) -> ${file.public_url}`);
console.log(`  Tags: ${file.tags.join(', ')}`);
});
} catch (err) {
console.error("❌ Error en búsqueda:", err.response?.data || err.message);
}
}
searchCdn('diseño dark mode');
Python (Búsqueda Semántica)
import requests
res = requests.post('https://api.evogb.org/api/cdn/ai/search', json={
'query': 'recibo factura pdf',
'limit': 10
}, headers={'x-upload-token': 'TU_UPLOAD_TOKEN'})
if res.status_code == 200:
data = res.json()
print(f"Total encontrados: {data['count']}")
for file in data['results']:
print(f"- {file['original_name']} | URL: {file['public_url']}")
else:
print("❌ Error:", res.json())
Browser (Fetch)
fetch('https://api.evogb.org/api/cdn/ai/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-upload-token': 'TU_UPLOAD_TOKEN'
},
body: JSON.stringify({
query: 'banner promocional',
limit: 15
})
})
.then(res => res.json())
.then(data => console.log(data.results));
cURL
curl -X POST "https://api.evogb.org/api/cdn/ai/search" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{ "query": "dashboard ui", "limit": 10 }'
Ejemplo Respuesta JSON (/api/cdn/ai/search)
{
"status": true,
"code": 200,
"query": "diseño dark mode",
"count": 2,
"results": [
{
"id": 108,
"file_uuid": "k9xL2pQ.png",
"original_name": "dashboard-preview.png",
"size_mb": 1.45,
"mime_type": "image/png",
"public_url": "https://cdn.evogb.org/k9xL2pQ.png",
"folder_id": 4,
"folder_name": "Assets UI",
"tags": [
"dashboard",
"dark mode",
"ui design",
"graficos",
"analytics"
],
"upload_date": "2026-08-15 18:30:22"
},
{
"id": 115,
"file_uuid": "v8mZ1aB.png",
"original_name": "hero-dark.png",
"size_mb": 2.10,
"mime_type": "image/png",
"public_url": "https://cdn.evogb.org/v8mZ1aB.png",
"folder_id": null,
"folder_name": null,
"tags": [
"hero banner",
"dark mode",
"fondo tecnologico"
],
"upload_date": "2026-08-14 11:20:10"
}
]
}

Descripción de Propiedades de Búsqueda Semántica

CampoTipoDescripción Técnica
statusBooleanIndica si la búsqueda se completó correctamente (true / false).
codeIntegerCódigo de estado HTTP devuelto (ej: 200).
queryStringTérmino o concepto semántico consultado.
countIntegerTotal de archivos encontrados que coincidieron con los criterios.
results[].idIntegerID numérico del archivo encontrado.
results[].file_uuidStringUUID o identificador único del archivo.
results[].original_nameStringNombre original del archivo.
results[].size_mbFloatPeso del archivo en Megabytes (MB).
results[].mime_typeStringTipo MIME validado del archivo.
results[].public_urlStringEnlace público directo HTTPS para consumir el recurso.
results[].folder_idInteger / nullID de la carpeta en la que está ubicado (o null para la raíz).
results[].folder_nameString / nullNombre legible de la carpeta contenedora.
results[].tagsArray (Strings)Etiquetas indexadas que activaron la coincidencia semántica.
results[].upload_dateStringFecha en la que fue subido el archivo.
POST /api/cdn/ai/chat (Chat Neuronal para Desarrolladores & Bots)

Permite integrar el asistente de inteligencia artificial conversacional directamente en tus aplicaciones, bots de Discord/WhatsApp/Telegram o scripts de terminal, autenticando fácilmente con tu x-upload-token.

ParámetroTipoObligatorioDescripción
messageStringREQMensaje, pregunta o instrucción enviada al modelo neuronal. Límite de caracteres adaptado a tu plan (hasta 10,000 chars en planes Pro/Ultra).
modelStringOpcionalIdentificador del modelo de IA a emplear (por defecto: "ai-evogb-pro"). Consulta la tabla inferior de modelos disponibles.
system_promptStringOpcionalInstrucción de sistema para definir el rol, tono o personalidad del asistente (ej: "Eres un arquitecto backend senior...").
historyArrayOpcionalHistorial previo de mensajes [{ role: 'user', content: '...' }, { role: 'assistant', content: '...' }] para mantener contexto continuo.

Catálogo de Modelos de Inteligencia Artificial Disponibles

Puedes elegir el modelo que mejor se adapte a tu caso de uso pasando su código en el parámetro model. Haz clic en el botón de copiar para copiar el identificador exacto:

Código del ModeloEspecialidad / PerfilVelocidadCasos de Uso Recomendados
ai-evogb-pro

⭐ Recomendado
Multimodal General
Equilibrio óptimo
Rápida (~350ms)Modelo estándar recomendado por defecto. Ideal para chatbots, asistentes de atención, extracción de datos, redacción y consultas generales.
ai-evogb-ultra
Razonamiento Profundo
Máxima potencia
Profunda (~750ms)Análisis arquitectónico de sistemas, resolución de problemas complejos de múltiples pasos, deducción científica y toma de decisiones crítica.
ai-evogb-titan
Alto Rendimiento
Procesamiento masivo
Balanceada (~500ms)Procesamiento y condensación de grandes volúmenes de texto, análisis de reportes corporativos y flujos de automatización pesados.
ai-evogb-core
Ultra Rápido
Mínima latencia
Instantánea (~180ms)Autocompletados en tiempo real, validación de formularios, clasificación de intención y microservicios de respuesta inmediata.
ai-evogb-logic-v1
Lógica & Algoritmos
Deducción paso a paso
Precisa (~650ms)Resolución de algoritmos, análisis de expresiones matemáticas, depuración lógica y demostraciones estructuradas.
ai-evogb-logic-v2
Analítica Avanzada
Modelado formal
Profunda (~700ms)Auditoría de consistencia en esquemas, análisis inferencial y validación rigurosa de condiciones lógicas complejas.
ai-evogb-agile-v1
Respuestas Directas
Sin rodeos
Muy Rápida (~220ms)Bots de comandos en Discord, WhatsApp, Telegram, scripts CLI y respuestas formateadas en JSON / Markdown limpio.
ai-evogb-agile-v2
Diálogo Interactivo
Flujo conversacional
Rápida (~280ms)Agentes conversacionales con memoria de contexto, asistentes de soporte técnico interactivo y roles personalizados.
ai-evogb-flash-v1
Latencia Crítica
Inferencia relámpago
Ultra Baja (~150ms)Sistemas de alta concurrencia, traducción en tiempo real, detección de idioma y respuestas síncronas.
ai-evogb-flash-v2
Inferencia Sintética
Alta eficiencia
Ultra Baja (~180ms)Generación de resúmenes de 1 línea, notificaciones automáticas push y moderación previa de textos.
ai-evogb-prime-v1
Redacción Creativa
Prosa enriquecida
Rápida (~400ms)Copywriting publicitario, redacción de correos profesionales, blogs, guiones para redes y narrativas estilizadas.
ai-evogb-prime-v2
Comprensión & Síntesis
Análisis de documentos
Balanceada (~450ms)Extracción de ideas principales, síntesis de minutas de reuniones y reestructuración de textos informativos.
ai-evogb-omega-v1
Contexto Extenso
Memoria de largo alcance
Moderada (~600ms)Análisis de manuales completos, flujos de conversación extensos con historial y extracción de múltiples variables interconectadas.
ai-evogb-omega-v2
Ingeniería & Código
Políglota técnico
Balanceada (~500ms)Generación, corrección y documentación de código en JavaScript, TypeScript, Python, Go, Rust, PHP, SQL, Shell, C++ y más.
ai-evogb-legacy
Compatibilidad
Flujos estándar
Estable (~450ms)Compatibilidad continua con integraciones y aplicaciones legacy configuradas previamente.
Node.js (Chat Neuronal con Modelo Específico)
const axios = require('axios');
async function askNeuralBot() {
try {
const res = await axios.post('https://api.evogb.org/api/cdn/ai/chat', {
message: '¿Cómo puedo estructurar un pipeline de compresión y subida por lotes en Node.js usando la API del CDN?',
model: 'ai-evogb-pro',
system_prompt: 'Eres un senior backend architect especializado en APIs cloud de alto rendimiento.'
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("🤖 Respuesta del Asistente:\n", res.data.response || res.data.message);
if (res.data.tokens_used) {
console.log("📊 Tokens Usados:", res.data.tokens_used);
}
} catch (err) {
console.error("❌ Error en chat:", err.response?.data || err.message);
}
}
askNeuralBot();
Python (Chat Neuronal)
import requests
res = requests.post('https://api.evogb.org/api/cdn/ai/chat', json={
'message': '¿Cuáles son las mejores prácticas para optimizar imágenes y videos antes de subirlos a la API?',
'model': 'ai-evogb-pro',
'system_prompt': 'Eres un experto en optimización web y entrega de medios.'
}, headers={'x-upload-token': 'TU_UPLOAD_TOKEN'})
if res.status_code == 200:
print("🤖 Respuesta:\n", res.json().get('response'))
else:
print("❌ Error:", res.json())
cURL
curl -X POST "https://api.evogb.org/api/cdn/ai/chat" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"message": "Hola, ¿cuáles son los límites de tamaño para el análisis de IA de imágenes en el CDN?",
"model": "ai-evogb-pro"
}'
Ejemplo Respuesta JSON (/api/cdn/ai/chat)
{
"status": true,
"code": 200,
"reply": "En el CDN de Evogb, los límites de tamaño para el análisis de IA son los siguientes:\n• Imágenes y Documentos: Hasta 10 MB.\n• Audios y Videos (Transcripción): Hasta 10 MB.\n• Archivos de Código (Auditoría): Hasta 3 MB.\n\nTodos los análisis se procesan directamente sobre tu almacenamiento seguro sin necesidad de exponer tus archivos públicamente.",
"response": "En el CDN de Evogb, los límites de tamaño para el análisis de IA son los siguientes:\n• Imágenes y Documentos: Hasta 10 MB.\n• Audios y Videos (Transcripción): Hasta 10 MB.\n• Archivos de Código (Auditoría): Hasta 3 MB.\n\nTodos los análisis se procesan directamente sobre tu almacenamiento seguro sin necesidad de exponer tus archivos públicamente.",
"used_model": "ai-evogb-pro",
"tokens": {
"prompt": 38,
"completion": 74,
"total": 112
}
}

Descripción de Propiedades de Respuesta (/api/cdn/ai/chat)

CampoTipoDescripción Técnica
statusBooleanIndica si la inferencia neuronal se completó de manera satisfactoria (true / false).
codeIntegerCódigo de estado HTTP de la respuesta (ej: 200).
replyStringTexto de respuesta generado por el modelo de IA seleccionado.
responseStringAlias compatible con el texto de respuesta generado.
used_modelStringIdentificador del modelo que procesó la respuesta (ej: "ai-evogb-pro").
tokens.promptIntegerCantidad de tokens computados a partir del mensaje y contexto enviados.
tokens.completionIntegerCantidad de tokens producidos en la respuesta generada.
tokens.totalIntegerTotal global de tokens computados durante la sesión de inferencia.

Operaciones Masivas & Respaldos

Comprime y descarga paquetes ZIP completos respetando las jerarquías de carpetas, o genera archivos comprimidos directamente en la nube.

POST /api/cdn/backup/generate (Descargar ZIP de Backup)

Genera en streaming continuo un archivo ZIP con todos los archivos y subcarpetas seleccionados para guardarlo directamente en tu disco local.

Parámetros (Body JSON)

ParámetroTipoObligatorioDescripción
modeStringREQ"selected" para IDs específicos o "folder" para comprimir toda una carpeta.
folderIdsArray (Integers)OpcionalIDs de las carpetas a incluir recursivamente en el archivo ZIP.
fileIdsArray (Integers)OpcionalIDs de archivos específicos sueltos para empaquetar.
Node.js (Guardar Backup ZIP en Disco)
const axios = require('axios');
const fs = require('fs');
async function downloadBackup() {
const response = await axios.post('https://api.evogb.org/api/cdn/backup/generate', {
mode: 'selected',
folderIds: [1, 2],
fileIds: [105, 108]
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' },
responseType: 'stream'
});
response.data.pipe(fs.createWriteStream('./backup_cdn.zip'));
console.log("✅ Descarga de backup iniciada.");
}
downloadBackup();
POST /api/cdn/compress (Comprimir en la Nube)

Empaqueta los archivos seleccionados en un .zip directamente en los servidores del CDN y lo almacena de forma permanente en tu cuenta, devolviendo la URL pública del archivo comprimido generado.

Parámetros (Body JSON)

ParámetroTipoObligatorioDescripción
folderIdsArray (Integers)OpcionalIDs de las carpetas que se deben empaquetar recursivamente.
fileIdsArray (Integers)OpcionalIDs de archivos individuales para comprimir en el ZIP.
Node.js (Axios)
const axios = require('axios');
const res = await axios.post('https://api.evogb.org/api/cdn/compress', {
folderIds: [1],
fileIds: [102, 103]
}, {
headers: { 'x-upload-token': 'TU_UPLOAD_TOKEN' }
});
console.log("🔗 URL del ZIP generado:", res.data.url);
Respuesta JSON (/api/cdn/compress)
{
"status": true,
"code": 200,
"url": "https://cdn.evogb.org/evogb_1771123456789.zip"
}

Descripción de Propiedades (/api/cdn/compress)

CampoTipoDescripción Técnica
statusBooleantrue si el archivo ZIP fue generado y almacenado en el CDN con éxito.
codeIntegerCódigo de estado HTTP devuelto (200).
urlStringEnlace HTTPS público directo para acceder y descargar el archivo comprimido.

Códigos de Error

La API utiliza códigos HTTP estrictos para indicar el éxito o fallo de una solicitud.

CódigoErrorCausa ProbableSolución
400Bad RequestToken de ejemplo o falta ID.Usa tu token real y verifica el Body.
401UnauthorizedToken faltante o incorrecto.Verifica el header x-upload-token.
403ForbiddenAlmacenamiento lleno o archivo ajeno.No puedes borrar archivos de otros usuarios.
404Not FoundID de archivo inexistente.El ID ingresado no existe en la base de datos.
413Payload Too LargeArchivo supera el peso máximo.Comprime el archivo o sube de plan.
415Unsupported Media TypeEl tipo de archivo no está permitido.Asegurarse de subir archivos según tú plan.
429Too Many RequestsLímite diario de operaciones.Espera a las 04:00 AM o mejora plan.
500Server ErrorFallo interno.Intenta de nuevo o contacta soporte.

Snippets & Ejemplos

Copia y pega estos ejemplos para integrar Evogb Cloud rápidamente en tus proyectos.

Configuración Previa (Node.js)

Recomendamos usar axios y form-data.

config.js
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const API_URL = 'https://api.evogb.org/api/cdn';
const TOKEN = 'TU_UPLOAD_TOKEN';
const api = axios.create({
baseURL: API_URL,
headers: { 'x-upload-token': TOKEN }
});
Subida de Archivos

Subida Básica

Node.js
async function uploadFile() {
try {
const form = new FormData();
form.append("file", fs.createReadStream("./gato.jpg"));
const res = await api.post("/upload", form, {
headers: {
...form.getHeaders(),
"x-upload-token": TOKEN,
},
});
console.log("✅ Subido:", res.data);
} catch (err) {
console.error("❌ Error:", err.response?.data || err.message);
}
}
uploadFile();

Subida Múltiple

Node.js (Múltiple)
async function uploadFiles() {
try {
const form = new FormData();
// 📁 Archivos locales
form.append('file', fs.createReadStream('./foto1.jpg'));
form.append('file', fs.createReadStream('./foto2.png'));
// 🌐 Archivo desde URL
form.append('url', 'https://i.imgur.com/ejemplo.jpg');
const res = await axios.post(`${API_URL}/upload`, form, {
headers: {
...form.getHeaders(),
'x-upload-token': TOKEN
}
});
console.log(`✅ ${res.data.count} archivos subidos`);
console.log(res.data);
} catch (err) {
console.error('❌ Error:', err.response?.data || err.message);
}
}
uploadFiles();

Subida desde URL

Node.js (URL Externa)
async function uploadUrl() {
try {
const form = new FormData();
form.append('url', 'https://i.imgur.com/ejemplo.jpg');
const res = await axios.post(`${API_URL}/upload`, form, {
headers: {
...form.getHeaders(),
'x-upload-token': TOKEN
}
});
console.log('✅ URL clonada correctamente');
console.log(res.data);
} catch (err) {
console.error('❌ Error:', err.response?.data || err.message);
}
}
uploadUrl();

Subida Premium (Privacidad)

Node.js (Params)
// Query Params: hide_user=true | hide_filename=true | custom_name=...
const uploadUrl = `${API_URL}/upload?hide_user=true&custom_name=banner_oficial`;
async function uploadPremium() {
try {
const form = new FormData();
form.append('url', 'https://i.imgur.com/ejemplo.jpg');
const res = await axios.post(uploadUrl, form, {
headers: {
...form.getHeaders(),
'x-upload-token': TOKEN
}
});
console.log('✅ Subida Premium desde URL:', res.data.url);
} catch (err) {
console.error('❌ Error:', err.response?.data || err.message);
}
}
uploadPremium();
Eliminar Archivo (Multi-Lenguaje)
Node.js (Axios)
async function deleteFile(fileId) {
try {
const response = await axios.post(`${API_URL}/delete`,
{ id: fileId },
{ headers: { 'x-upload-token': TOKEN } }
);
console.log('🗑️ Eliminado:', response.data.message);
} catch (error) {
console.error("Error:", error.message);
}
}
// deleteFile(152);
Browser (Fetch)
fetch('https://api.evogb.org/api/cdn/delete', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-upload-token': 'TU_TOKEN_AQUI'
},
body: JSON.stringify({ id: 152 })
})
.then(res => res.json())
.then(data => console.log(data));
Python (Requests)
import requests
url = "https://api.evogb.org/api/cdn/delete"
headers = {"x-upload-token": "TU_TOKEN_AQUI"}
payload = {"id": 152}
r = requests.post(url, json=payload, headers=headers)
print(f"Eliminado: {r.json().get('message')}")
PHP (cURL)
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.evogb.org/api/cdn/delete");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, [
"x-upload-token: TU_TOKEN_AQUI",
"Content-Type: application/json"
]);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode(["id" => 152]));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($ch);
curl_close($ch);
echo $response;
?>
Terminal (cURL)
curl -X POST "https://api.evogb.org/api/cdn/delete" \
-H "x-upload-token: TU_TOKEN_AQUI" \
-H "Content-Type: application/json" \
-d '{"id": 152}'
Consultas (Listar & Stats)
Listar Archivos (Node.js)
async function listFiles() {
const res = await axios.get(`${API_URL}/files`, {
headers: { 'x-upload-token': TOKEN }
});
// La API devuelve un Array directamente
console.log(`✅ Tienes ${res.data.length} archivos.`);
}
Obtener Stats (Node.js)
async function getStats() {
const res = await axios.get(`${API_URL}/stats`, {
headers: { 'x-upload-token': TOKEN }
});
const { usage, limits, plan } = res.data;
console.log(`📊 Plan: ${plan}`);
console.log(`💾 Uso: ${usage.storage_used_mb} / ${limits.storage_total_mb} MB`);
}
CDN IA Suite (Flujos & Pipelines Completos)

Recetas completas de código listas para producción combinando subida de medios, análisis con IA y procesamiento inteligente.

Receta 1: Subida + Auto-Tagging + OCR Automatizado (Node.js)

pipeline-ocr.js
const axios = require('axios');
const FormData = require('form-data');
const fs = require('fs');
const TOKEN = 'TU_UPLOAD_TOKEN';
const BASE_URL = 'https://api.evogb.org/api/cdn';
async function uploadAndProcessOcr(filePath) {
try {
// 1. Subir el archivo al CDN
const form = new FormData();
form.append('file', fs.createReadStream(filePath));
form.append('folder_path', 'documentos/ocr');
console.log('⏳ Subiendo archivo al CDN...');
const uploadRes = await axios.post(`${BASE_URL}/upload`, form, {
headers: {
...form.getHeaders(),
'x-upload-token': TOKEN
}
});
const uploadedFile = uploadRes.data.files ? uploadRes.data.files[0] : uploadRes.data;
console.log(`✅ Archivo subido con ID: ${uploadedFile.id} | URL: ${uploadedFile.public_url}`);
// 2. Extraer texto mediante OCR con la Suite de IA
console.log('🤖 Procesando OCR con modelo neuronal...');
const ocrRes = await axios.post(`${BASE_URL}/ai/analyze`, {
id: uploadedFile.id,
task: 'ocr',
save_tags: true
}, {
headers: { 'x-upload-token': TOKEN }
});
console.log('📄 Idioma Detectado:', ocrRes.data.result.detected_language);
console.log('📝 Texto Extraído:\n', ocrRes.data.result.text);
console.log(`📊 Cuota de IA restante: ${ocrRes.data.ai_quota.remaining_today}/${ocrRes.data.ai_quota.daily_limit}`);
} catch (error) {
console.error('❌ Error en el pipeline:', error.response?.data || error.message);
}
}
uploadAndProcessOcr('./factura_servicio.png');

Receta 2: Auditoría y Refactorización Automática de Código (Node.js)

code-reviewer.js
const axios = require('axios');
const fs = require('fs');
const TOKEN = 'TU_UPLOAD_TOKEN';
async function reviewAndRefactorCode(fileId) {
try {
console.log(`🔍 Analizando código fuente (ID: ${fileId})...`);
const res = await axios.post('https://api.evogb.org/api/cdn/ai/analyze', {
id: fileId,
task: 'code_refactor'
}, {
headers: { 'x-upload-token': TOKEN }
});
const { language, analysis, issues, refactored_code, improvements, time_complexity } = res.data.result;
console.log(`\n================== DIAGNÓSTICO (${language}) ==================`);
console.log(`Evaluación: ${analysis}`);
console.log(`Complejidad: ${time_complexity || 'Optimizada'}`);
console.log(`\nIssues Detectados (${issues.length}):`);
issues.forEach((issue, idx) => {
console.log(`  ${idx + 1}. [${issue.severity.toUpperCase()}] Línea ${issue.line_reference || 'N/A'}: ${issue.description}`);
});
console.log('\nMejoras Aplicadas:');
improvements.forEach(imp => console.log(`  • ${imp}`));
// Guardar el código optimizado localmente
fs.writeFileSync('./codigo_refactorizado.js', refactored_code, 'utf8');
console.log('\n💾 Código limpio guardado en: ./codigo_refactorizado.js');
} catch (err) {
console.error('❌ Error en revisión:', err.response?.data || err.message);
}
}
reviewAndRefactorCode(310);

Receta 3: Transcripción Automática de Voz / Podcasts (Python)

transcribe_audio.py
import requests
import json
TOKEN = "TU_UPLOAD_TOKEN"
API_URL = "https://api.evogb.org/api/cdn"
def transcribe_audio(file_id):
headers = {"x-upload-token": TOKEN, "Content-Type": "application/json"}
payload = {
"id": file_id,
"task": "transcribe"
}
print(f"🎙️ Enviando archivo {file_id} al motor de transcripción...")
response = requests.post(f"{API_URL}/ai/analyze", json=payload, headers=headers)
if response.status_code == 200:
data = response.json()
result = data.get("result", {})
print("\n✅ Transcripción Exitosa:")
print(f"• Idioma: {result.get('detected_language')}")
print(f"• Resumen: {result.get('summary')}")
print(f"• Temas Clave: {', '.join(result.get('key_topics', []))}")
print("\n--- TEXTO COMPLETO ---")
print(result.get("transcription"))
# Guardar en archivo
with open("transcripcion.txt", "w", encoding="utf-8") as f:
f.write(result.get("transcription", ""))
print("\n💾 Transcripción guardada en 'transcripcion.txt'")
else:
print(f"❌ Error {response.status_code}:", response.text)
transcribe_audio(205)

Receta 4: Buscador Inteligente en Tiempo Real (Frontend JavaScript)

smart-search.js (Frontend)
// Función de búsqueda semántica con debounce para inputs de búsqueda
let searchTimeout = null;
function onSearchInputChanged(query) {
clearTimeout(searchTimeout);
if (!query || query.trim().length < 2) return;
searchTimeout = setTimeout(async () => {
try {
const response = await fetch('https://api.evogb.org/api/cdn/ai/search', {
method: 'POST',
headers: {
'Content-Type': 'application/json',
'x-upload-token': 'TU_UPLOAD_TOKEN'
},
body: JSON.stringify({ query: query.trim(), limit: 10 })
});
const data = await response.json();
renderSearchResults(data.results);
} catch (err) {
console.error('Error buscando archivos:', err);
}
}, 300); // 300ms debounce
}
function renderSearchResults(files = []) {
const container = document.getElementById('search-results');
container.innerHTML = files.map(file => `
<div class="file-card">
<h4>${file.original_name}</h4>
<p>Carpeta: ${file.folder_name || 'Raíz'} | Tamaño: ${file.size_mb} MB</p>
<div class="tags">
${file.tags.map(t => `<span class="tag-badge">#${t}</span>`).join('')}
</div>
<a href="${file.public_url}" target="_blank" class="btn-link">Ver Archivo</a>
</div>
`).join('');
}

Sincronización en Tiempo Real (WebSockets)

El ecosistema de Evogb Cloud está impulsado por una arquitectura de eventos bidireccionales de baja latencia con Socket.IO. Cualquier modificación realizada mediante la API REST, bots, scripts o el panel web se propaga inmediatamente a todas las sesiones activas sin necesidad de peticiones repetitivas (polling).

Autenticación Segura de Sockets

Al establecer la conexión de WebSocket, el servidor autentica la sesión de forma segura y une al socket a su sala privada exclusiva cdn_<tu_email>. En el navegador se invoca socket.emit('join_cdn') tras la conexión exitosa.

Catálogo de Eventos del Servidor

EventoPayload (Datos)Descripción y Disparador
cdn_folder_created{ folder: Object }Emitido cuando se crea una nueva carpeta o ruta. Contiene id, name, color, parent_id y created_at.
cdn_folder_updated{ folder: Object }Emitido al editar el nombre, color o jerarquía padre de una carpeta existente.
cdn_folder_deleted{ folder_ids: Array, deleted_files_count: Number, freed_storage_mb: Number }Emitido al eliminar carpetas recursivamente. Detalla los IDs borrados y el espacio en MB liberado.
cdn_folder_moved{ folder_id: Number, parent_id: Number|null }Emitido al mover una carpeta dentro de otra o a la raíz.
cdn_file_created{ file: Object, size_mb: Number }Emitido únicamente al completar la subida y ensamblado final del archivo en el almacenamiento en la nube y base de datos.
cdn_file_deleted{ file_id: Number, size_mb: Number }Emitido al eliminar un archivo del almacenamiento. Notifica el peso liberado para actualizar cuotas en vivo.
cdn_file_moved{ file_id: Number, folder_id: Number|null }Emitido al reubicar un archivo en una carpeta específica o en la raíz.
cdn_public_toggled{ id: Number, is_public: Number }Emitido al alternar la visibilidad de un archivo entre privado y público (galería).
cdn_tags_updated{ id: Number, tags: Array }Emitido al agregar, actualizar o eliminar etiquetas (#tags) en un archivo.
cdn_stats_updated{ download_ops_daily: Number, upload_ops_daily: Number, storage_used_mb: Number }Emitido periódicamente al procesar descargas en segundo plano o al actualizar consumo de ancho de banda.
cdn_daily_reset{}Emitido automáticamente por el cron a medianoche (00:00) para reiniciar los contadores diarios de operaciones en vivo.

Ejemplo de Conexión y Escucha en Tiempo Real

Frontend Web (Socket.IO)
import { io } from "https://cdn.socket.io/4.7.2/socket.io.esm.min.js";
const socket = io("https://api.evogb.org", { withCredentials: true });
socket.on("connect", () => {
console.log("🟢 Conectado al bus de eventos de Evogb Cloud");
socket.emit("join_cdn");
});
// Escuchar nuevo archivo subido
socket.on("cdn_file_created", (data) => {
console.log("✨ Nuevo archivo recibido en vivo:", data.file.original_name);
console.log("🔗 URL:", data.file.public_url);
});
// Escuchar eliminación de archivo
socket.on("cdn_file_deleted", (data) => {
console.log(`🗑️ Archivo #${data.file_id} eliminado. Espacio liberado: ${data.size_mb} MB`);
});
// Escuchar actualización de consumo de descargas
socket.on("cdn_stats_updated", (data) => {
console.log("📊 Nuevas operaciones de descarga:", data.download_ops_daily);
});
Node.js Client
const { io } = require("socket.io-client");
const socket = io("https://api.evogb.org", {
extraHeaders: {
"x-upload-token": "TU_UPLOAD_TOKEN"
}
});
socket.on("connect", () => {
console.log("⚡ Bot / Worker conectado a Socket.IO");
socket.emit("join_cdn");
});
socket.on("cdn_folder_created", (data) => {
console.log("📁 Carpeta creada:", data.folder.name, "(ID:", data.folder.id, ")");
});
socket.on("cdn_daily_reset", () => {
console.log("🔄 Medianoche: Cuotas diarias restablecidas.");
});

Lógica de Integración

Recomendaciones para programar tu Bot o App basándose en las respuestas de la API.

Escenario Bot (429)

Tu bot sube memes y recibe error 429.

  • Diagnóstico: Superaste upload_ops_limit.
  • Acción Code: Pausar subidas o guardar en cola local.
  • Reintento: Programar a las 04:00 AM Hora Colombia

Disco Lleno (403)

Subes 10 archivos y el 9 falla con 403.

  • Diagnóstico: storage_total_mb alcanzado.
  • Acción Code: Detener loop. Llamar endpoint /delete.
  • No hacer: Reintentar inmediatamente (bucle infinito).

Ciclo de Vida y Escenarios

Cómo reacciona el sistema ante eventos críticos. Entender esto garantiza la alta disponibilidad de tus proyectos.

Downgrade (Premium a Free)

Si pasas de un plan alto (ej. 2GB) a Free (50MB):

  • Sobre Cuota: Entras en congelamiento. No puedes subir nada hasta liberar espacio.
  • Gracia (Días 1-7): Archivos viejos NO se borran. Tienes 7 días para descargar los archivos y hacer backups local si crees que no vas a renovar Plan.
  • Día 8: Se borran automáticamente archivos con antigüedad > 30 días.
  • Privacidad: Los enlaces viejos privados se mantienen, pero nuevas subidas serán según Tú Plan .

Límite Excedido (Bloqueo Visual)

Si tu cuenta supera el download_ops_limit o ancho de banda, el CDN deja de servir tus archivos y devuelve este SVG informativo en su lugar:

LÍMITE EXCEDIDOAncho de banda agotadoActualiza tu plan en Evogbapi.evogb.org

Recuperación

El bloqueo se levanta automáticamente a las 04:00 AM Hora Colombia o si mejoras a un plan superior (Business es ilimitado).

Error 403: Disco Lleno

Si alcanzas el storage_total_mb a mitad de una operación:

  • La subida falla. No reintentes inmediatamente.
  • Debes llamar a /api/cdn/delete o mejorar tu plan.

Token Comprometido

Si expones tu token en GitHub: Regenéralo inmediatamente en el Panel Cloud. El viejo dejará de funcionar al instante.

Dominios y Periodo de Gracia

Configuración de Dominio

Disponible en Plan Pro o superior. Se configura desde el Panel Cloud:

  1. Ingresa tu dominio (ej: cloud.marca.com).
  2. El sistema te dará un registro CNAME.
  3. Añádelo en tu proveedor DNS (Cloudflare: Proxy OFF/Gris).
  4. El sistema valida el SSL automáticamente y migra tus enlaces.

Periodo de Gracia

Si tu plan Premium vence:

  • Estado: Entras en Gracia por 7 días.
  • Archivos: NO se borran. Siguen accesibles.
  • Dominio: Sigue activo durante los 7 días.
  • Final: Si no renuevas al día 8, el dominio se desconecta y los archivos > 30 días se eliminan. Evita esto renovando tú Plan en la Tienda

Dominio Personalizado (Custom Domain)

Configura y sirve todos tus archivos multimedia desde tu propio dominio o subdominio de marca (por ejemplo: cdn.tuweb.com o media.tudominio.xyz). Cuenta con aprovisionamiento de certificados SSL/TLS automáticos y aceleración global a través de Cloudflare.

Dominio Personalizado

Configura tu propio dominio para servir archivos.

Pasos para la Configuración

1

Requisitos de Plan

La función de dominio propio está disponible en Planes Pro, Ultra y Business (o mediante el permiso granular allow_custom_domain en tu Upload Token). Si aún no cuentas con un plan compatible, puedes adquirirlo en la Tienda.

2

Ingresar tu Dominio en el Panel Cloud

Accede a Evogb Cloud, dirígete a la sección 🌐 Dominio Personalizado, escribe el subdominio o dominio que deseas usar (ejemplo: cdn.tuweb.com) y presiona Guardar.

3

Configurar el Registro DNS (CNAME)

En el panel de tu registrador de dominio o proveedor DNS (Cloudflare, Namecheap, GoDaddy, Hostinger, etc.), crea el siguiente registro:

Tipo Nombre (Host) Destino / Valor Modo Proxy
CNAME
cdn (o tu subdominio)
cdn.evogb.org
Solo DNS (Nube Gris)

Importante para usuarios de Cloudflare

Si administras tu dominio en Cloudflare, el registro CNAME debe configurarse obligatoriamente en "Solo DNS" (Nube Gris). Si activas el proxy (Nube Naranja), los retos de validación HTTP DV de Cloudflare for SaaS fallarán y no se podrá emitir el certificado SSL.

4

Emisión de SSL y Actualización de URLs en Tiempo Real

El sistema verifica automáticamente la propagación DNS y aprovisiona el certificado SSL/TLS.

Una vez que el dominio pasa al estado ACTIVO, el servidor emite una notificación vía WebSockets (cdn_domain_activated) y actualiza en tiempo real todas las URLs de tus archivos existentes y futuros en la base de datos y en la interfaz visual, aplicando una suave animación luminosa de confirmación en tus tarjetas de archivos.

Ciclo de Vida: Período de Gracia (7 Días) y Limpieza en Tiempo Real

Para salvaguardar tus integraciones en producción, Evogb Cloud opera con una política de protección activa:

  • Durante los 7 días de Gracia: Si tu plan expira, tu dominio personalizado continúa activo y entregando tráfico con normalidad. Ningún archivo ni enlace se rompe.
  • Si no renuevas tras los 7 días: El sistema ejecuta de forma automática una limpieza en tiempo real:
    • Se elimina el Custom Hostname y certificado SSL en Cloudflare.
    • Se remueve el registro del dominio en la base de datos (custom_domain = NULL).
    • Migración Automática de Enlaces: Todas las URLs de tus archivos se restauran suavemente al dominio oficial (https://cdn.evogb.org/...) garantizando que sigan siendo accesibles.
    • El panel web recibe el evento cdn_domain_deleted en tiempo real y actualiza la interfaz con transiciones visuales suaves sin necesidad de recargar la página.
  • Renovación: Si renuevas tu plan antes de que termine el plazo en la Tienda, el período de gracia se anula y tu dominio permanece 100% operativo sin interrupciones.

Gestión de Dominios vía API REST

Puedes automatizar el registro y desvinculación de dominios desde tus scripts o paneles usando peticiones HTTP autenticadas:

POST /api/cdn/domain (Vincular Dominio Propio)

Registra y solicita el aprovisionamiento SSL para un dominio propio.

cURL
curl -X POST "https://api.evogb.org/api/cdn/domain" \
-H "x-upload-token: TU_UPLOAD_TOKEN" \
-H "Content-Type: application/json" \
-d '{"domain": "cdn.tuweb.com"}'
DELETE /api/cdn/domain (Desvincular Dominio Propio)

Desvincula el dominio propio, elimina el certificado SSL y restaura las URLs de todos los archivos al dominio por defecto en tiempo real.

cURL
curl -X DELETE "https://api.evogb.org/api/cdn/domain" \
-H "x-upload-token: TU_UPLOAD_TOKEN"

Preguntas Frecuentes (FAQ)

¿Qué pasa si mi plan vence?

Si tu suscripción Premium (Plus+) finaliza, entras en un Periodo de Gracia de 7 días. Tus archivos NO se borran inmediatamente. Durante este tiempo, puedes acceder y descargar tus archivos, pero no subir nuevos (downgrade a Free). Si no renuevas tras esos 7 días, tu cuenta pasa a Free y se eliminarán los archivos con más de 30 días de antigüedad.

¿Por qué mi archivo tiene un nombre raro?

Si eres usuario Free o activaste "Ocultar Nombre", el sistema reemplaza el nombre original por un ID aleatorio (ej: a1b2c.png) para proteger la privacidad y evitar colisiones.

¿Cómo puedo cambiar el nombre de un archivo?

Lo ideal es que le pongas el nombre que gustes antes de subirlo, pero en caso de ya estar subido, en la web Evogb Cloud ve al archivo y presiona, va aparecer el panel lateral de detalles del archivo y tendrás una opción para modificar el nombre del archivo (Solo en planes premium).

¿Puedo subir archivos .exe o .zip?

En planes Plus, Pro, Ultra y Business sí: Permiten */* (Cualquier tipo de archivo), incluyendo binarios y comprimidos. En planes Free/Lite/Go/Basic, estás limitado a imágenes, PDF y multimedia básica.

¿Cómo configuro mi Dominio Propio?

  1. Ve al Panel Cloud > Dominio Personalizado (disponible en Pro+).
  2. Ingresa tu dominio (ej: cloud.miweb.com).
  3. En tu proveedor de dominio, crea un registro CNAME apuntando cloud.miweb.com a cloud.evogb.org.
  4. Espera la propagación DNS. Nuestro sistema se encargará de ajustar el resto.

¿Cómo manejo preferencias de URL?

En el Panel Cloud (Premium), usa switches para ocultar usuario/archivo. Se aplican en subidas nuevas una vez configurado.

¿Hotlinking y CORS?

¡Sí! Soportamos CORS (Access-Control-Allow-Origin: *). Puedes usar las URLs directamente en <img src>, Canvas, React o Bots sin bloqueos, siempre que respetes los límites de ancho de banda diarios.

¿Archivos con el mismo nombre?

Nunca sobrescribimos. Si subes foto.jpg dos veces, generamos IDs únicos: a1-foto.jpg y b2-foto.jpg. Ambos existen independientemente.

¿Archivos duplicados?

El sistema está diseñado para nunca sobrescribir archivos. Si subes foto.jpg dos veces, el sistema generará IDs únicos internos: 1. a8j9s-foto.jpg, 2. x2p4m-foto.jpg. Ambos archivos coexistirán y tendrán URLs diferentes.

¿Qué pasa si no envío parámetros de nombre?

El sistema aplica la lógica por defecto (Fail-safe):
1. Nombre: Usa el nombre original del archivo con un ID aleatorio al inicio (x9z-foto.jpg).
2. Carpeta: Usa tu configuración guardada en el Dashboard. Si no has configurado nada, muestra tu carpeta de usuario (/Usuario/x9z-foto.jpg).

¿Cómo obtengo el ID de un archivo?

Tienes dos opciones sencillas:
1. Modo Desarrollador: Haz una petición GET a /api/cdn/files. Recibirás un JSON con todos tus archivos y sus IDs.
2. Modo Visual (Panel): Entra a tu Dashboard (cloud.evogb.org), haz clic sobre la imagen que quieras y mira el panel lateral derecho; allí verás el ID junto a otros detalles.

¿Hay límite de velocidad de subida?

No imponemos un "Throttling" artificial de velocidad en ningún plan, pero dependemos de la conexión entre tu servidor y nuestros nodos. Para archivos grandes (+100MB), recomendamos usar una conexión estable o el método de stream (Node.js) para evitar timeouts HTTP. Pero en general tendrás una experiencia fluida.

¿Perderé mis archivos en mantenimiento?

No, tus archivos no se perderán porque estan en un lugar apartado e independiente de todos nuestros servicios así que puedes estar tranquilo/a, aunque el mantenimiento pueda hacer que nuestros servicios esten fuera de línea temporalmente, los enlaces de tus archivos seguirán funcionando con normalidad.

Migración y Actualizaciones

  • Usuarios Existentes: Si tu cuenta es antigua, el sistema migra automáticamente datos como cdn_prefs y typePlan.
  • Actualizaciones: El sistema verifica esquemas al inicio (Agrega datos si faltan). Contacta soporte si ves errores.
  • Mantenimiento: Limpiezas diarias a las 04:00 AM Hora Colombia. No afecta para archivos permanentes. Para más información consulta Tabla de Planes