HiAPI
Blog

Tutorial

Cómo usar la API Recraft Creative Upscale: curl, Python y una ejecución real

Un único campo image_url, una entrada de 1254 px que vuelve a 4096 px, y qué devolvió realmente la tarea.

Oct 23, 2026
Cómo usar la API Recraft Creative Upscale: curl, Python y una ejecución real

TL;DR

  • recraft/creative-upscale amplía la imagen y redibuja su textura y detalles. El cuerpo de la solicitud tiene un solo campo, image_url. No hay prompt ni ajustes de escala.
  • Usa el flujo unificado /v1/tasks: POST para obtener el taskId, sondeo con GET /v1/tasks/<taskId> y descarga desde data.output[0].url.
  • En nuestra ejecución, un PNG de 1254×1254 se devolvió tras unos 60 segundos como WebP de 4096×4096, unos 19,8 MB. Presupuesta el tiempo de espera y el tamaño del archivo.

Qué necesitas preparar

Una clave de API de hiapi desde la consola y una URL de imagen accesible públicamente. La página del modelo enumera los límites de entrada: se recomienda PNG, máximo 20 MB, entre 256 y 4096 px por lado y máximo 16 MP.

Si necesitas que el texto, los logotipos o los detalles del producto se mantengan intactos, usa Recraft Crisp Upscale. Creative Upscale redibuja, por lo que los elementos pequeños pueden cambiar.

Solicitud curl mínima

export HIAPI_KEY=sk-your-key

curl -s https://www.hiapi.ai/v1/tasks \
  -H "Authorization: Bearer $HIAPI_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "model": "recraft/creative-upscale",
    "input": { "image_url": "https://example.com/old-illustration.png" }
  }'

La respuesta es un identificador de tarea:

{"code":200,"data":{"taskId":"tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD"},"message":"success"}

Sondéala hasta que data.status sea success:

curl -s https://www.hiapi.ai/v1/tasks/tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD \
  -H "Authorization: Bearer $HIAPI_KEY"

Python: enviar, sondear y guardar

import os, time, requests

BASE = "https://www.hiapi.ai"
HEADERS = {"Authorization": f"Bearer {os.environ['HIAPI_KEY']}"}

def upscale(image_url: str, out_path: str) -> str:
    r = requests.post(f"{BASE}/v1/tasks", headers=HEADERS, timeout=30, json={
        "model": "recraft/creative-upscale",
        "input": {"image_url": image_url},
    })
    r.raise_for_status()
    task_id = r.json()["data"]["taskId"]

    deadline = time.time() + 300
    while time.time() < deadline:
        time.sleep(5)
        try:
            d = requests.get(f"{BASE}/v1/tasks/{task_id}", headers=HEADERS, timeout=30).json()["data"]
        except requests.RequestException:
            continue  # transient network error: keep polling the SAME taskId
        if d["status"] == "success":
            url = d["output"][0]["url"]
            with open(out_path, "wb") as f:
                f.write(requests.get(url, timeout=120).content)
            return task_id
        if d["status"] in ("fail", "failed"):
            raise RuntimeError(f"task {task_id} failed: {d}")
    raise TimeoutError(f"task {task_id} still running; re-poll it, do not resubmit")

upscale("https://example.com/old-illustration.png", "upscaled.webp")

Dos detalles importan en producción. Primero, nunca reenvíes tras un tiempo de espera agotado: cada envío crea una nueva tarea facturable, así que conserva el taskId y vuelve a sondearlo. Segundo, guarda el archivo de inmediato; la URL de salida lleva expireAt y el host es temporal.

Consideraciones para producción

  • Usa callbacks para tareas por lotes. En lugar de sondear, puedes pasar callback: {"url": "...", "when": "final"} en el cuerpo de la tarea para que hiapi te llame al terminar. Trata el taskId como clave de deduplicación.
  • Basta con un intervalo de sondeo de 5 segundos. Una tarea tarda alrededor de un minuto, así que sondear más rápido solo añade solicitudes.
  • Valida la URL antes de enviar. La plataforma rechaza de antemano las URL mal formadas (ver más abajo), pero una URL https:// inaccesible es otro tipo de fallo que conviene capturar de antemano desde tu lado con una rápida solicitud HEAD.

Lo que vimos en una ejecución real

Ejecutamos una solicitud real con la imagen de entrada de ejemplo de la página del modelo (un PNG de 1254×1254 de una cabaña en la montaña).

