Communitygithub.com

CheaperGen/skills

Genera videos e imágenes con IA utilizando la API de Cheaper Gen. (cheapergen.com), que ejecuta los modelos oficiales de ByteDance Seedance y Seedream, Alibaba Wan y MiniMax por debajo de sus precios oficiales. Úsalo cuando el usuario quiera crear un video o imagen con estos modelos, agregar texto a video, imagen a video, referencia a video, texto a imagen o edición de imágenes a código, o trabajar con una CHEAPERGEN_API_KEY o clave cg_live_. Incluye selección de modelo, cotización de precio, envío, sondeos o webhooks, menciones de referencia estilo @Image1, cargas, facturación y errores.

¿Qué es skills?

Esta skill proporciona acceso a una API REST unificada para generar videos e imágenes utilizando modelos de IA de vanguardia como Seedance, Seedream, Wan y MiniMax, ofreciendo precios más bajos que los oficiales. Es compatible con múltiples modos de generación: texto a video, imagen a video, edición de imágenes y referencias a video, audio e imágenes mediante menciones como @Image1. La skill maneja todo el flujo de trabajo: selección de modelo, cotización de precios, envío de trabajos, sondeo de resultados, webhooks con verificación HMAC, carga de archivos locales, facturación por saldo prepago y gestión de errores. Se integra de forma nativa con servidores MCP para una experiencia más fluida, permitiendo usar herramientas como list_models, generate con protección de presupuesto y add_credits para recargar saldo. Está diseñada para Claude Code, Cursor, Codex y otros agentes de IA que necesiten generar contenido multimedia de alta calidad mediante una API simple y económica.

Compatible con✓Claude Code~Codex CLI~Cursor
npx skills add https://github.com/CheaperGen/skills/tree/HEAD/skills/cheapergen

Preguntar en tu IA favorita

Abre un nuevo chat con esta habilidad de agente ya precargada.

Documentación

API de Cheaper Gen.

