Tutorial
Cómo usar recraft/creative-upscale a través de la API de HiAPI: guía de solicitudes con curl y Python
El papel de recraft/creative-upscale en el flujo de trabajo del desarrollador
recraft/creative-upscale es un endpoint de imagen a imagen: envías una imagen existente y el modelo devuelve una versión más grande, reconstruida por el modelo. La palabra clave aquí es creativa (creative). Un paso de upscaling clásico (bilineal, Lanczos o un modelo genérico de superresolución) conserva la entrada con la mayor fidelidad posible. El upscaling creativo, en cambio, permite regenerar detalles que nunca existieron en los píxeles de origen: los bordes se resintetizan, las texturas se infieren y las zonas pequeñas y borrosas pueden nitidizarse hasta convertirse en contenido plausible, no solo interpolado.
Esto lo diferencia de una simple herramienta de escalado y determina que ocupe una posición distinta en la tubería.
Cuándo usarlo
- Actualización de material. Una miniatura o una imagen de producto antigua necesita mostrarse a un tamaño de visualización mayor, y el escalado ordinario se vería borroso en comparación con los elementos vecinos a resolución nativa.
- Trabajo con imágenes de referencia y renders. El arte conceptual, los storyboards o las imágenes de marcador de posición deben mostrarse a gran tamaño sin revelar su origen de baja resolución.
- Upscaling dentro del bucle de generación. Has generado una imagen a un tamaño de trabajo pequeño y quieres un material final sin volver a ejecutar todo el proceso de generación en un lienzo más grande.
Cuándo no usarlo
Si la necesidad es una fidelidad exacta byte a byte —escaneos de archivo, documentos, atlas de texturas cuyos valores de píxel son datos—, no uses un modelo creativo. Los detalles regenerados son conjeturas plausibles, no reconstrucciones; para fines de medición o archivo, esa conjetura es un defecto. En esos casos, usa un remuestreador determinista y deja los modelos creativos para salidas perceptuales.
La forma de la llamada
Este endpoint sigue el mismo patrón de solicitud que los demás endpoints de imagen de HiAPI: una solicitud POST con JSON autenticada enviada a la ruta del modelo, que contiene una imagen de entrada y un objeto de parámetros. Si ya has integrado cualquier otro modelo de imagen de la plataforma, este modelo mental se transfiere directamente —eso es precisamente lo que significa enrutar estas llamadas a través de una interfaz unificada. Una llamada curl funcional se convierte en la plantilla para cada endpoint de imagen que toques a partir de entonces.
Una forma útil de entender este paso: consume una imagen en la que ya confías (composición, contenido y color ya decididos) y devuelve una variante más grande y detallada. Las decisiones de contenido pertenecen a la etapa anterior; recraft/creative-upscale es la fase de cierre.
Requisitos previos y configuración del endpoint
Antes de escribir tu primera solicitud, reúne cuatro cosas. Ninguna requiere un SDK especial: toda la integración es comunicación HTTPS pura con un cuerpo JSON.
1. Clave de API
Necesitas una clave de API de HiAPI con acceso a los modelos de imagen. Trátala como un secreto: cárgala desde una variable de entorno en lugar de pegarla en un script, y nunca la confirmes en el repositorio.
export HIAPI_API_KEY="your-key-here"
La clave se pasa mediante una cabecera, ni en la URL ni en el cuerpo JSON. Mantenerla fuera de la cadena de consulta también la mantiene fuera del historial del shell y de los registros del proxy.
2. URL base
La URL base es tu host de la API de HiAPI. Todas las llamadas a modelos son rutas relativas bajo ella, así que puedes asignarla a una variable y reutilizarla en cada script:
export HIAPI_BASE_URL="https://api.hiapi.ai"
Consulta la documentación de referencia de la API de la plataforma para obtener la URL base canónica y el prefijo de ruta de tu cuenta, y guárdalos en esta única variable. Así, un cambio de host o de versión es una edición de una sola línea.
3. Identificador del modelo
El ID del modelo es un segmento de ruta y debe escribirse exactamente como se publica: recraft/creative-upscale. Contiene una barra, lo que importa en algunas herramientas —la sección de depuración lo detalla. Mayúsculas y guiones cuentan. Un carácter incorrecto produce un error de modelo no encontrado que, si solo echas un vistazo rápido al mensaje, parece un problema de autenticación.
4. Imagen de prueba
Ten una imagen preparada en disco y conoce su ruta exacta y su tipo MIME. Usa un archivo pequeño en la primera ejecución, para que un fallo sea claramente un problema de la solicitud y no del tamaño de la carga útil o de un tiempo de espera. Reutilizarás la misma imagen para las ejecuciones de comparación, así que elige algo con detalle visible (tejido, vegetación, carteles sin texto) en lugar de un degradado plano.
Lista de comprobación de cabeceras
Cada solicitud a partir de aquí lleva las mismas cabeceras:
Authorization: Bearer $HIAPI_API_KEYContent-Type: application/json
Si envías la imagen en el cuerpo JSON como base64 o data URI, estas dos cabeceras son suficientes. Si en cambio subes primero el archivo para obtener una URL, haz esa carga como una llamada aparte y guarda la URL resultante por separado de la solicitud al modelo.
Con la clave, la URL base, el ID del modelo y una imagen de prueba, puedes lanzar una llamada real en menos de un minuto.
Una solicitud funcional con curl
Aquí tienes una llamada lista para ejecutar. Sustituye el valor de la imagen por tu propia entrada —puede ser una URL accesible públicamente o un data URI codificado en base64, según lo que acepte el modo de entrada del modelo.
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": {
"image": "https://example.com/test-input.png"
},
"parameters": {
"upscale": 2
}
}' \
-o response.json
Usar -o para escribir la respuesta en un archivo, en lugar de dejarla fluir a la terminal, mantiene el JSON intacto para poder analizarlo y hace que la llamada sea scriptable.
Qué hace cada parte
-X POST— el endpoint es POST; un GET devuelve un error de método que se malinterpreta fácilmente como un problema de permisos.- URL — la URL base, seguida de la ruta del modelo con el ID completo. Como el ID contiene una barra, la ruta tiene dos segmentos tras la colección de modelos; mantenla como una sola cadena y no dejes que la biblioteca cliente la recodifique como
recraft%2Fcreative-upscale, a menos que la documentación indique que ese es el comportamiento esperado. Authorization— token de portador. Si ves un 401 en este comando exacto, la clave o el formato de la cabecera están mal; no se ha validado nada más del cuerpo de la solicitud.Content-Type: application/json— obligatoria. Sin ella, algunas pasarelas tratan el cuerpo como datos de formulario y la solicitud nunca llega al modelo.input.image— la imagen de origen. Durante la iteración, prefiere una URL: mantiene el comando corto y el diff claro.parameters.upscale— control de upscaling. Empieza con un factor moderado y auméntalo cuando hayas confirmado la respuesta.
Dos variantes útiles
Para enviar un archivo local como base64 en lugar de una URL:
B64=$(base64 -w0 ./test-input.png)
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d "{
\"input\": { \"image\": \"data:image/png;base64,${B64}\" },
\"parameters\": { \"upscale\": 2 }
}" \
-o response.json
Para ver el código de estado HTTP y el cuerpo de la respuesta al depurar, añade -w '\nHTTP %{http_code}\n' y quita -o.
Trata este único comando como tu plantilla. Una vez que devuelva una imagen, cada cambio posterior —un factor distinto, otra imagen de origen— es solo editar dos campos, no una nueva integración.
La misma solicitud en Python
La versión en Python no debe ser un copiar y pegar del cuerpo de curl; debería ser una pequeña función reutilizable, de modo que cada ejecución de comparación posterior sea solo una llamada. Usa solo la biblioteca estándar: sin SDK.
import base64
import json
import os
import pathlib
import urllib.request
HIAPI_BASE_URL = os.environ["HIAPI_BASE_URL"].rstrip("/")
HIAPI_API_KEY = os.environ["HIAPI_API_KEY"]
MODEL = "recraft/creative-upscale"
def creative_upscale(image: str, upscale: int = 2, timeout: int = 120) -> dict:
"""Envía una imagen a recraft/creative-upscale y devuelve el JSON analizado."""
payload = {
"input": {"image": image},
"parameters": {"upscale": upscale},
}
request = urllib.request.Request(
url=f"{HIAPI_BASE_URL}/v1/models/{MODEL}",
data=json.dumps(payload).encode("utf-8"),
headers={
"Authorization": f"Bearer {HIAPI_API_KEY}",
"Content-Type": "application/json",
},
method="POST",
)
with urllib.request.urlopen(request, timeout=timeout) as response:
return json.loads(response.read().decode("utf-8"))
def as_data_uri(path: str) -> str:
data = pathlib.Path(path).read_bytes()
mime = "image/png" if path.lower().endswith(".png") else "image/jpeg"
return f"data:{mime};base64,{base64.b64encode(data).decode('ascii')}"
if __name__ == "__main__":
result = creative_upscale(as_data_uri("test-input.png"), upscale=2)
print(json.dumps(result, indent=2)[:2000])
Por qué adoptar esta forma
- Configuración desde variables de entorno. La URL base y la clave se leen una vez al importar, así que no hay ningún secreto en el archivo y cambiar de entorno es solo un export.
- Una función, una responsabilidad.
creative_upscalerecibe una referencia de imagen y un factor, y devuelve el JSON analizado. Toda la información sobre los parámetros permanece visible en el punto de llamada. - Tiempo de espera explícito. Los modelos de imagen tardan más que los endpoints de texto. Establece el tiempo de espera a propósito, en lugar de heredar un valor predeterminado demasiado corto, y mantenlo lo bastante largo para que una llamada lenta pero exitosa no se reintente innecesariamente.
- Una función auxiliar para archivos locales.
as_data_urisignifica que puedes pasar una URL o una ruta local sin tocar la lógica de la solicitud.
Si prefieres un cliente basado en sesión
La misma llamada con httpx requiere solo dos líneas de sustitución: construye un cliente, establece la cabecera Authorization predeterminada y luego haz post del cuerpo JSON. Los invariantes importantes no cambian: el ID del modelo sigue siendo un único segmento de ruta sin codificar, la clave permanece en la cabecera y el cuerpo mantiene la separación input / parameters. Si cumples estos tres puntos, tu cliente es intercambiable con cualquier otro de la plataforma.
Cuando lo conectes a una tubería, devuelve el diccionario analizado y deja que quien llama decida cómo persistir la imagen: esta separación hace reutilizable el manejo de la respuesta de la siguiente sección.
Parámetros de upscaling y creatividad
Los valores que envías importan menos que dónde los envías. Primero confirma que la ubicación es correcta; después ajusta los números.
Dos contenedores, un contrato
Cada solicitud se divide en:
input— la imagen en sí. El objeto sobre el que se opera. Nada relacionado con el comportamiento del modelo va aquí.parameters— los controles. El factor de upscaling y la configuración de creatividad pertenecen a este objeto, como hermanos.
Esta separación es el contrato. La primera ejecución debe confirmar que el modelo acepta tu ubicación —es decir, que la llamada al menos devuelve una imagen— antes de empezar a optimizar valores. Si un parámetro está en el contenedor equivocado, normalmente obtendrás una imagen generada con los valores predeterminados o un error de validación que señala un campo desconocido. En ambos casos es un error de ubicación, no de calidad, y perseguir ajustes de calidad no lo solucionará.
Factor de upscaling
El factor controla el tamaño de la salida respecto a la entrada. Cómo razonar sobre él:
- Es un multiplicador, así que el coste y la latencia crecen con él. Pasar de un factor moderado al máximo no es un paso lineal en tiempo de renderizado. Trata cada aumento como un nuevo experimento, no como mover un control deslizante.
- La resolución de entrada sigue importando. Cuando existe algo de estructura, el modelo creativo tiene más margen. Una entrada extremadamente pequeña le da más libertad para inventar, lo que a veces es el objetivo y a veces una sorpresa.
- Elige el factor según el tamaño objetivo, no según el máximo. Si la imagen necesita 2× para encajar en su lugar, solicita 2×. Pedir el máximo y luego reducir descarta la ganancia y pagas por ella.
Control de creatividad
La creatividad es el mando que decide cuánto puede el modelo sustituir (en lugar de ampliar). Los valores bajos se comportan más como un upscaling fiel; los altos hacen que el modelo resintetice con más agresividad, lo que puede rescatar una fuente borrosa o con bloques, y también puede introducir detalles que no quieres.
Piensa en este parámetro como una palanca de fidelidad, con lecturas concretas en ambos extremos:
- Conservar — logotipos, rostros, imágenes de catálogo de productos, cualquier cosa que el espectador pueda comparar con el original.
- Regenerar — arte conceptual, fondos, texturas, imágenes decorativas, donde la plausibilidad importa más que la exactitud.
Método de trabajo
Cambia un parámetro a la vez, mantén la entrada fija y registra los valores junto con la salida. Una pequeña matriz —la misma imagen con dos factores y, para cada factor, dos ajustes de creatividad— basta para caracterizar el comportamiento de este endpoint con tu propio contenido. No tomes prestados los valores "óptimos" de otra persona; los modelos creativos interactúan fuertemente con la entrada, y los ajustes que funcionan para una foto rara vez funcionan para una ilustración plana.
Si un valor se rechaza directamente en lugar de producir un mal resultado, el contrato te está indicando el dominio del parámetro: consulta la referencia de parámetros del endpoint para conocer los rangos aceptables en lugar de adivinar.
Leer la respuesta y guardar la imagen
Analiza la respuesta de forma defensiva. El tipo de carga útil forma parte del contrato, pero puede variar entre una URL y un bloque base64 en línea, y tu cliente no debería fallar según cuál reciba.
Primero, mira el JSON sin procesar
Antes de escribir un analizador, ejecuta una vez la llamada curl con -o response.json y lee el archivo. Identifica el campo que contiene la imagen. Suele ser uno de estos:
- una URL que apunta al archivo generado, o
- una cadena en línea, normalmente base64 o un data URI.
Busca también metadatos que merezca la pena registrar: dimensiones, el ID del modelo devuelto y cualquier identificador que puedas usar para abrir una solicitud de soporte.
Una función de guardado tolerante a fallos
import base64
import pathlib
import urllib.request
def extract_image(result: dict) -> str:
"""Encuentra la carga útil de la imagen, sea cual sea la forma en que se devuelva."""
for container in (result, result.get("data"), result.get("output")):
if isinstance(container, list) and container:
container = container[0]
if isinstance(container, dict):
for key in ("image", "url", "b64_json", "image_url"):
value = container.get(key)
if isinstance(value, str) and value:
return value
raise ValueError(f"no image field in response: {sorted(result)}")
def save_image(payload: str, out_path: str = "upscaled.png") -> pathlib.Path:
path = pathlib.Path(out_path)
if payload.startswith("data:"):
payload = payload.split(",", 1)[1]
path.write_bytes(base64.b64decode(payload))
elif payload.startswith("http://") or payload.startswith("https://"):
with urllib.request.urlopen(payload) as response:
path.write_bytes(response.read())
else:
path.write_bytes(base64.b64decode(payload))
return path
El punto no es que este sea el único analizador correcto, sino que la función declara sus supuestos (data:, http(s)://, base64 puro) y lanza un error claro cuando ninguno coincide. Cuando cambie la forma de la respuesta, solo tendrás que actualizar una función, no todos los scripts que consumen imágenes.
Guardado seguro en el flujo con curl
curl -sS -X POST "$HIAPI_BASE_URL/v1/models/recraft/creative-upscale" \
-H "Authorization: Bearer $HIAPI_API_KEY" \
-H "Content-Type: application/json" \
-d @request.json -o response.json
python - <<'PY'
import json
from save_image import extract_image, save_image
result = json.load(open("response.json"))
print(save_image(extract_image(result), "out.png"))
PY
Dos hábitos que conviene mantener: escribir un nombre de archivo nuevo en cada ejecución, para que una ejecución fallida o una escritura parcial nunca sobrescriba un buen resultado; y verificar las dimensiones de la salida después de guardar: un HTTP 200 correcto pero con dimensiones inesperadas significa que el parámetro no surtió efecto, y es más fácil detectarlo aquí que después de tres etapas de la tubería.
Depurar fallos comunes
La mayoría de los fallos de la primera ejecución son triviales. Recorre esta lista en orden; cubre la gran mayoría de los casos.
401 / 403 — autenticación
- ¿La clave está cargada en el mismo shell donde ejecutas el comando?
echo $HIAPI_API_KEYdebería imprimir un valor no vacío. - ¿La cabecera es exactamente
Authorization: Bearer <key>, incluido el espacio y la palabraBearer? - ¿La clave acabó en la URL o en el cuerpo JSON en lugar de en la cabecera? Devuélvela a su sitio.
- ¿La clave está limitada a los modelos de imagen? Una clave válida para un área de producto puede no aplicarse a este endpoint.
404 — modelo o ruta no encontrados
Esto casi siempre es un problema del ID del modelo. Compáralo carácter a carácter con el identificador publicado recraft/creative-upscale: la barra, las minúsculas y el guion de creative-upscale son críticos. Una trampa relacionada es el escape de URL del cliente: si ves recraft%2Fcreative-upscale en la solicitud real y la llamada devuelve 404, tu capa HTTP codificó la barra; configúrala para que no toque los segmentos de ruta.
Comprueba también que no estés duplicando el prefijo de ruta (por ejemplo, que la URL base ya termine en un segmento de versión y la ruta lo repita). Usar una sola variable para la URL base hace que esto sea fácil de detectar.
400 — solicitud comprendida pero rechazada
Lee el mensaje en lugar de adivinar. Causas comunes:
- Formato de imagen de entrada incorrecto. Base64 truncado (a menudo porque una variable del shell se truncó, o falta el prefijo
data:image/png;base64,cuando el modo espera un data URI completo), o una URL que no es accesible públicamente. - Parámetro fuera de rango o mal ubicado. Un factor que el modelo no acepta, o
upscaleenviado en el nivel superior en lugar de dentro deparameters. - Falta el tipo de contenido. Un
Content-Typedetext/plaino ausente convierte el cuerpo JSON en un documento que no se puede analizar.
413 / 422 / tiempo de espera — tamaño y duración
Las imágenes de origen muy grandes pueden fallar la validación antes de que se ejecute el modelo. Reduce modestamente la entrada, vuelve a intentarlo y confirma que la forma de la solicitud es razonable antes de enviar el archivo a resolución completa. Para los tiempos de espera, distingue entre lento y fallido: aumenta una vez el tiempo de espera del cliente y, si la llamada tiene éxito después, la corrección pertenece a la configuración del cliente, no a la carga útil.
Regla de triaje rápida
Si el error menciona autenticación, modelo o formato de entrada, no has llegado a la lógica de upscaling: todavía no interviene ningún valor de creatividad o de factor. Corrige el envoltorio, reintenta con la solicitud más pequeña posible (una imagen de prueba pequeña, parámetros predeterminados) y solo entonces empieza a cambiar la configuración. Depurar en este orden evita el error clásico: compensar una cabecera rota ajustando parámetros.
Construir una prueba comparativa reproducible
El upscaling creativo depende mucho del criterio, así que usa un dispositivo fijo en lugar de la memoria. El objetivo es un pequeño banco de pruebas que responda a "¿realmente ayuda este ajuste?" sin tener que volver a mirar archivos antiguos.
Entrada fija
- Una imagen de prueba, versionada en el repositorio. Elige algo con detalle recuperable: tejido, vegetación, bordes de edificios. Confírmala junto al script para que cada ejecución y cada miembro del equipo use la misma fuente.
- Parámetros fijos. El factor y los valores de creatividad viven en una lista dentro del script, no en tu cabeza ni en un mensaje de chat.
- ID de modelo fijo. Por la misma razón que la lista de comprobación de cabeceras:
recraft/creative-upscalese escribe una vez, en una constante.
Un ejecutor de matrices mínimo
import itertools, json, pathlib
FACTORS = [2, 4]
CREATIVITY = ["preserve", "regenerate"] # usa los valores exactos que acepte la documentación
src = as_data_uri("fixtures/test-input.png")
out_dir = pathlib.Path("runs"); out_dir.mkdir(exist_ok=True)
for factor, mode in itertools.product(FACTORS, CREATIVITY):
result = creative_upscale(src, upscale=factor, creativity=mode)
name = f"f{factor}-{mode}"
save_image(extract_image(result), out_dir / f"{name}.png")
(out_dir / f"{name}.json").write_text(json.dumps(result, indent=2))
print(name, "ok")
Dos detalles importan más que el código. Primero, guarda la respuesta JSON sin procesar junto a cada imagen: cuando un resultado no parezca correcto, la respuesta te dice si el parámetro se aplicó o se ignoró silenciosamente. Segundo, nombra los archivos a partir de los valores de los parámetros, para que el listado del directorio sea la matriz y nunca tengas que dudar qué archivo vino de qué ajuste.
Comparar de forma constante
- Mira las salidas al tamaño de visualización previsto, no ampliadas. Un detalle creativo impresionante al 400% puede parecer antinatural al tamaño en que el usuario realmente lo ve.
- Comprueba las dimensiones mediante código como parte de la ejecución. Una discrepancia significa que el factor no surtió efecto, lo cual es un informe de error sobre tu propia solicitud, no un problema estético.
- Juzga según criterios definidos de antemano: fidelidad a la fuente frente a nitidez perceptual, elegidos según la categoría del recurso. Escribe ese criterio junto a la matriz para que la siguiente persona sepa qué significa "mejor".
Una vez que la matriz se estabiliza, el banco de pruebas se convierte en una prueba de regresión: vuelve a ejecutarla tras cualquier cambio en el código del cliente y compara con el directorio de ejecuciones anterior. Como cada llamada de esta guía comparte la misma forma de solicitud que los demás endpoints de imagen de la plataforma, el ejecutor que construyas aquí se generaliza a cualquier modelo que integres después.
Artículos relacionados
Ver todos los artículos →-
Tutorial
Cómo llamar a hailuo-2.3-fast/image-to-video a través de la API de HiAPI: práctica con curl y Python
La primera solicitud ejecutable del nivel rápido y de bajo coste de imagen a vídeo: del ID del modelo a la descarga del MP4
-
Tutorial
Cómo llamar a hailuo-2.3/text-to-video mediante la API de HiAPI: curl, Python y ejemplos de solicitud ejecutables
-
Tutorial
Uso de Kandinsky 6.0 Pro texto a video en HiAPI: tutorial con curl y Python
Demostración práctica centrada en la solicitud: construir la llamada de prompt a clip de video, enviar la solicitud, sondear el estado de finalización y descargar el resultado