API en tiempo real

API de eliminación de fondos: envías una solicitud y recibes el PNG terminado.

Sube un archivo, envía la URL pública de una imagen o pásala en base64. La mayoría de las imágenes individuales vuelven terminadas en la misma respuesta HTTP, normalmente en unos segundos. Si alguna tarda más, recibes un id de trabajo para obtener el resultado sin volver a enviar la imagen. Para grandes volúmenes hay un endpoint de lotes.

1 crédito por imagen procesada con éxito · las imágenes fallidas son gratis · claves en tu cuenta

$ curl -X POST https://removebackground.dev/v1/remove \
    -H "x-api-key: $REMOVEBG_API_KEY" \
    -F 'image_file=@dog.jpg' -o dog.png

← 200 OK · image/png · normalmente unos segundos
  guardado dog.png (transparente, resolución completa)
1 Tu imagen2 Una solicitud HTTP3 PNG en la respuesta

Inicio rápido

Copia, pega y sustituye YOUR_API_KEY. Cada ejemplo guarda el resultado directamente en un archivo, y los de JavaScript y Python además esperan si reciben un 202.

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Envía tu imagen

POST /v1/remove acepta la imagen de cuatro formas. Envía una de ellas; si una solicitud incluye varias, gana image_file, luego image_file_b64, luego image_url y por último el cuerpo sin procesar. Estos ejemplos leen tu clave de la variable de entorno REMOVEBG_API_KEY (defínela con export REMOVEBG_API_KEY=…); fíjate en las comillas dobles, que permiten que la shell la sustituya.

curl -X POST https://removebackground.dev/v1/remove \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Datos de formulario multipart, campo image_file. JPG, PNG o WebP, hasta 25 MB.

Todos los ejemplos guardan el cuerpo en un archivo. Ese archivo solo es una imagen cuando el estado es 200; consulta Gestiona la respuesta.

Gestiona la respuesta

La mayoría de las imágenes individuales vuelven terminadas en la misma respuesta. Cuando la cola está inusualmente ocupada y una imagen tarda más de unos 55 segundos, recibes 202 Accepted con un id de trabajo. El trabajo sigue en marcha: obtén su resultado con el id. Volver a enviar la imagen iniciaría un segundo trabajo y podría costar un segundo crédito.

EstadoCuerpoQué hacer
200La imagen (image/png, image/jpeg o image/webp)Guárdala. Usa el Content-Type para elegir la extensión del archivo.
202JSON: { id, status, status_url, result_url }No es una imagen. Espera un par de segundos y haz GET a result_url. No vuelvas a enviar la imagen.
4xx / 5xxJSON: { "error": { "code", "message" } }No es una imagen. Lee el código (ver Errores) y no guardes el cuerpo como imagen.

Un ejemplo completo

Gestiona la imagen terminada, un 202, un trabajo que falla y un límite de tiempo local. Envía la imagen una sola vez y solo reintenta las consultas de estado, que son seguras.

import os
import time
import uuid

import requests

API = "https://removebackground.dev"
KEY = os.environ["REMOVEBG_API_KEY"]  # keep the key on your server
EXT = {"image/png": ".png", "image/jpeg": ".jpg", "image/webp": ".webp"}


def save(res, stem):
    """Save an image response with the right extension; raise on anything else."""
    mime = res.headers.get("Content-Type", "").split(";")[0]
    if res.status_code != 200 or mime not in EXT:
        raise RuntimeError(f"HTTP {res.status_code}: {res.text[:500]}")
    path = stem + EXT[mime]
    with open(path, "wb") as f:
        f.write(res.content)
    return path


