> ## Documentation Index
> Fetch the complete documentation index at: https://docs.poof.bg/llms.txt
> Use this file to discover all available pages before exploring further.

# Remove Background

> Remove the background from an image

The core endpoint for background removal. Send an image, get back a processed image with the background removed.

Each successful request costs 1 credit regardless of parameters; failed requests are free.

## Request

<ParamField body="image_file" type="file">
  The image file to process. Supports JPEG, PNG, and WebP formats. Maximum size: 20MB. Required unless `image_file_b64` or `image_url` is given. When several inputs are sent, `image_file` wins, then `image_file_b64`, then `image_url`.
</ParamField>

<ParamField body="image_file_b64" type="string">
  The image as a base64 string, with or without a `data:image/...;base64,` prefix. Same formats and 20MB limit (after decoding) as `image_file`.
</ParamField>

<ParamField body="image_url" type="string">
  A public `http(s)` URL to fetch the image from. Poof downloads it server-side (up to 3 redirects, 15 second timeout, 20MB). URLs that resolve to private or internal addresses are rejected with `validation_error`.
</ParamField>

<ParamField body="format" type="string" default="png">
  Output image format.

  * `png` — Lossless with transparency support
  * `jpg` — Smaller file size, no transparency
  * `webp` — Best compression with transparency
</ParamField>

<ParamField body="channels" type="string" default="rgba">
  Output color channels.

  * `rgba` — Include alpha channel (transparency)
  * `rgb` — Opaque output, uses `bg_color` for background (white by default)
  * `alpha` — Grayscale alpha mask only: white foreground, black background
</ParamField>

<ParamField body="bg_color" type="string">
  Background color when `channels` is `rgb` or `rgba`. Accepts:

  * Hex: `#ffffff`, `#fff`
  * RGB: `rgb(255, 255, 255)`
  * Named: `white`, `black`, `red`
</ParamField>

<ParamField body="size" type="string" default="full">
  Output image size preset (megapixel cap). Ignored when `width` or `height` is set.

  * `full` — Original resolution
  * `preview` — up to 0.25 megapixels
  * `medium` — up to 1.5 megapixels
  * `hd` — up to 4 megapixels
</ParamField>

<ParamField body="crop" type="boolean | string" default="false">
  Crop the output to the subject bounds, removing empty space around the subject.
  Pass `true`/`false`, or an aspect ratio like `1:1`, `4:3`, `16:9` to crop to that ratio around the subject.
</ParamField>

<ParamField body="padding" type="string" default="10%">
  Padding around the subject when `crop` is enabled, added to **each side** as a fraction (`0.1`) or percentage (`10%`) of the subject's size on that axis. Defaults to `10%`; ignored unless `crop` is set.

  Pass one value for both axes, or two comma-separated values as `horizontal,vertical` to pad the axes differently — e.g. `10%,7.5%` produces a canvas 120% of the subject's width and 115% of its height.

  | `padding` | Result |
  | - | - |
  | `0` | Tight crop to the subject |
  | `10%` | Canvas is 120% of subject width and 120% of subject height |
  | `10%,7.5%` | Canvas is 120% of subject width and 115% of subject height |
  | `5%,0` | Horizontal padding only |

  Padding is applied before any aspect-ratio expansion from `crop`. If the padded area extends beyond the original image, it is filled with transparent pixels.
</ParamField>

<ParamField body="crop_margin" type="string">
  remove.bg compatibility alias for `padding`, used only when `padding` is absent. Percentages map directly (`10%`; CSS shorthand `5% 10%` becomes `10%,5%`). Pixel values such as `10px` cannot be honoured and are ignored.
</ParamField>

<ParamField body="width" type="integer">
  Output width in pixels, `1`–`6000`. On its own, the height follows the image's aspect ratio. Together with `height`, the image is fitted into a `width` × `height` canvas according to `fit`.

  The aspect ratio is always preserved — the image is never stretched or squeezed. Images smaller than the target are upscaled unless `fit` is `scale-down`. Applied after `crop`, and overrides `size`.
</ParamField>

<ParamField body="height" type="integer">
  Output height in pixels, `1`–`6000`. On its own, the width follows the image's aspect ratio. Together with `width`, the image is fitted into a `width` × `height` canvas according to `fit`.
