API de miniaturas

La API de miniaturas te permite crear, generar y gestionar miniaturas con IA de forma programática.

URL base

https://youthumb.ai/api/thumbnails

Resumen de endpoints

MétodoEndpointDescripción
POST/thumbnailsCrear un nuevo proyecto de miniatura
POST/thumbnails/:projectId/startIniciar la generación
GET/thumbnails/:projectId/statusObtener el estado de la generación
GET/thumbnails/:projectId/detailed-statusObtener el estado detallado con las imágenes

POST /thumbnails

Crea un nuevo proyecto de miniatura.
bash
curl -X POST https://youthumb.ai/api/thumbnails \
  -H "x-api-key: your_api_key" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Excited creator with bright yellow background",
    "presetKey": "mrbeast-viral"
  }'

Cuerpo de la solicitud

ParámetroTipoObligatorioDescripción
promptstringSíDescripción de la miniatura (3-2000 caracteres)
personIduuidNoID de la persona para el intercambio de rostro
personNamestringNoNombre de la persona (alternativa a personId)
presetKeystringNoPreset de estilo (ver Presets)
templateIduuidNoID de plantilla como referencia de estilo
styleReferenceUrlurlNoURL de una imagen externa como referencia de estilo
youtubeUrlurlNoURL de YouTube de la que extraer la miniatura
contentImagesarrayNoImágenes adicionales (máx. 6)
titlestringNoTexto superpuesto (máx. 200 caracteres)
projectNamestringNoNombre del proyecto (máx. 100 caracteres)
advancedOptionsobjectNoOpciones avanzadas de generación

Opciones avanzadas

OpciónTipoValores
variationsnumber1, 2, 3, 4
faceExpressionstringneutral, happy, surprised, excited, serious, confident, keep-original
textPositionstringtop, center, bottom, none, keep-original
negativePromptstringLo que se debe evitar (máx. 500 caracteres)
clothingStylestringcasual, professional, sporty, elegant, streetwear, keep-original
faceEnhancementstringsubtle, normal, enhanced, keep-original
backgroundBlurnumber0 - 100

Respuesta 201 Created

