
Una integración confiable de cómics de cuatro paneles necesita más de una solicitud de generación. El ciclo mínimo de producción es:
subir referencia del personaje -> crear cuatro paneles -> consultar estado terminal -> inspeccionar cada panel -> reparar solo el panel fallido
Este inicio rápido implementa ese ciclo en TypeScript. Mantiene la clave de API en el servidor, proporciona un registro estable del personaje, usa una clave de idempotencia para la solicitud de creación, registra el tiempo transcurrido y los fallos, y apunta a un solo panel cuando se rompe la continuidad.
Comienza con la API de Cómics de LlamaGen.AI, luego usa el ejemplo completo a continuación como base para una integración del lado del servidor.
Este artículo se verificó contractualmente con la documentación en vivo de la API de Cómics el 10 de octubre de 2026.
| Check | Comportamiento verificado |
|---|---|
| Autenticación | Token Bearer en cada solicitud |
| URL base de producción | https://api.llamagen.ai |
| Carga | POST /v1/comics/upload devuelve un fileUrl reutilizable |
| Creación | POST /v1/comics/generations acepta fixPanelNum: 4 y comicRoles |
| Estado | GET /v1/comics/generations/{generationId} devuelve estado y salida de paneles |
| Reparación | PATCH /v1/comics/generations/{generationId} puede regenerar un panel basado en índice cero |
| Uso | Las respuestas de creación y reparación exponen datos de uso para tus propios registros |
No inventamos un benchmark de latencia ni de tasa de éxito. Esos valores varían según la cuenta, la cola, la configuración del modelo y la entrada. El ejemplo registra tu tiempo transcurrido real, uso de la API, estado terminal y detalles de fallo para que puedas producir un benchmark defendible en tu propio entorno.
El prompt le dice al modelo qué sucede. La referencia del personaje le dice a quién le está sucediendo la historia.
Para un rol recurrente, mantén estables estos campos:
En este ejemplo, el rol es un mensajero con cabello corto y oscuro, un impermeable amarillo y un bolso mensajero rojo. Esos detalles son lo suficientemente compactos como para repetirlos y lo suficientemente distintivos como para auditarlos.

Usa Node.js 20 o una versión más reciente para que fetch, FormData y Blob estén disponibles. Mantén la clave en una variable de entorno solo del servidor.
export LLAMAGEN_API_KEY="your_server_side_key"
No expongas esta clave en un bundle de navegador, aplicación móvil, repositorio público o solicitud del lado del cliente. Si tu producto tiene un frontend, envía el resumen del usuario a tu propio backend y deja que ese backend llame a LlamaGen.AI.
El flujo de trabajo tiene cuatro operaciones de red:

