Sometimes you do not want to remove the background at all. You want to keep the scene but make the subject stand out. A blurred background (often called portrait mode or bokeh) does exactly that. FAPIhub's blur endpoint detects the subject, keeps it sharp, and blurs everything behind it in one request.

When to blur instead of remove

  • Profile photos and headshots: a soft background looks natural and professional.
  • Real estate and travel: the setting still gives context.
  • Video call snapshots and thumbnails: blur hides clutter without looking cut out.
  • Lifestyle product shots: the product stays in focus while the scene sets the mood.

Make the request

Send the image and a radius value to /v2/rembg/blur/.

curl -X POST https://fapihub.com/v2/rembg/blur/ \
  -H "ApiKey: YOUR_API_KEY" \
  -F "image=@portrait.jpg" \
  -F "radius=10" \
  --output portrait-blurred.png

The same request in Python:

import requests

with open("portrait.jpg", "rb") as image_file:
    response = requests.post(
        "https://fapihub.com/v2/rembg/blur/",
        headers={"ApiKey": "YOUR_API_KEY"},
        files={"image": image_file},
        data={"radius": 10},
        timeout=60,
    )
response.raise_for_status()

with open("portrait-blurred.png", "wb") as out:
    out.write(response.content)

Choosing the blur radius

The radius controls how strong the blur is. Higher values blur more.

RadiusEffectGood for
3 to 6Subtle softeningReal estate, lifestyle shots where the scene matters
8 to 15Clear portrait-mode lookHeadshots, profile photos, social posts
20+Heavy blur, background becomes colorThumbnails, privacy, text overlays

The right value also depends on image size. A radius that looks strong on an 800 px image looks mild on a 4,000 px photo, so test with images at the resolution you actually serve.

Blur for privacy

A strong blur is a quick way to hide personal details in the background, such as documents on a desk, faces in a crowd, or house numbers. It is a good default for user-uploaded profile photos when you cannot control where people take them.

Scale the radius to the image size

Because the same radius looks different at different resolutions, a fixed value gives inconsistent results when users upload everything from small phone screenshots to full-size camera files. A simple fix is to pick the look you like at a reference width and scale the radius proportionally. The radius parameter is an integer with a maximum of 50, so clamp the result.

from PIL import Image

REFERENCE_WIDTH = 1200   # width where you tuned the look
REFERENCE_RADIUS = 12    # radius that looked right at that width
MAX_RADIUS = 50          # API maximum


def radius_for(path: str) -> int:
    with Image.open(path) as img:
        width = img.width
    radius = round(REFERENCE_RADIUS * width / REFERENCE_WIDTH)
    return max(1, min(MAX_RADIUS, radius))


print(radius_for("portrait.jpg"))

If you resize images before upload (which also keeps them under the 10 MB limit), compute the radius from the resized width, not the original.

Blurring in Node.js

Node 18 and later ship with fetch, FormData, and Blob, so no extra packages are needed. The response body is the image itself, so you write the bytes straight to disk.

import { readFile, writeFile } from "node:fs/promises";

async function blurBackground(inputPath, outputPath, radius = 10) {
  const form = new FormData();
  form.append("image", new Blob([await readFile(inputPath)]), "photo.jpg");
  form.append("radius", String(radius));

  const response = await fetch("https://fapihub.com/v2/rembg/blur/", {
    method: "POST",
    headers: { ApiKey: process.env.FAPIHUB_API_KEY },
    body: form,
  });

  if (!response.ok) {
    const { error } = await response.json();
    throw new Error(`${response.status} ${error.code}: ${error.message}`);
  }

  await writeFile(outputPath, Buffer.from(await response.arrayBuffer()));
}

await blurBackground("portrait.jpg", "portrait-blurred.png", 12);

For a full setup with retries and streaming uploads, see the Node.js background removal guide. The same patterns apply to every effect endpoint.

Handling errors and rate limits

Errors come back as JSON with an error object containing code, message, and request_id. Log the request_id so you can reference it if you contact support.