json
{
  "success": true,
  "data": {
    "projectId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "draft",
    "projectName": "Untitled Project",
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
}

POST /thumbnails/:projectId/start

Inicia el proceso de generación con IA. Esto consume créditos.
bash
curl -X POST https://youthumb.ai/api/thumbnails/:projectId/start \
  -H "x-api-key: your_api_key"

Opciones de sobrescritura

Sobrescribe opciones al iniciar:
json
{
  "prompt": "Override the original prompt",
  "advancedOptions": {
    "variations": 4
  }
}

Respuesta correcta 200 OK

json
{
  "success": true,
  "data": {
    "projectId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "processing",
    "creditsConsumed": 1,
    "message": "Generation started"
  }
}

Respuesta de error 402 Payment Required

json
{
  "success": false,
  "error": "Insufficient credits"
}

GET /thumbnails/:projectId/status

Obtiene el estado del proyecto y sus trabajos. Admite paginación y filtrado por estado opcionales.
bash
# Básico (devuelve todos los trabajos, compatible con versiones anteriores)
curl https://youthumb.ai/api/thumbnails/:projectId/status \
  -H "x-api-key: your_api_key"

# Con paginación
curl "https://youthumb.ai/api/thumbnails/:projectId/status?page=1&limit=20" \
  -H "x-api-key: your_api_key"

# Con filtro de estado
curl "https://youthumb.ai/api/thumbnails/:projectId/status?status=completed&page=1&limit=10" \
  -H "x-api-key: your_api_key"

# Filtro de varios estados
curl "https://youthumb.ai/api/thumbnails/:projectId/status?status=pending,processing" \
  -H "x-api-key: your_api_key"

Parámetros de consulta

ParámetroTipoPor defectoDescripción
pagenumber1Número de página (empieza en 1)
limitnumber20Elementos por página (máx. 100)
statusstring—Filtrar por estado del trabajo. Separados por comas para varios: pending,processing
Nota: sin page ni limit, se devuelven todos los trabajos sin paginación (comportamiento compatible con versiones anteriores).

Respuesta (sin paginación)

json
{
  "success": true,
  "data": {
    "projectId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "processing",
    "projectName": "My Thumbnail",
    "jobs": [
      {
        "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "status": "completed",
        "generatedFileUrl": "https://storage.youthumb.ai/thumbnails/result.png",
        "createdAt": "2024-01-15T10:31:00.000Z"
      }
    ]
  }
}

Respuesta (con paginación)

json
{
  "success": true,
  "data": {
    "projectId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "status": "processing",
    "projectName": "My Thumbnail",
    "jobs": [
      {
        "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "status": "completed",
        "generatedFileUrl": "https://storage.youthumb.ai/thumbnails/result.png",
        "createdAt": "2024-01-15T10:31:00.000Z"
      }
    ],
    "pagination": {
      "total": 42,
      "page": 1,
      "limit": 20,
      "totalPages": 3
    }
  }
}

Valores de estado

EstadoDescripción
draftProyecto creado, sin iniciar
processingGeneración en curso
completedTodos los trabajos completados
failedLa generación falló

GET /thumbnails/:projectId/detailed-status

Obtiene el estado detallado con todas las imágenes generadas.
bash
curl https://youthumb.ai/api/thumbnails/:projectId/detailed-status \
  -H "x-api-key: your_api_key"

Respuesta detallada

json
{
  "success": true,
  "data": {
    "projectId": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
    "projectName": "My Thumbnail",
    "status": "completed",
    "summary": {
      "totalJobs": 1,
      "activeJobs": 0,
      "completedJobs": 1,
      "failedJobs": 0,
      "totalVariations": 4
    },
    "latestGeneratedFileUrl": "https://storage.youthumb.ai/thumbnails/result.png",
    "jobs": [
      {
        "jobId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
        "status": "completed",
        "type": "thumbnail-generation",
        "userPrompt": "Excited creator with yellow background",
        "generatedFileUrl": "https://storage.youthumb.ai/thumbnails/result.png",
        "images": {
          "styleReference": [],
          "content": [],
          "faces": [
            {
              "id": "face-001",
              "url": "https://storage.youthumb.ai/faces/face.jpg",
              "name": "face.jpg"
            }
          ],
          "results": [
            {
              "id": "result-001",
              "url": "https://storage.youthumb.ai/results/var1.png",
              "width": 1280,
              "height": 720
            },
            {
              "id": "result-002",
              "url": "https://storage.youthumb.ai/results/var2.png",
              "width": 1280,
              "height": 720
            }
          ]
        },
        "personIds": ["b2c3d4e5-f6a7-8901-bcde-f12345678901"],
        "createdAt": "2024-01-15T10:31:00.000Z"
      }
    ],
    "createdAt": "2024-01-15T10:30:00.000Z"
  }
}

Ejemplo de flujo completo

javascript
const API = 'https://youthumb.ai/api';
const headers = {
  'x-api-key': process.env.YOUTHUMB_API_KEY,
  'Content-Type': 'application/json',
};

// 1. POST - Crear el proyecto
const create = await fetch(`${API}/thumbnails`, {
  method: 'POST',
  headers,
  body: JSON.stringify({
    prompt: 'Excited tech reviewer with product',
    presetKey: 'tech-review',
    advancedOptions: { variations: 2 }
  }),
});
const { data: project } = await create.json();

// 2. POST - Iniciar la generación
await fetch(`${API}/thumbnails/${project.projectId}/start`, {
  method: 'POST',
  headers: { 'x-api-key': process.env.YOUTHUMB_API_KEY },
});

// 3. GET - Consultar el estado
let status = 'processing';
while (status === 'processing') {
  await new Promise(r => setTimeout(r, 3000));

  const res = await fetch(`${API}/thumbnails/${project.projectId}/status`, {
    headers: { 'x-api-key': process.env.YOUTHUMB_API_KEY },
  });
  const data = await res.json();
  status = data.data.status;
}

// 4. GET - Obtener los resultados
const results = await fetch(
  `${API}/thumbnails/${project.projectId}/detailed-status`,
  { headers: { 'x-api-key': process.env.YOUTHUMB_API_KEY } }
);
const { data: final } = await results.json();

console.log('Generated images:', final.jobs[0].images.results);

Biblioteca, favoritos y papelera

Busca proyectos existentes antes de crear otra miniatura. GET /api/thumbnails y list_thumbnail_projects aceptan search, status, favorite y deleted. Las listas usan page (desde 1) y limit (1–100, 20 por defecto); los filtros se aplican antes de paginar. favorite=false selecciona los no favoritos y deleted=true los proyectos en la papelera. Los favoritos se comparten en la organización seleccionada. Envía {"isFavorite":true} o {"isFavorite":false} explícitamente: repetir la petición no alterna el estado. Renombra con {"projectName":"Nuevo título"}. Gestionar la biblioteca no consume créditos. Las lecturas MCP requieren mcp:read y acceso Lectura; las mutaciones requieren mcp:generate y acceso Generación, además de los permisos normales. Solo los administradores pueden enviar un proyecto completo a la papelera. Las listas normales y el detalle ocultan los jobs eliminados y los proyectos padres eliminados. list_generations devuelve resultados completados de proyectos de miniaturas visibles, con todas las imágenes de variaciones en el array results de cada job. La papelera acepta kind=projects o kind=jobs (jobs eliminados individualmente, incluso bajo padres eliminados). No hay eliminación permanente. Restaura primero el proyecto y después sus jobs eliminados individualmente. Restaurar un proyecto establece su estado en completed sin restaurar sus hijos. El deletedAt del proyecto deriva de updatedAt; no es un historial inmutable de eliminación. Cada job tiene su propio deletedAt almacenado. Repetir una eliminación/restauración ya realizada conserva las fechas. No se pueden eliminar jobs activos ni proyectos con jobs activos (409). Restaurar un job bajo un padre eliminado también devuelve 409. Las peticiones inválidas devuelven 400, permisos insuficientes 403, e identificadores desconocidos o de otra organización 404. GET /api/thumbnails/:projectId, /detailed-status, /status y get_generation comparten el detalle: metadatos del proyecto, isFavorite, resumen global, último resultado, metadatos de jobs, imágenes agrupadas e IDs de personas. Se conservan jobs[].results y activeJobs. Sin opciones se devuelven todos los jobs visibles; page o limit activa páginas limitadas. status solo (valores separados por comas) filtra todos los jobs visibles sin paginarlos, conservando el comportamiento anterior. El resumen y el último resultado siempre abarcan el proyecto visible completo.
RESTMCPParameters
GET /api/thumbnailslist_thumbnail_projectspage, limit, search, status, favorite, deleted
GET /api/thumbnails/:projectIdget_generationsummary?, page?, limit?, status?
PATCH /api/thumbnails/:projectIdupdate_thumbnail_projectprojectName
GET /api/thumbnails/resultslist_generationspage, limit, favorite, projectId
PUT /api/thumbnails/:projectId/favoriteset_project_favoriteisFavorite
PUT /api/thumbnails/jobs/:jobId/favoriteset_generation_favoriteisFavorite
DELETE /api/thumbnails/:projectIdtrash_thumbnail_projectprojectId
POST /api/thumbnails/:projectId/restorerestore_thumbnail_projectprojectId
DELETE /api/thumbnails/jobs/:jobIdtrash_generationjobId
POST /api/thumbnails/jobs/:jobId/restorerestore_generationjobId
GET /api/thumbnails/trashlist_trashkind=projects / jobs, page, limit
json
{"favorite":true,"page":1,"limit":20}

Intentos, iteración y reintento

POST /api/thumbnails/:projectId/start y start_generation conservan el proyecto. Opciones: prompt, personId (null elimina), presetKey, templateId, styleReferenceUrl, youtubeUrl, sourceResultId, contentImages ([] elimina), title ("" elimina) y advancedOptions. Los campos omitidos conservan los valores del proyecto; las opciones se combinan. Solo cambia este intento, no el proyecto guardado. Indica una sola fuente (preset, plantilla, URL, YouTube o resultado). Cada imagen contiene exactamente un userImageId o url; las URL explícitas deben pertenecer a tu ruta de almacenamiento configurada. Sube primero las imágenes externas. Obtén jobs[].results[].id del detalle del proyecto y úsalo como sourceResultId para iterar sobre esa imagen exacta. Debe proceder de un trabajo terminado y visible del mismo proyecto. Una referencia selecciona generación normal; un preset, generación mágica. Se rechazan proyectos y resultados eliminados.
json
{"projectId":"<project-id>","sourceResultId":"<result-image-id>","prompt":"Conserva la composición y aclara el fondo","advancedOptions":{"variations":1}}
POST /api/thumbnails/jobs/:jobId/retry / retry_generation({jobId}) acepta solo trabajos Default fallidos. Crea un nuevo intento facturado en el mismo proyecto con el prompt, imágenes de entrada, personas, título, preset y opciones originales. No reinicia el trabajo fallido ni usa los valores actuales del proyecto. Registra retryOfJobId. Cada llamada vuelve a consumir créditos: no es idempotente. Devuelve jobId, projectId, status, creditsConsumed tras confirmar el lanzamiento. Un fallo síncrono reembolsa y marca el trabajo huérfano como fallido.

Ayuda con el prompt

POST /api/thumbnails/prompts/improve / improve_prompt: prompt y context opcional con axes (composition, hook, readability), language (fr, en, es), personName, title, customInstruction, hasStyleReference, referenceTokens (@image1...), sketchTokens (@sketch1...). POST /api/thumbnails/prompts/from-reference / prompt_from_reference: una sola fuente entre assetId, templateId publicado o privado creado por ti, projectId + sourceResultId, o imageUrl cuya pertenencia a las subidas del usuario esté verificada. language opcional, en por defecto. No acepta URL arbitrarias: sube primero la imagen. Las referencias se autorizan en la organización seleccionada antes del cobro. Ambos devuelven {prompt, creditsConsumed: 0.5} sin crear un proyecto ni una imagen. Un error del proveedor reembolsa una vez. MCP exige mcp:generate y generación habilitada. El límite diario contabiliza medios créditos exactos; cambiar de herramienta no elude el límite. Los límites enteros existentes conservan su significado.

Exploración compacta y contadores explícitos

Para explorar o consultar el progreso, usa get_generation({projectId, summary:true, page:1, limit:5}) o GET /api/thumbnails/:projectId?summary=true&page=1&limit=5. summary=true aplica página 1 y límite 20 por defecto (1–100); status admite estados separados por comas. La respuesta contiene projectId, projectName, status, isFavorite, el summary global del proyecto, pagination y jobs con solo jobId, status, type, isFavorite, userPrompt, generatedFileUrl, createdAt. Omite metadatos, imágenes incrustadas y personas. Conserva los prompts completos: no garantiza un tamaño máximo en bytes. Sigue pagination.hasMore. Para obtener IDs de imágenes para sourceResultId, solicita una página detallada acotada con summary:false. Sin summary, o con false, se conserva el contrato detallado anterior, incluidas las lecturas sin límite con solo status. list_generations / GET /api/thumbnails/results incluye el userPrompt completo (o null) por job, sin consultar el detalle. get_credits / GET /api/usage añade counts.activeGenerationProjects (proyectos no eliminados, todos los tipos) y counts.completedThumbnailJobs (jobs completados no eliminados en proyectos de miniaturas visibles, mismo alcance que list_generations sin filtros). Son contadores de la organización: proyectos y jobs, no imágenes ni créditos consumidos. Las estadísticas anteriores generations siguen contando proyectos; generations.total equivale a counts.activeGenerationProjects. Los créditos y contadores anteriores no cambian. Los favoritos de proyecto (generation_project), job (generation_job) y archivo bucket personal son independientes. list_thumbnail_projects({favorite:true}) puede devolver cero aunque existan muchos jobs favoritos: no selecciona proyectos solo por contener un job favorito. Si faltan los parámetros summary, page, limit o search de assets, actualiza/reconecta el cliente MCP y recarga su lista de herramientas. Actualizar únicamente el skill no renueva los esquemas almacenados en caché.