Elemento Observación
Respuesta al envío {"code":200,"data":{"taskId":"tk-hiapi-01M5K8J899THH6XJK99TAZ4VSD"}}
Secuencia de estados handling → archiving → success
Tiempo de created a completed 61 segundos (1792721625 → 1792721686)
Salida Una imagen, WebP, https://temp.hiapi.ai/.../...-0.webp, con un expireAt de unos 7 días después
Tamaño de entrada PNG de 1254×1254, 2,7 MB
Tamaño de salida WebP de 4096×4096, unos 19,8 MB

Cosas que vale la pena saber de esa ejecución:

  1. La fase archiving aún no tiene output. La tarea informa completed y status: "archiving" durante varios sondeos antes de que el resultado se mueva al almacenamiento. Solo status == "success" trae output[0].url, así que no leas la URL la primera vez que veas la marca de tiempo completed.
  2. El resultado no es un 2× limpio. La entrada de 1254 px se convirtió en 4096 px, aproximadamente 3,3× por lado. La página del modelo muestra el mismo par y no expone ningún campo de escala, así que espera que el tamaño de salida lo decida el modelo, no tú. Si necesitas exactamente 2×, Crisp Upscale es el endpoint que cumple esa convención.
  3. El archivo de salida es grande. 19,8 MB por imagen supera el límite de entrada de 20 MB que te permitiría volver a alimentarlo directamente, así que no encadenes una segunda pasada sobre la salida sin redimensionarla.
  4. Los detalles se redibujan, no solo se enfocan. La propia descripción de la página del modelo para este par de imágenes dice que la composición, la iluminación y el color se conservan en gran medida, mientras que los troncos, la mampostería y las barandillas se redibujan, y algunos elementos pequeños (por ejemplo, un árbol junto al porche) cambian. Revisa la salida antes de sustituir activos de marca.
  5. Las URL erróneas fallan rápido. Enviar "image_url": "not-a-url" devuelve de inmediato HTTP 400: {"code":400,"data":null,"error_code":"INVALID_REQUEST","message":"invalid input: image_url: 'not-a-url' does not match pattern '^https?://'"}. Ese patrón es la única comprobación que hemos validado; no probamos el mínimo de 256 px ni el límite de 16 MP.

Ejecutamos una sola tarea, así que la cifra de 61 segundos es una única muestra, no un benchmark.

¿Creative Upscale o Crisp Upscale?

Ambos aceptan solo un image_url y no necesitan prompt. Se diferencian en cómo tratan los píxeles y en el precio.

Creative Upscale Crisp Upscale
ID del modelo recraft/creative-upscale recraft/crisp-upscale
Comportamiento Amplía y redibuja texturas y detalles Duplica el ancho y el alto, conservando el contenido y el texto
Ideal para Ilustraciones antiguas, arte de pequeño tamaño o baja resolución Fotos de producto, pósteres con texto, activos de diseño
Precio Mucho más alto por imagen; consulta precios Consulta el artículo de precios de Crisp

El precio por imagen de Creative Upscale es muy superior al de Crisp (compara las cifras en vivo en la página de precios), así que úsalo solo cuando realmente quieras que los detalles se regeneren. Para flujos de trabajo genéricos de resolución entre modelos, consulta aumentar la resolución de imágenes con hiapi.

Relacionado

FAQ

¿Necesito un prompt? No. La página del modelo describe una entrada de una sola imagen, sin prompt ni otros ajustes, y nuestra solicitud solo usó image_url.

¿Puedo elegir el tamaño de salida? No mediante la API. No hay campo de escala; nuestra entrada de 1254 px se devolvió a 4096 px.

¿Se conservan el texto y los logotipos? No está garantizado. Los detalles se regeneran y los elementos pequeños pueden cambiar, así que para activos con texto usa Crisp Upscale.

¿Qué formato de salida obtendré? En nuestra ejecución fue WebP, entregado desde una URL temporal que caduca, así que descárgalo de inmediato.

¿Cuánto tarda? Nuestra única ejecución tardó alrededor de un minuto; diseña tu cliente para esperas de ese orden.

Artículos relacionados

Ver todos los artículos →

Empieza a crear con artefactos de IA persistentes

Consigue tu API key y llama a modelos de imagen, vídeo y audio a través de una única API basada en tasks.

Leer la documentación de la API