def remove_background(image_url, stem="result", max_wait=300):
    s = requests.Session()
    s.headers["x-api-key"] = KEY

    # One key per image: resending with the same key returns the same job, never a second
    # charge, so this POST is safe to retry after a timeout or a dropped connection.
    idem = {"Idempotency-Key": str(uuid.uuid4())}
    for attempt in range(3):
        try:
            res = s.post(f"{API}/v1/remove", data={"image_url": image_url}, headers=idem, timeout=(10, 120))
            break
        except requests.ConnectionError:
            if attempt == 2:
                raise
            time.sleep(2)
    if res.status_code != 202:
        return save(res, stem)  # 200 = the image; anything else raises

    # 202: still processing. Wait for the same job; never send the image again.
    job_id = res.json()["id"]
    deadline = time.monotonic() + max_wait
    while time.monotonic() < deadline:
        time.sleep(2)  # the API sends Retry-After: 2
        res = s.get(f"{API}/v1/jobs/{job_id}/result", timeout=30)
        if res.status_code == 409 and res.json()["error"]["code"] == "not_ready":
            continue
        return save(res, stem)  # the image, or the job's own error
    raise TimeoutError(f"Job {job_id} is still running. Check it later at /v1/jobs/{job_id}.")


print(remove_background("https://example.com/photo.jpg"))

Requiere Python 3 y requests (pip install requests).

  • Detener tu script no detiene el trabajo; puede terminar igualmente y cobrarse. Su resultado aparecerá en tu Studio.
  • Los límites de tiempo los eliges tú, no son una promesa nuestra; la mayoría de las imágenes terminan en unos segundos.
  • El endpoint compatible con remove.bg funciona de otra forma: nunca responde 202 (ver más abajo).

Autenticación

Envía tu clave de API en la cabecera x-api-key. Crea y revoca claves en la página de tu cuenta; cada llamada gasta los créditos de esa cuenta. Todos los endpoints están bajo https://removebackground.dev y aceptan solicitudes CORS, pero CORS no hace que sea seguro poner una clave en una página web: guárdala en tu servidor (ver Seguridad). Los errores son JSON: { "error": { "code": "…", "message": "…" } }.

El contrato completo está publicado como OpenAPI 3.1 (openapi.json), para generadores de clientes, Postman o tests; los asistentes de programación con IA pueden empezar por llms.txt.

POST /v1/remove

En tiempo real. Elimina el fondo de una imagen. Normalmente la imagen terminada es el cuerpo de la respuesta (image/png, image/jpeg o image/webp), por lo general tras unos segundos. Los parámetros pueden ser campos de formulario, claves JSON o valores de query string; también puedes hacer POST de los bytes de la imagen sin procesar con Content-Type: image/jpeg, image/png, image/webp o application/octet-stream. Máximo 25 MB. Consulta Envía tu imagen para cada método de entrada.