Guarda lo siguiente como comic-quickstart.ts, coloca una imagen del personaje en ./courier-reference.png y ejecútalo desde tu entorno de servidor.
Un resumen de los últimos lanzamientos de funciones de LlamaGen, mejoras del producto, actualizaciones de diseño y correcciones importantes de errores.
import { basename } from "node:path";
import { readFile } from "node:fs/promises";
import { randomUUID } from "node:crypto";
const API_BASE = "https://api.llamagen.ai";
const API_KEY = process.env.LLAMAGEN_API_KEY;
if (!API_KEY) {
throw new Error("Set LLAMAGEN_API_KEY before running this script.");
}
type UploadResponse = {
code?: number;
fileUrl: string;
};
type Usage = {
total_comics?: number;
redraw_panels?: number;
amount?: number;
};
type Generation = {
id: string;
status: "LOADING" | "PROCESSED" | "FAILED" | "CANCELLED" | string;
usage?: Usage;
comics?: Array<{
page?: number;
panels?: Array<{
panel?: number;
image?: string;
assetUrl?: string;
caption?: string;
}>;
}>;
error?: unknown;
};
async function api<T>(path: string, init: RequestInit = {}): Promise<T> {
const response = await fetch(`${API_BASE}${path}`, {
...init,
headers: {
Authorization: `Bearer ${API_KEY}`,
...init.headers,
},
});
const text = await response.text();
const body = text ? JSON.parse(text) : null;
if (!response.ok) {
throw new Error(
`Comic API ${response.status}: ${JSON.stringify(body)}`,
);
}
return body as T;
}
async function uploadReference(filePath: string) {
const bytes = await readFile(filePath);
const form = new FormData();
form.set("file", new Blob([bytes]), basename(filePath));
return api<UploadResponse>("/v1/comics/upload", {
method: "POST",
body: form,
});
}
async function waitForGeneration(
generationId: string,
timeoutMs = 10 * 60_000,
) {
const startedAt = Date.now();
while (Date.now() - startedAt < timeoutMs) {
const job = await api<Generation>(
`/v1/comics/generations/${generationId}`,
);
console.log(
JSON.stringify({
generationId,
status: job.status,
elapsedMs: Date.now() - startedAt,
usage: job.usage,
}),
);
if (job.status === "PROCESSED") return job;
if (job.status === "FAILED" || job.status === "CANCELLED") {
throw new Error(
`Generation ended as ${job.status}: ${JSON.stringify(job.error)}`,
);
}
await new Promise((resolve) => setTimeout(resolve, 4_000));
}
throw new Error(`Generation ${generationId} timed out.`);
}
async function main() {
const startedAt = Date.now();
try {
const reference = await uploadReference("./courier-reference.png");
const created = await api<Generation>("/v1/comics/generations", {
method: "POST",
headers: {
"Content-Type": "application/json",
"Idempotency-Key": randomUUID(),
},
body: JSON.stringify({
prompt: [
"Create one four-panel comic page in a restrained cinematic manga style.",
"Panel 1: Ren enters a rain-soaked station and notices a golden key.",
"Panel 2: Close view as Ren lifts the key and studies it.",
"Panel 3: Ren runs toward an old locked service door.",
"Panel 4: Ren opens the door and warm light spills into the station.",
"Keep the same face, haircut, yellow jacket, and red messenger bag.",
"Leave clean space for later lettering.",
].join("\n"),
preset: "japanese_manga",
size: "1024x1024",
fixPanelNum: 4,
language: "en",
comicRoles: [
{
name: "Ren",
age: 22,
gender: "male",
dress: "yellow rain jacket, black trousers, red messenger bag",
image: reference.fileUrl,
},
],
}),
});
const firstPass = await waitForGeneration(created.id);
console.log("first_pass_complete", {
id: firstPass.id,
elapsedMs: Date.now() - startedAt,
usage: firstPass.usage,
pages: firstPass.comics?.length ?? 0,
});
// Example review result: panel 3 lost the red bag.
const repairQueued = await api<Generation>(
`/v1/comics/generations/${created.id}`,
{
method: "PATCH",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
page: 0,
panel: 2,
panelPrompt:
"Ren runs toward the service door. Preserve his exact face, short dark hair, yellow rain jacket, and visible red messenger bag.",
images: [reference.fileUrl],
}),
},
);
console.log("repair_queued", {
id: repairQueued.id,
usage: repairQueued.usage,
});
const repaired = await waitForGeneration(created.id);
console.log("workflow_complete", {
id: repaired.id,
totalElapsedMs: Date.now() - startedAt,
finalStatus: repaired.status,
});
} catch (error) {
console.error("comic_workflow_failed", {
elapsedMs: Date.now() - startedAt,
message: error instanceof Error ? error.message : String(error),
});
process.exitCode = 1;
}
}
await main();
Ejecútalo con:
npx tsx comic-quickstart.ts
El ejemplo registra intencionalmente objetos estructurados. En producción, envía los mismos campos a tu sistema de observabilidad e incluye tu propio identificador de solicitud o proyecto.
No apruebes una página porque se vea atractiva en tamaño miniatura. Audita cada panel según el bloqueo del personaje:
| Check | Condición para aprobar |
|---|---|
| Rostro | Misma edad, rasgos y proporciones |
| Cabello | Misma silueta, longitud y color |
| Vestuario | La chaqueta amarilla sigue siendo amarilla y conserva la misma confección |
| Accesorio | El bolso mensajero rojo sigue presente y correctamente ubicado |
| Secuencia | La llave, la puerta, el clima y la dirección del desplazamiento se mantienen continuos |
| Composición | Cada panel tiene una función narrativa distinta |
| Espacio para rotulación | Los rostros y las acciones esenciales no están bloqueados |
Trata esto como control de calidad legible por máquina si estás construyendo un pipeline más grande. Almacena una razón de aprobado/reprobado por panel, no solo una aprobación general de la página.
El prompt de reparación más rápido nombra tanto la nueva acción como los elementos que no pueden cambiar.
Reparación del panel 3:
Ren corre hacia la puerta de servicio.
Conserva su rostro exacto, cabello corto y oscuro, impermeable amarillo,
y el bolso mensajero rojo visible.
Mantén la estación lluviosa y el movimiento de izquierda a derecha.
Los índices de panel son de base cero, así que el tercer panel visible es panel: 2. El endpoint de actualización puede aceptar panelPrompt, images de referencia o una caption de reemplazo.