StatusCodeWhat to do
400invalid_imageThe file is not a valid image or a parameter is malformed. Fix the input; retrying will not help.
401invalid_api_keyCheck the ApiKey header and that the key is still active in your dashboard.
402insufficient_creditsThe quota is used up. Stop the job and upgrade or top up.
429rate_limit_exceededWait for the number of seconds in the Retry-After header, then retry.
5xxServer errorRetry with backoff. These responses are not counted against your quota.

A minimal Python retry wrapper that respects Retry-After and backs off on server errors:

import time
import requests


def blur_with_retry(path: str, radius: int, attempts: int = 4) -> bytes:
    for attempt in range(attempts):
        with open(path, "rb") as image_file:
            response = requests.post(
                "https://fapihub.com/v2/rembg/blur/",
                headers={"ApiKey": "YOUR_API_KEY"},
                files={"image": image_file},
                data={"radius": radius},
                timeout=60,
            )
        if response.ok:
            return response.content
        if response.status_code == 429:
            time.sleep(int(response.headers.get("Retry-After", 5)))
            continue
        if response.status_code >= 500:
            time.sleep(2 ** attempt)
            continue
        response.raise_for_status()  # 400, 401, 402: do not retry
    raise RuntimeError(f"Gave up on {path} after {attempts} attempts")

Saving the result for the web

The endpoint returns a PNG. A blurred photo usually does not need transparency, and smooth blurred areas compress very well as JPEG or WebP, so converting before you store or serve it can cut file size noticeably. Keep the PNG if you plan to edit it again.

from PIL import Image

with Image.open("portrait-blurred.png") as img:
    img.convert("RGB").save("portrait-blurred.webp", "WEBP", quality=85)

Want to tune the blur locally? Use a mask

The blur endpoint is the simplest option when you know the radius you want. If you need to try several strengths on the same photo, or apply a different kind of effect such as darkening or desaturating the background, request a mask once from /v2/rembg/mask/ and do the blur yourself with Pillow. Every variation after that is free because it never touches the API.

from PIL import Image, ImageFilter

photo = Image.open("portrait.jpg").convert("RGB")
mask = Image.open("mask.png").convert("L").resize(photo.size)

for radius in (6, 12, 24):
    blurred = photo.filter(ImageFilter.GaussianBlur(radius))
    Image.composite(photo, blurred, mask).save(f"portrait-blur-{radius}.jpg", quality=90)

Our image mask guide covers more of what you can build from a mask.

What it costs

Each blur call is one request, priced the same as a standard background removal. Some worked examples using current plan prices:

  • Small app, about 80 new profile photos a month: fits in the free Basic plan (100 requests per month, no credit card).
  • Growing community, about 5,000 uploads a month: Pro at $15 per month covers 7,500 requests, leaving room for re-uploads and retries.
  • Irregular volume: Per Usage costs $10 per 1,000 requests, paid once, and the requests never expire.

Remember that 4xx errors count against quota, so validate file type and size before upload. Server errors (5xx) are not counted. Full details are on the pricing section.

Try it without code

Upload a photo in the playground and try different radius values before writing any code. Every plan includes the blur endpoint, and it uses the same quota as standard background removal. For other effects, see our guides on changing the background color and adding product shadows.

Frequently asked questions

What is the maximum blur radius?

The radius parameter accepts an integer up to 50. For very large photos where 50 is still not strong enough, resize the image down before sending it, or use the mask endpoint and apply a larger blur locally.

Does the blur endpoint remove the background?

No. It keeps the original background and only blurs it, while the detected subject stays sharp. If you want the background gone or replaced, use /v2/rembg/ or the color and gradient endpoints.

Can I choose the segmentation model for blur?

No. The model parameter only applies to the standard removal and mask endpoints. If you want to pick a model, request a mask with your preferred model and apply the blur yourself as shown above.

Is the blur strong enough to hide sensitive information?

A high radius makes most background detail unreadable, but always check the output at the size you serve it. For anything that must be fully hidden, a heavy blur combined with a review step is safer than relying on a fixed setting.