</ParamField>

<ParamField body="fit" type="string" default="contain">
  How to fit the image into `width`/`height`. The image is never stretched.

  * `contain` — scale the image to fit inside the canvas and centre it. The remaining area is transparent, or filled with `bg_color` (white for `jpg`).
  * `cover` — scale the image to fill the canvas and crop the overflow, keeping the subject centred.
  * `scale-down` — like `contain`, but never enlarges: an image smaller than the target keeps its native size (centred on the canvas when both dimensions are set).

  `contain` and `cover` only differ when both `width` and `height` are set.

  | Parameters | Result |
  | - | - |
  | `width=500` | 500px wide, height follows the aspect ratio |
  | `width=500&height=500` | 500 × 500, image fitted inside and centred, padding transparent |
  | `width=500&height=500&fit=cover` | 500 × 500, image fills the canvas, overflow cropped around the subject |
  | `crop=true&width=500&height=500` | Subject cropped (with `padding`), then fitted into 500 × 500 |
  | `width=500&height=500&fit=scale-down` | 500 × 500, a smaller image is centred at its native size, not enlarged |
</ParamField>

## Response

The API returns the processed image directly in the response body. Check the response headers for metadata:

| Header | Description |
| - | - |
| `Content-Type` | MIME type of the image (`image/png`, `image/jpeg`, `image/webp`) |
| `X-Request-ID` | Unique request ID for support inquiries |
| `X-Processing-Time-Ms` | Processing time in milliseconds |
| `X-Image-Width` | Output image width in pixels |
| `X-Image-Height` | Output image height in pixels |
| `X-Matte-Confidence` | Confidence in the alpha matte, `0`–`1`. `1` means a fully decisive mask; lower values mean the model hedged. Heuristic, not a calibrated probability |
| `X-Matte-Ambiguous-Ratio` | Fraction of pixels with alpha between 0.1 and 0.9, `0`–`1`. High values indicate large uncertain regions — useful for flagging results for manual review |

## Examples

### Basic Usage

Remove background and save as PNG with transparency:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -o result.png
  ```

  ```python Python theme={null}
  from poof import Poof

  client = Poof(api_key="YOUR_API_KEY")
  result = client.remove_background("photo.jpg")
  result.save("result.png")
  ```

  ```typescript TypeScript theme={null}
  import { Poof } from '@poof-bg/js';
  import fs from 'fs/promises';

  const poof = new Poof({ apiKey: 'YOUR_API_KEY' });
  const image = await fs.readFile('photo.jpg');
  const result = await poof.removeBackground(image);
  await fs.writeFile('result.png', Buffer.from(result.data));
  ```
</CodeGroup>

### White Background

Get a JPEG with a white background (great for e-commerce):

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@product.jpg" \
    -F "format=jpg" \
    -F "channels=rgb" \
    -F "bg_color=#ffffff" \
    -o product-white-bg.jpg
  ```

  ```python Python theme={null}
  result = client.remove_background(
      "product.jpg",
      format="jpg",
      channels="rgb",
      bg_color="#ffffff"
  )
  result.save("product-white-bg.jpg")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, {
    format: 'jpg',
    channels: 'rgb',
    bgColor: '#ffffff'
  });
  ```
</CodeGroup>

### Alpha Mask Only

Get just the grayscale alpha mask (white = foreground, black = background) — useful for custom compositing pipelines:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -F "channels=alpha" \
    -o mask.png
  ```

  ```python Python theme={null}
  result = client.remove_background("photo.jpg", channels="alpha")
  result.save("mask.png")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, { channels: 'alpha' });
  await fs.writeFile('mask.png', Buffer.from(result.data));
  ```
</CodeGroup>

### Cropped Thumbnail

Get a small, cropped preview:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -F "size=preview" \
    -F "crop=true" \
    -o thumbnail.png
  ```

  ```python Python theme={null}
  result = client.remove_background(
      "photo.jpg",
      size="preview",
      crop=True
  )
  result.save("thumbnail.png")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, {
    size: 'preview',
    crop: true
  });
  ```
</CodeGroup>

### Consistent Product Shots