Una API REST asíncrona para modelos oficiales de video e imagen. La facturación se realiza a través de un saldo USD prepago: pagas por segundo de video o por imagen, y las generaciones fallidas se reembolsan automáticamente.

  • URL base: https://cheapergen.com/api/v1
  • Autenticación: Authorization: Bearer $CHEAPERGEN_API_KEY (las claves comienzan con cg_live_; crea una en https://cheapergen.com/dashboard/keys). Lee la clave del entorno. Nunca la imprimas, la registres ni la confirmes.
  • Prefiere el servidor MCP cuando esté conectado. Sus herramientas son list_models, get_model, quote, generate (con wait_seconds y una protección de presupuesto max_cost_usd), get_generation, get_account y add_credits (un enlace de pago que el usuario abre cuando el saldo es bajo); úsalas en lugar de llamadas HTTP. El flujo de trabajo a continuación es el mismo. Para conectarlo, agrega el servidor remoto https://cheapergen.com/api/mcp; el usuario inicia sesión y aprueba en el navegador (OAuth), sin necesidad de clave. En Claude Code: claude mcp add --transport http cheapergen https://cheapergen.com/api/mcp, luego /mcp → Autenticarse. Configuración completa: https://cheapergen.com/docs/mcp

Flujo de trabajo

  1. Elige un modelo: GET /models (público). Devuelve cada modelo con endpoints[].id y niveles de precio. Usa siempre la lista en vivo; los modelos cambian.
    • Video: Seedance 2.0 (mejor calidad, 4K, audio sincronizado), Seedance 2.0 Fast / Mini (más barato y rápido), Seedance 2.5 (más nuevo, referencias más largas), Wan 3.0 / Prime (Alibaba), MiniMax H3 / H3 Max.
    • Imagen: Seedream 5.0 Pro / Lite / Flash (texto a imagen y edit).
    • Los IDs de endpoints son {vendor}/{model}/{mode}, p. ej., bytedance/seedance-2.0-fast/text-to-video, bytedance/seedream-5.0-lite/text-to-image.
  2. Lee el esquema de entrada: GET /models/{vendor}/{model} (público) devuelve endpoints[].input_schema (JSON Schema con enumerados, valores predeterminados y límites) y pricing.tiers. Envía solo campos del esquema: los campos desconocidos se rechazan con 400.
  3. Cotiza: POST /quote/{endpoint} con la entrada (público, gratuito) devuelve { amount_usd, list_usd, discount_pct, available }. Antes de un trabajo costoso (video a 1080p/4K, duraciones largas, lotes), informa al usuario del precio.
  4. Envía: POST /run/{endpoint} con la entrada como cuerpo JSON devuelve 202 y una generación con status: "queued". El precio se retiene del saldo en este punto.
  5. Espera: sondea GET /generations/{id} hasta que status sea succeeded, failed o canceled. Sondea imágenes cada 1–2 s; sondea video cada 3–5 s, aumentando a 10 s, ya que un clip de 5 s suele tardar de 1 a 3 minutos. O pasa webhook_url (ver más abajo).
  6. Usa la salida: output.video.url (video) o output.images[].url (imágenes). Las URLs son públicas pero caducan según la retención de la cuenta (predeterminado 1 día; ver expires_at), así que descarga cualquier cosa que valga la pena conservar.
curl -s https://cheapergen.com/api/v1/run/bytedance/seedance-2.0-fast/text-to-video \
  -H "Authorization: Bearer $CHEAPERGEN_API_KEY" -H "Content-Type: application/json" \
  -d '{"prompt":"Un barco de papel a la deriva por una calle lluviosa y neón, lento dolly-in","resolution":"720p","duration":5,"aspect_ratio":"16:9"}'
# → 202 {"id":"gen_…","status":"queued","cost":{"amount_usd":…,"estimated":true},…}
curl -s https://cheapergen.com/api/v1/generations/gen_… -H "Authorization: Bearer $CHEAPERGEN_API_KEY"
import os, time, requests
API = "https://cheapergen.com/api/v1"
H = {"Authorization": f"Bearer {os.environ['CHEAPERGEN_API_KEY']}"}

def generate(endpoint: str, inp: dict, timeout_s: int = 900) -> dict:
    r = requests.post(f"{API}/run/{endpoint}", json=inp, headers=H, timeout=60)
    r.raise_for_status()  # Cuerpos 4xx: {"error": {"code", "message", "param"}
    gen, delay, start = r.json(), 2.0, time.time()
    while gen["status"] in ("queued", "running"):
        if time.time() - start > timeout_s:
            raise TimeoutError(gen["id"])
        time.sleep(delay)
        delay = min(delay * 1.5, 10)
        r = requests.get(f"{API}/generations/{gen['id']}", headers=H, timeout=30)
        if r.status_code == 429 or r.status_code >= 500:
            continue  # transitorio: seguir sondeando
        r.raise_for_status()
        gen = r.json()
    if gen["status"] != "succeeded":
        raise RuntimeError(gen["error"])  # la retención fue reembolsada
    return gen  # gen["output"]["video"]["url"] o gen["output"]["images"][0]["url"]

Modos y entradas

  • text-to-video y text-to-image: toman prompt más opciones (resolution, duration, aspect_ratio, size, seed, generate_audio…). Consulta el esquema para los enumerados de cada modelo.
  • image-to-video: toma image_url (primer fotograma) y, para algunos modelos, end_image_url (último fotograma).
  • edit (Seedream): image_urls (imágenes a editar o combinar; refiérete a ellas como "imagen 1", "imagen 2" en el prompt) más la instrucción en prompt.
  • reference-to-video: toma reference_image_urls, reference_video_urls y reference_audio_urls. En el prompt, apunta a ellas por posición basada en 1: @Image1, @Image2, @Video1, @Audio1 (no distingue mayúsculas). Una mención sin una referencia coincidente da un 400 con param: "prompt". Ejemplo: "@Image1 camina por el mercado desde @Image2, la cámara se mueve como @Video1".
    • reference_rules en el esquema establece el número máximo de archivos y si necesitas al menos una imagen o video (el audio solo no es suficiente para Seedance y H3).
    • Los videos de referencia y el audio se miden en el servidor (duración, tamaño, resolución, fps) según media_limits / x-media-limits. Seedance 2.0 toma videos MP4/MOV de 2–15 s cada uno y 15 s en total; el audio debe ser MP3/WAV. Una infracción da un 400 que nombra el archivo, p. ej., @Video2 tiene 16 s de duración….
    • Los segundos de video de referencia se facturan junto con los segundos de salida. Las imágenes de referencia y el audio son gratuitos. Para cotizar, pasa reference_video_durations: [6.5] (segundos por clip).
  • Las entradas de medios deben ser URLs https públicas. Para archivos locales, llama a POST /uploads con JSON { "filename", "content_type", "size" }. Devuelve { upload_url, headers, url }: haz PUT de los bytes a upload_url con exactamente esos headers, luego usa url como entrada. Límites: imágenes (PNG/JPEG/WebP/GIF) ≤ 20 MB, video (MP4/MOV) ≤ 50 MB, audio (MP3/WAV/M4A) ≤ 15 MB.
  • Opcional en cada ejecución: webhook_url (HTTPS) y retention (immediate | 1h | 1d; 7d / 30d necesitan una configuración de cuenta).

Webhooks

Cuando el trabajo finaliza (exitoso o fallido), hacemos un POST { "type": "generation.succeeded" | "generation.failed", "data": <generation> } a webhook_url, con el encabezado CheaperGen-Signature: t=<unix>,v1=<hex>. Para verificarlo, calcula hex(HMAC_SHA256(secret, "<t>.<raw body>")) con el secreto de firma del webhook de la cuenta (whsec_…, en Panel → Claves API), compara en tiempo constante y rechaza solicitudes cuyo t tenga más de 5 minutos. Usa el cuerpo de solicitud sin procesar, no JSON reserializado. Devuelve 2xx rápidamente; las entregas fallidas se reintentan (3 intentos en total).

Precios y facturación

  • Los precios son por segundo de video de salida o por imagen. GET /models muestra el price_usd de cada nivel junto a list_price_usd (el precio oficial).
  • Al enviar, el precio cotizado se retiene (cost.estimated: true). Al tener éxito se vuelve definitivo; al fallar o cancelar se reembolsa en su totalidad (cost.amount_usd: 0). cost.official_usd y cost.saved_usd muestran los ahorros.
  • Saldo: GET /account devuelve balance_usd y reserved_usd (retenido para trabajos en curso). Un 402 significa que el saldo es demasiado bajo: a través de MCP, llama a add_credits y muestra al usuario el enlace de pago; de lo contrario, el usuario agrega créditos en https://cheapergen.com/dashboard/billing.
  • Cancela un trabajo en cola con POST /generations/{id}/cancel (409 una vez que está en ejecución). Elimina uno finalizado con DELETE /generations/{id}.

Errores

Cada error tiene la forma { "error": { "code", "message", "param"? } }.

HTTPcódigoQué hacer
400invalid_requestCorrige el campo nombrado en param (revisa el esquema, enumerados, límites y menciones). No reintentes sin cambios.
401unauthorizedClave faltante, inválida o revocada.
402insufficient_balanceObtén un enlace de pago con add_credits (MCP) y pide al usuario que pague, o elige un nivel más barato.
404not_foundEndpoint o ID de generación incorrecto.
409conflictP. ej., cancelar un trabajo que ya comenzó.
429rate_limitedRetrocede y reintenta. El límite es de aproximadamente 20 solicitudes en ráfaga, reabastecidas a 10/s por clave, más un límite de generaciones concurrentes por cuenta (predeterminado 20).
502upstream_errorReintenta una vez, luego prueba con otro modelo.
503model_unavailableReintenta más tarde o cambia de modelo.

Una generación que termina failed tiene error.code (p. ej., generation_failed, timeout) y ha sido reembolsada. Reintenta como máximo una vez con la misma entrada.

Más

Skills relacionados