Esto importa a nivel operativo. Volver a generar los cuatro paneles puede introducir tres nuevos riesgos de continuidad mientras se corrige uno anterior. La reparación dirigida reduce la superficie de revisión.
Antes de lanzar la integración, agrega estos controles:
Para secuencias más largas, cambia de fixPanelNum a pagination.totalPages y pagination.panelsPerPage. No envíes ambos modos en una sola solicitud de creación.
Usa la API de Cómics cuando los cómics se generen dentro de tu propio producto, trabajo por lotes, herramienta educativa, pipeline de publicación o flujo de trabajo del cliente.
Usa el editor visual cuando un creador quiera explorar la historia de forma interactiva, comparar alternativas o dirigir artísticamente cada página a mano. Muchos equipos usan ambos: la API crea y registra la primera pasada repetible, mientras que el editor maneja revisiones excepcionales.
Si la estructura de tu historia todavía está cambiando, planifícala antes de crear paneles terminados. La siguiente guía, ¿Storyboard primero o paneles de cómic primero?, muestra cómo medir la diferencia de retrabajo.
Sí. Envía fixPanelNum: 4 para una solicitud de una sola página con cuatro paneles. Para varias páginas, usa el objeto pagination en su lugar.
Sube una imagen de referencia limpia, pasa su fileUrl devuelto en comicRoles[].image, mantén estables el nombre del rol y la descripción del vestuario, y audita cada panel devuelto antes de continuar la secuencia.
Sí. Envía una solicitud PATCH con los índices de página y panel de base cero más un nuevo panelPrompt, imágenes de referencia opcionales o caption.
Usa el comportamiento de idempotencia documentado por LlamaGen.AI para que los reintentos de red no creen trabajo duplicado accidentalmente. Usa una clave nueva solo cuando realmente quieras una nueva generación.
No. Muestra la instrumentación necesaria para capturar tus números reales. Publica latencia, uso y tasas de fallo solo después de ejecutar repetidamente la misma entrada en tu propia cuenta y registrar las condiciones.
Escrito por Jay y revisado técnicamente contra el contrato del endpoint en vivo por el equipo de contenido de LlamaGen.AI. El comportamiento del producto puede cambiar; la documentación enlazada es la fuente de verdad.
¿Listo para crear el flujo de trabajo? Abre la API de Cómics de LlamaGen.AI, crea una clave del lado del servidor y ejecuta el inicio rápido con tu propia referencia de personaje.
Popular creator tools
Go from comics and storyboards to stylized photos with LlamaGen.
© 2026 LlamaGen.Ai Todos los derechos reservados
Liderando el futuro de la generación de cómics con IA