Crop to the subject, then add 10% horizontal and 7.5% vertical padding (a 120% × 115% canvas) so every image has the same margins:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@product.jpg" \
    -F "crop=true" \
    -F "padding=10%,7.5%" \
    -o product-cropped.png
  ```

  ```python Python theme={null}
  result = client.remove_background(
      "product.jpg",
      crop=True,
      padding="10%,7.5%"
  )
  result.save("product-cropped.png")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, {
    crop: true,
    padding: '10%,7.5%'
  });
  ```
</CodeGroup>

### Fixed Output Size

Resize every result to exactly 500 × 500 — ideal for marketplace listings and product grids. The subject is cropped, padded, then fitted into the square canvas without distortion:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@product.jpg" \
    -F "crop=true" \
    -F "width=500" \
    -F "height=500" \
    -o product-500.png
  ```

  ```python Python theme={null}
  result = client.remove_background("product.jpg", crop=True, width=500, height=500)
  result.save("product-500.png")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, { crop: true, width: 500, height: 500 });
  ```
</CodeGroup>

Use `fit=cover` to fill the canvas edge to edge instead (the overflow is cropped around the subject), and add `bg_color` to fill the padded area with a colour:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -F "width=1080" \
    -F "height=1080" \
    -F "fit=cover" \
    -F "format=jpg" \
    -F "bg_color=#ffffff" \
    -o square-1080.jpg
  ```

  ```python Python theme={null}
  result = client.remove_background(
      "photo.jpg",
      width=1080,
      height=1080,
      fit="cover",
      format="jpg",
      bg_color="#ffffff"
  )
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, {
    width: 1080,
    height: 1080,
    fit: 'cover',
    format: 'jpg',
    bgColor: '#ffffff',
  });
  ```
</CodeGroup>

Set only `width` (or only `height`) to scale to that dimension and let the other follow the aspect ratio. Use `fit=scale-down` if small images should keep their native size rather than being enlarged to the target:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@icon.png" \
    -F "width=1000" \
    -F "height=1000" \
    -F "fit=scale-down" \
    -o icon-1000.png
  ```

  ```python Python theme={null}
  result = client.remove_background("icon.png", width=1000, height=1000, fit="scale-down")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, { width: 1000, height: 1000, fit: 'scale-down' });
  ```
</CodeGroup>

### WebP for Web

Optimal format for web delivery:

<CodeGroup>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -F "format=webp" \
    -o result.webp
  ```

  ```python Python theme={null}
  result = client.remove_background("photo.jpg", format="webp")
  result.save("result.webp")
  ```

  ```typescript TypeScript theme={null}
  const result = await poof.removeBackground(image, { format: 'webp' });
  ```
</CodeGroup>

## Error Responses

All errors return a flat JSON body (`{ "code", "message", "details"?, "request_id", "doc_url" }`) and carry an `X-Request-ID` header. Failed requests are not billed.

| Status | Code | Description |
| - | - | - |
| 400 | `validation_error` | Invalid parameter value or non-multipart body |
| 400 | `missing_image` | No `image_file` part provided |
| 400 / 413 | `image_too_large` | Image exceeds the 20 MB limit (413 when rejected by the processing service) |
| 401 | `authentication_error` | `x-api-key` missing or not recognised |
| 402 | `payment_required` | Monthly credits used up |
| 403 | `permission_denied` | Endpoint or feature not included in your plan |
| 422 | `invalid_image` | File could not be decoded as PNG, JPEG or WebP |
| 429 | `rate_limit_exceeded` | Per-plan requests-per-minute limit or global per-IP limit hit |
| 500 | `processing_failed` | The model or encoder failed on this image |
| 500 | `internal_server_error` | Unexpected server error, retry later |
| 502 / 503 / 504 | `upstream_error` | Processing service unreachable, unavailable, or timed out; retry with backoff |

See [API Error Codes](/errors/list) for detailed troubleshooting.

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST https://api.poof.bg/v1/remove \
    -H "x-api-key: YOUR_API_KEY" \
    -F "image_file=@photo.jpg" \
    -F "format=png" \
    -F "size=full" \
    -o result.png
  ```
</RequestExample>


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.