ParámetroTipoDescripción
image_filefileLa imagen (JPG, PNG o WebP), como datos de formulario multipart.
image_file_b64stringLa imagen en base64, con o sin el prefijo data:image/…;base64, (25 MB tras decodificar). Práctico desde JSON.
image_urlstringUna URL pública http(s) de la imagen. La descargamos (hasta 3 redirecciones, 15 s). Si se envían varias, gana image_file, luego image_file_b64, luego image_url y por último el cuerpo sin procesar.
formatpng | jpg | webpFormato de salida. Por defecto, png. JPG no tiene transparencia: se aplana sobre bg_color o sobre blanco.
bg_colorcolorRellena el fondo: hex (ffffff, #fff), rgb(255, 255, 255) o white, black, red, green, blue, yellow, gray / grey. transparent (por defecto) lo mantiene transparente.
sizepreview | medium | hd | fullLímite de megapíxeles, mantiene la relación de aspecto y nunca amplía: preview ≤ 0,25 MP, medium ≤ 1,5 MP, hd ≤ 4 MP, full (por defecto) la resolución original (hasta 25 MP). Se ignora si se define width o height.
croptrue | false | W:HRecorta al cuadro delimitador del sujeto. Con una relación de aspecto (1:1, 4:5, 4:3, 16:9…), el cuadro se amplía (nunca se reduce) a esa relación alrededor del sujeto; la zona fuera de la foto queda transparente (o con bg_color). Por defecto, false.
paddingpx | fracción | %Con crop: margen añadido a cada lado. 0.1 o 10% = una décima parte del ancho (izquierda/derecha) y del alto (arriba/abajo) del sujeto; "10%,7.5%" define el horizontal y el vertical por separado; 24px (o un número entero mayor que 1 sin unidad) son píxeles, hasta 500. Por defecto, 0.
channelsrgba | rgb | alphargba (por defecto): recorte transparente. rgb: opaco, aplanado sobre bg_color o blanco. alpha: máscara PNG en escala de grises (blanco = sujeto), con el mismo tamaño y recorte que el recorte normal. type=mask sigue funcionando como alias de alpha.
width / height1–6000Tamaño de salida exacto en píxeles, aplicado después de crop (prevalece sobre size). Si solo indicas uno, el otro sigue la relación de aspecto. Nunca se estira.
roix1 y1 x2 y2Región de interés, en px o % (p. ej. 0% 0% 50% 100%). Solo se conserva el sujeto que está dentro; todo lo de fuera pasa a ser fondo. Las coordenadas se refieren a la imagen original. Por defecto: la imagen completa.
fitcontain | cover | scale-downCon width y height. contain (por defecto): encaja dentro, centrado, y el resto queda transparente (o con bg_color). cover: llena el cuadro y recorta lo que sobra alrededor del sujeto. scale-down: como contain, pero nunca amplía.

Las opciones se aplican en este orden: roi, size (o width/height más adelante), crop + padding + relación de aspecto, width/height + fit, después channels o el color de fondo y, por último, el formato. Todas las opciones cuestan el mismo crédito. Los parámetros desconocidos se ignoran.

Ejemplo: JPG en HD sobre blanco, recortado al sujeto con 40 px de margen

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@product.jpg' \
  -F 'bg_color=ffffff' \
  -F 'format=jpg' \
  -F 'size=hd' \
  -F 'crop=true' \
  -F 'padding=40' \
  -o product-no-bg.jpg

Ejemplo: imagen cuadrada para marketplace, sujeto centrado con un 10% de margen

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@product.jpg' \
  -F 'crop=1:1' -F 'padding=10%' \
  -F 'width=1000' -F 'height=1000' \
  -F 'format=jpg' -F 'bg_color=white' \
  -o product-square.jpg

Ejemplo: entrada en base64, salida como máscara alfa

printf '{"image_file_b64":"%s","channels":"alpha"}' "$(base64 < portrait.jpg | tr -d '\n')" > request.json

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary @request.json \
  -o portrait-mask.png

200 OK

Los bytes de la imagen, con estas cabeceras:

CabeceraSignificado
X-Image-Width / X-Image-HeightTamaño del resultado en píxeles (también se envía como X-Width / X-Height).
X-Request-IDTu X-Request-ID si enviaste uno; si no, un id generado. Indícalo al contactar con soporte.
X-Processing-Time-MsTiempo dedicado a la solicitud (también X-Processing-Ms).
X-Matte-Confidence0–1: lo nítida que es la máscara (media de |2a − 1| sobre los píxeles, a = alfa). Cerca de 1 es un recorte limpio; valores más bajos indican muchos bordes suaves o dudosos.
X-Matte-Ambiguous-RatioProporción de píxeles con alfa estrictamente entre 0,1 y 0,9 (pelo, cristal, desenfoque de movimiento). Útil para marcar imágenes que conviene revisar.
X-Credits-RemainingTu saldo después de esta imagen.
X-Removal-IdId del resultado almacenado.
X-Job-IdId del trabajo detrás de la solicitud (se puede usar con /v1/jobs/:id).

202 Accepted (alternativa cuando la cola es larga)

Si la imagen no está terminada en unos 55 segundos, por ejemplo cuando la cola está inusualmente ocupada, recibes 202 con el JSON { id, status, status_url, result_url } (más Location y Retry-After: 2). Consulta status_url hasta que done sea true y luego descarga result_url. Se te cobra una sola vez, solo cuando la imagen sale bien. No vuelvas a enviar la imagen sin una Idempotency-Key: eso inicia un segundo trabajo. Consulta Gestiona la respuesta para ver un ejemplo completo.

GET /v1/jobs/:id

Estado de un trabajo creado con /v1/remove o /v1/batch. Misma clave; solo ves tus propios trabajos.

CampoSignificado
statusqueued, processing, succeeded, partial, failed o canceled
donetrue cuando ya no queda nada por ejecutar
total, succeeded, failed, skippedrecuento de imágenes
credits_chargedcréditos que usó este trabajo (1 por imagen procesada con éxito)
status_url, result_urldónde consultar el estado y dónde descargar
items[]por imagen: position, input, status, error { code, message } y, si sale bien, removal_id, width, height, format, result_url

GET /v1/jobs/:id/result

Los bytes de la imagen de un trabajo terminado, con las mismas cabeceras que /v1/remove. ?item=N elige una imagen de un trabajo por lotes (por defecto, 0). Responde 409 not_ready con Retry-After: 2 mientras sigue en curso, o con el error de la propia imagen si falló.

POST /v1/batch

Pon en cola hasta 100 URLs de imágenes como un solo trabajo: JSON { "image_urls": ["https://…", …], "format": "jpg", "bg_color": "ffffff", "size": "hd", "crop": "1:1", "padding": "10%" }, con las mismas opciones que /v1/remove (también channels, width, height y fit). Responde 202 al instante con { id, status, total, invalid, duplicates, status_url }. Consulta el trabajo y después obtén la result_url de cada elemento. 1 crédito por imagen que sale bien; como máximo 3 trabajos por lotes abiertos por cuenta. Guía paso a paso con respuestas de ejemplo en Lotes, de principio a fin.

Endpoint compatible con remove.bg

La API de autoservicio de remove.bg termina el 1 December 2026, 09:00 CET (anuncio). Las integraciones existentes con remove.bg funcionan aquí cambiando una línea: https://api.remove.bg/v1.0/removebg → https://removebackground.dev/v1.0/removebg, con una clave de removebackground.dev en la misma cabecera X-Api-Key. Misma cola, el mismo crédito por imagen procesada con éxito y la misma calidad de resultado que /v1/remove. Guía de migración.

POST /v1.0/removebg

Cuerpo multipart, urlencoded o JSON con los nombres de parámetros de remove.bg. Responde con los bytes de la imagen y las cabeceras de remove.bg, o con { "data": { "result_b64", "foreground_top", "foreground_left", "foreground_width", "foreground_height" } } si envías Accept: application/json. Los errores usan el formato de remove.bg: { "errors": [{ "title", "code", "detail" }] }. A diferencia de /v1/remove, nunca responde 202: espera hasta 110 segundos y luego devuelve un 503 por tiempo de espera. El trabajo sigue en marcha y se cobra si sale bien, así que reintentar esa solicitud inicia un segundo trabajo.

ParámetroEstadoNotas
image_file / image_file_b64 / image_urlCompatibleCuerpos multipart, urlencoded o JSON. JPG, PNG o WebP de hasta 25 MB.
sizeCompatibleauto, full, 4k y 50MP dan la resolución original (hasta 25 MP); preview, small y regular ≈ 0,25 MP; medium 1,5 MP; hd 4 MP. Siempre 1 crédito.
formatCompatibleauto (PNG si hay transparencia; si no, JPG), png, jpg, webp y zip (color.jpg + alpha.png).
crop / crop_marginCompatiblepx o % del sujeto, de 1 a 4 valores al estilo CSS ("10% 20%" = vertical, horizontal); como máximo 500px o 50% por lado.
roiCompatible"x1 y1 x2 y2" en px o %: solo se conserva el sujeto dentro de la región.
scale / positionCompatiblescale del 10% al 100% u original; position center, original o "x% y%".
channelsCompatiblergba (recorte) o alpha (máscara en escala de grises).
bg_colorCompatibleHex con o sin # (81d4fa), o un nombre de color. Un hex de 8 dígitos conserva el color y descarta su alfa.
bg_image_url / bg_image_fileCompatibleEl recorte se compone sobre tu imagen de fondo, ajustada en modo cover al tamaño de salida.
Accept: application/jsonCompatibleDevuelve { data: { result_b64, foreground_top, foreground_left, foreground_width, foreground_height } }.
type / type_levelAceptado, se ignoraEl sujeto se detecta automáticamente; X-Type siempre es "other".
semitransparencyAceptado, se ignoraLos bordes suaves y las zonas semitransparentes salen tal cual de la máscara del modelo.
shadow_type / shadow_opacity / add_shadowAceptado, se ignoraNo se añaden sombras.
Solicitudes largasDiferenciaEsperamos hasta 110 segundos; si una imagen no está lista para entonces, recibes un 503 que puedes reintentar (no se cobra salvo que haya terminado).

Ejemplo

curl -H "X-Api-Key: $REMOVEBG_API_KEY" \
  -F 'image_file=@photo.jpg' -F 'size=auto' \
  -F 'crop=true' -F 'crop_margin=10%' -F 'bg_color=ffffff' \
  -o no-bg.jpg https://removebackground.dev/v1.0/removebg

Cabeceras de respuesta

CabeceraSignificado
X-Width / X-HeightTamaño del resultado en píxeles.
X-Credits-ChargedCréditos que usó esta imagen: siempre 1 (las imágenes fallidas cuestan 0).
X-TypeSiempre "other" (la detección del sujeto es automática).
X-Foreground-Top / -Left / -Width / -HeightCuadro delimitador del sujeto en el resultado, en píxeles.
X-Request-IDRepite tu X-Request-ID, o un id generado. Extra.
X-Matte-Confidence / X-Matte-Ambiguous-RatioLo limpia que es la máscara (0–1) y la proporción de píxeles suaves. Extra: útil para marcar imágenes que conviene revisar.

Errores

EstadoSignificado
400Parámetro o imagen no válidos (códigos como invalid_size, invalid_crop_margin, missing_source, file_too_large, unknown_foreground).
402insufficient_credits: recarga en la página de precios.
403auth_failed: falta X-Api-Key o no es válida.
429rate_limit_exceeded.
500 / 503El procesamiento falló, superó el tiempo de espera o el servicio no está disponible momentáneamente. Reintenta; las imágenes fallidas son gratis.

GET /v1.0/account

Tu saldo con el formato de cuenta de remove.bg: { "data": { "attributes": { "credits": { "total", "subscription": 0, "payg", "enterprise": 0 }, "api": { "free_calls": 0, "sizes": "all" } } } }. Todos los créditos son de pago por uso y no caducan nunca, así que total es igual a payg. GET https://removebackground.dev/v1.0/account con tu X-Api-Key.

Errores (endpoints /v1)

Las imágenes fallidas nunca se cobran.

EstadoCódigosSignificado
400missing_image, invalid_url, invalid_body, invalid_json, invalid_image_b64, invalid_format, invalid_bg_color, invalid_size, invalid_crop, invalid_padding, invalid_type, invalid_channels, invalid_width, invalid_height, invalid_fit, invalid_roi, fetch_failed, fetch_timeout, rejected, too_many_images, invalid_imagesLa solicitud o la URL de la imagen no se pueden usar.
401unauthorizedx-api-key ausente, incorrecta o revocada.
402insufficient_credits, out_of_creditsTu saldo está a cero. Recarga en la página de precios.
404not_foundEse trabajo no existe (o no es tuyo).
409not_ready, canceled, idempotency_key_reusedGET …/result mientras el trabajo sigue en curso (reintenta tras 2 s), el trabajo se canceló o se reutilizó una Idempotency-Key para otra solicitud.
410result_unavailableEl resultado se eliminó o caducó.
413too_largeLa imagen pesa más de 25 MB.
422processing_failed, invalid_image, missing_uploadEl archivo no es una imagen legible. No se cobra.
429rate_limited, too_many_batchesHas superado el límite de solicitudes por cuenta (espera lo que indique Retry-After) o ya tienes 3 trabajos por lotes en curso.
502model_unavailable, upstream_error, …No pudimos procesar la imagen tras varios reintentos. No se cobra.
503server_paused, unavailableLa API está en pausa (antes del lanzamiento) o no está disponible momentáneamente. Reintenta más tarde.

Lotes, de principio a fin

1. Enviar

curl -X POST https://removebackground.dev/v1/batch \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "image_urls": ["https://example.com/front.jpg", "https://example.com/back.jpg"], "format": "png", "size": "hd" }'

Hasta 100 URLs públicas de imágenes, más cualquiera de las opciones de /v1/remove. Las dos URLs de ejemplo de arriba costarían hasta 2 créditos si fueran imágenes reales. La respuesta llega al instante:

202 Accepted
{
  "id": "3f6c2a9e-8d1b-4c7a-9e2f-5b8d0a1c4e77",
  "status": "queued",
  "total": 2,
  "invalid": 0,
  "duplicates": 0,
  "status_url": "https://removebackground.dev/v1/jobs/3f6c2a9e-8d1b-4c7a-9e2f-5b8d0a1c4e77"
}

invalid cuenta las entradas que no son URLs http(s) y duplicates cuenta las repetidas; ambas se descartan y nunca se cobran. Guarda el id: es la forma de retomar el trabajo tras un reinicio.

2. Consulta el trabajo

GET /v1/jobs/:id cada pocos segundos hasta que done sea true. status pasa de queued a processing y termina como succeeded, partial (algunas imágenes fallaron) o failed. Un elemento que se está reintentando muestra retrying.

{
  "id": "3f6c2a9e-…",
  "status": "partial",
  "done": true,
  "total": 2, "succeeded": 1, "failed": 1, "skipped": 0,
  "credits_charged": 1,
  "items": [
    { "position": 0, "input": "https://example.com/front.jpg", "status": "succeeded",
      "removal_id": "…", "width": 1600, "height": 1200, "format": "png",
      "result_url": "https://removebackground.dev/v1/jobs/3f6c2a9e-…/result?item=0" },
    { "position": 1, "input": "https://example.com/back.jpg", "status": "failed",
      "error": { "code": "fetch_failed", "message": "…" } }
  ]
}

3. Descarga cada resultado

GET /v1/jobs/:id/result?item=N para cada elemento correcto (o usa su result_url). item es la position empezando en cero. Las posiciones siguen tu lista después de quitar las URLs no válidas y repetidas, así que si alguno de esos contadores es mayor que 0, empareja los resultados por input y no por índice.

  • Un lote deja de contar para el límite de 3 lotes abiertos en cuanto done es true.
  • La API no tiene endpoint de cancelación, webhooks ni descarga en ZIP. Los lotes iniciados desde la página Bulk se pueden cancelar o descargar en ZIP allí.

Reintentos, duplicados y facturación

Envía una Idempotency-Key y los reintentos no cobrarán dos veces. Añade una cabecera Idempotency-Key (cualquier cadena única de hasta 255 caracteres, como un UUID) a POST /v1/remove o POST /v1/batch, una clave por imagen o por lote. Si vuelves a enviar la misma solicitud con la misma clave, recibes el trabajo que creó la primera, con Idempotent-Replayed: true: ni trabajo nuevo ni cargo nuevo, aunque la primera solicitud siga en curso. La misma clave con otra imagen u otras opciones responde 409 idempotency_key_reused. Las claves pertenecen a tu cuenta y no caducan.

Sin clave, cada POST crea un trabajo nuevo, y cada trabajo que sale bien cuesta 1 crédito (el endpoint compatible con remove.bg POST /v1.0/removebg no admite claves). Consultar un trabajo (GET /v1/jobs/…) siempre es gratis y se puede repetir sin riesgo.

IDEMPOTENCY_KEY=$(uuidgen)   # one per image; send the same one on every retry

curl -X POST https://removebackground.dev/v1/remove \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Qué cuesta un crédito

SituaciónCargo
Solicitud rechazada antes de procesarse (clave incorrecta, opción no válida, demasiado grande, sin créditos)Gratis.
La imagen no se puede procesar (422 imagen no válida, 502 tras nuestros reintentos)Gratis.
La imagen sale bien1 crédito, cobrado una sola vez, cuando sale bien. Nuestros reintentos internos no añaden cargos.
Recibes un 202Nada por ahora. El trabajo sigue en marcha y solo se cobra 1 crédito si sale bien.
Tu cliente agota el tiempo de espera o se desconecta mientras esperaEl trabajo sigue en marcha y se cobra si sale bien. El resultado aparece en tu Studio.
Envías la misma solicitud dos veces con la misma Idempotency-KeyUn solo trabajo, como máximo 1 crédito. La repetición recibe el mismo trabajo (cabecera Idempotent-Replayed: true).
Envías la misma imagen dos veces sin claveDos trabajos distintos; cada uno que sale bien cuesta 1 crédito.
Vuelves a descargar un resultado terminadoGratis, tantas veces como quieras mientras esté almacenado.
Un lote sale bien en parte1 crédito por imagen que salió bien; credits_charged en el trabajo muestra el total.
Un lote incluye la misma URL dos vecesLas repeticiones dentro de un mismo lote se descartan antes de entrar en la cola y nunca se cobran. Las URLs idénticas en lotes distintos son trabajos separados.
Te quedas sin créditos durante un loteLas imágenes ya terminadas quedan pagadas; el resto se marca como omitido (out_of_credits) y es gratis. Compra créditos y envía las URLs restantes en un lote nuevo.

Cuándo reintentar

Qué pasóQué hacer
GET /v1/jobs/:id o …/result falla (error de red, 5xx)Puedes reintentar sin riesgo: consultar un trabajo nunca crea trabajo ni cargos. Espera un poco entre intentos.
GET …/result responde 409 not_readyEspera lo que indique Retry-After (2 s) y vuelve a consultar. No reenvíes la imagen.
GET …/result responde 410 result_unavailableEl resultado almacenado se eliminó. Volver a procesar la imagen es un trabajo nuevo y cuesta 1 crédito.
POST responde 400, 413 o 422Corrige primero la solicitud o la imagen; si la envías sin cambios, recibirás la misma respuesta.
POST responde 401 o 402Corrige la clave o recarga créditos. No lo repitas en bucle.
POST responde 429 rate_limitedEspera los segundos que indique Retry-After y vuelve a enviarla (con la misma Idempotency-Key). ¿Más de 60 imágenes por minuto? Usa POST /v1/batch: una sola solicitud para hasta 100.
POST /v1/batch responde 429 too_many_batchesEspera a que termine uno de tus 3 lotes abiertos (consúltalo) y luego envía el nuevo.
POST /v1/… responde 503 (unavailable, server_paused)No se creó ningún trabajo. Reintenta tras una breve espera. (El endpoint compatible con remove.bg es distinto: su 503 por tiempo de espera significa que el trabajo sigue en marcha).
POST /v1/remove responde 502Ese trabajo falló y no se cobró. Un reintento es un trabajo nuevo.
El POST agota el tiempo de espera, se corta la conexión o recibes un 500Con Idempotency-Key: reenvía la misma solicitud con la misma clave y recibirás el trabajo original. Sin ella, puede que el trabajo ya exista y se cobre: revisa primero tu Studio.
POST responde 409 idempotency_key_reusedEsa clave ya se usó con otra imagen u otras opciones. Genera una clave nueva para cada imagen nueva.

Límites y almacenamiento

LímiteValorError si se supera
Archivo de imagen25 MB (25 × 1024 × 1024 bytes); JPG, PNG o WebP, detectado a partir de los bytes del archivo413 too_large · 422 processing_failed
Cuerpo Base64 / JSON25 MB tras decodificar (el cuerpo de la solicitud puede ocupar un tercio más)413 too_large
Resolución de entradaLas imágenes de más de 25 MP se reducen a 25 MP antes de procesarse—
Tamaño de salidawidth y height, cada uno de 1 a 6000 px400 invalid_width / invalid_height
Descarga de image_urlsolo http(s), tiempo de espera de 15 s, hasta 3 redirecciones; se rechazan las direcciones privadas, de loopback y link-local, en cada redirección400 invalid_url · fetch_failed · fetch_timeout
Espera en POST /v1/removeUnos 55 s; después, 202 con el id del trabajo202
Tamaño del lote100 URLs de imágenes por POST /v1/batch400 too_many_images
Lotes abiertos3 trabajos de varias imágenes sin terminar por cuenta (las imágenes individuales no cuentan)429 too_many_batches
Frecuencia de solicitudes60 solicitudes por minuto por cuenta, sumando POST /v1/remove, /v1/batch y /v1.0/removebg. Un lote cuenta una vez, sea cual sea su tamaño. Consultar trabajos no tiene límite429 rate_limited (con Retry-After)

Cuánto tiempo se conservan los resultados

Cada resultado se guarda de forma privada en tu cuenta durante 48 horas después de crearse y luego se elimina. Hasta entonces puedes volver a descargarlo gratis con GET /v1/jobs/:id/result o desde tu Studio. Después, los enlaces de resultado responden 410 result_unavailable; volver a procesar la imagen es un trabajo nuevo. Los registros de estado del trabajo se pueden seguir consultando cuando la imagen ya no existe. Consulta la política de privacidad para ver cómo se gestionan las subidas; no usamos tus imágenes para entrenar modelos.

Seguridad

Guarda tu clave de API en un servidor que controles. No la pongas en código del navegador, apps móviles, repositorios públicos ni URLs. Para que tus propios usuarios quiten fondos, envía sus imágenes a través de tu backend y añade ahí tu propio inicio de sesión y tus límites de gasto.

  • La API admite CORS para que funcione desde herramientas y código del servidor. Eso no hace que sea seguro poner una clave en una página web: cualquiera puede leerla ahí.
  • Todas las claves de una cuenta gastan el mismo saldo de créditos. Crea una clave distinta por app o entorno en la página de tu cuenta, para poder revocar una sin romper las demás.
  • Si se filtra una clave, revócala enseguida en la página de tu cuenta (deja de funcionar al instante) y crea una nueva. Solo guardamos un hash de cada clave, así que no podemos volver a mostrártela.

Solución de problemas

SíntomaQué está pasando
Mi PNG no se abreEl cuerpo era JSON (un trabajo 202 o un error), no una imagen. Comprueba el estado HTTP y el Content-Type antes de guardar.
Mi script agotó el tiempo de espera, pero la imagen aparece en StudioEl trabajo siguió en marcha cuando dejaste de esperar. Obtén el resultado con su id de trabajo en lugar de reenviarla.
Me cobraron dos veces por una imagenSe envió dos veces sin Idempotency-Key (a menudo por un reintento automático tras un tiempo de espera agotado). Usa una clave por imagen y reutilízala en los reintentos.
La URL se abre en mi navegador, pero la API no puede descargarlaPuede que el servidor requiera cookies o inicio de sesión, bloquee servidores, redirija más de 3 veces o tarde más de 15 s, o que la URL firmada haya caducado. Sube el archivo en su lugar.
Mi lote se detuvo a mediasRevisa items[] en el trabajo: los elementos fallidos tienen un código de error; los omitidos con out_of_credits indican que se agotó el saldo.
Una opción parece no hacer nadaLos nombres de parámetros desconocidos se ignoran sin avisar. Comprueba la ortografía con la tabla de parámetros. En /v1.0/removebg, algunas opciones de remove.bg se aceptan pero se ignoran (ver esa tabla).
El fondo no es transparenteJPG no admite transparencia. Usa format=png o webp y no definas bg_color.
El enlace del resultado devuelve 410El resultado almacenado se eliminó. Volver a procesarlo cuesta 1 crédito.