Alpha Matte (Binary)#

Generate a grayscale alpha matte (transparency mask) for an input image. The response is a binary PNG where pixel intensity encodes opacity (0 = fully transparent, 255 = fully opaque). This is the smallest, fastest transfer of all four endpoints, ideal for high-throughput server pipelines.

How the model works#

The model runs inference at a maximum of 1024 pixels on the longer side. If you send a larger image, the API downscales it to 1024 for inference, interpolates the matte back to your input dimensions, and returns it at your original resolution.

  • Edge precision is capped at 1024px. Sending a 4000px image returns a 4000px matte, but the edge detail is whatever was captured at 1024. Pre-resizing client-side gives no quality loss and a much smaller request.
  • This is the most efficient endpoint on the wire. A 1-channel grayscale PNG over raw multipart/form-data avoids both the extra channels of a cutout and the ~33% base64 inflation. For batch and high-volume pipelines, prefer it.
  • You keep the full-resolution original locally and apply the matte yourself, so a 1024px proxy is enough to process a full-resolution master (see the recommended workflow).

When to Use This Endpoint#

Use the binary alpha matte endpoint when:

  • Server-to-server workflows: Direct file I/O without JSON or base64 overhead
  • CLI tools and scripts: Save the mask directly to disk
  • High-throughput pipelines: The smallest per-request payload of any endpoint here
  • Full-resolution masters: Send a 1024px proxy, apply the matte to your original locally (see below)
  • Multi-output rendering: One mask, many composites (backgrounds, shadows, glows, blurs) without re-calling the API
  • Non-destructive editing: Keep RGB and alpha separate, apply straight alpha, refine edges yourself
Binary vs Base64: Choose binary for server environments and file-based workflows. Use the Base64 variant for browser-based apps, JSON APIs, or when embedding masks in structured data.
Matte vs Cutout: Use this endpoint when you need the transparency mask itself for compositing or a full-resolution master. If you just want a ready-made cut-out image with transparent background, use Background Removal (Binary) instead.

For any image larger than 1024px on the longer side, this is the fastest, highest-quality path. You keep the full-resolution original and only ship a cheap proxy through the API.

  1. Keep the original locally.
  2. Resize a copy so the longer side = 1024 px (Lanczos filter). Encode as JPEG at quality ≥ 90.
  3. POST the resized copy to /v1.0/alpha-channel. Receive the grayscale PNG matte.
  4. Upscale the matte to the original dimensions (bilinear or bicubic).
  5. Apply as straight alpha to the original RGB, or composite onto a new background.
Edge quality note: Upscaling the matte means edges carry only the precision captured at 1024px. For most subjects (people, products, animals) this is excellent. For very fine hair against a busy background at 4K, the matte precision, not your RGB, is the limiting factor.

Python (Pillow): resize, request, apply#

Recommended workflow — Python

Resize proxy, request the binary matte, upscale, apply to the original

1from PIL import Image
2import io, os, requests
3
4API_KEY = os.environ["WITHOUTBG_API_KEY"]
5
6# 1. Keep original
7orig = Image.open("input.jpg").convert("RGB")
8orig_w, orig_h = orig.size
9
10# 2. Resize proxy to max 1024px, encode JPEG q=90
11scale = min(1.0, 1024 / max(orig_w, orig_h))
12proxy = orig.resize((round(orig_w * scale), round(orig_h * scale)), Image.LANCZOS)
13buf = io.BytesIO()
14proxy.save(buf, format="JPEG", quality=90)
15buf.seek(0)
16
17# 3. Request the binary matte
18r = requests.post(
19    "https://api.withoutbg.com/v1.0/alpha-channel",
20    headers={"X-API-Key": API_KEY},
21    files={"file": ("proxy.jpg", buf, "image/jpeg")},
22    timeout=60,
23)
24r.raise_for_status()
25
26# 4. Decode matte and upscale to original dimensions
27matte = Image.open(io.BytesIO(r.content)).convert("L")
28matte = matte.resize((orig_w, orig_h), Image.BICUBIC)
29
30# 5. Apply straight alpha to the full-resolution original
31orig.putalpha(matte)
32orig.save("output.png")

Endpoint#

POST /v1.0/alpha-channel

Base URL: https://api.withoutbg.com

Description: Returns the alpha channel (mask) of the processed image.

Consumes: multipart/form-data

Produces: image/png (grayscale)

Authentication#

Send your API key in the request header:

Authentication Header

X-API-Key: YOUR_API_KEY
Security: Never embed API keys in client-side code. Use environment variables or a secrets manager, and proxy requests through your backend.

Request#

Headers#

  • X-API-Key (required) - Your API key

Body (multipart/form-data)#

  • file (required) - The image file to process

Supported input formats#

JPEG, PNG, WebP, TIFF, BMP, GIF. Max file size: 10 MB.

Response#

Success (200 OK)#

  • Content-Type: image/png
  • Body: Binary PNG containing the grayscale alpha matte

The response is a grayscale image where:

  • White (255) = fully opaque foreground
  • Black (0) = fully transparent background
  • Gray values = partial transparency (soft edges, hair, etc.)

Error Responses#

All errors return JSON:

Error Response Format

{
  "detail": "Error message here"
}
Rate limit: 7 requests per minute per API key
Examples

Examples#

cURL#

cURL Example

Upload an image file and save the alpha matte

curl -X POST "https://api.withoutbg.com/v1.0/alpha-channel" \
  -H "X-API-Key: $WITHOUTBG_API_KEY" \
  -F "file=@/path/to/input.jpg" \
  --output alpha-mask.png

This saves the alpha matte to alpha-mask.png.

Node.js (sharp): request and apply#

Applying the matte is the whole point. This requests the mask and composites it onto the original RGB to produce a transparent PNG.

Request and Apply — Node.js

npm install sharp

1import sharp from "sharp";
2import fs from "node:fs";
3import FormData from "form-data";
4
5const origBuffer = fs.readFileSync("input.jpg");
6const { width, height } = await sharp(origBuffer).metadata();
7
8const form = new FormData();
9form.append("file", origBuffer, { filename: "input.jpg" });
10
11const res = await fetch("https://api.withoutbg.com/v1.0/alpha-channel", {
12  method: "POST",
13  headers: { "X-API-Key": process.env.WITHOUTBG_API_KEY, ...form.getHeaders() },
14  body: form,
15});
16if (!res.ok) throw new Error(`HTTP ${res.status}: ${await res.text()}`);
17
18// Matte comes back at the input resolution; align to the original just in case
19const matteBuffer = Buffer.from(await res.arrayBuffer());
20const matteRaw = await sharp(matteBuffer)
21  .resize(width, height)
22  .raw()
23  .toBuffer();
24
25await sharp(origBuffer)
26  .joinChannel(matteRaw, { raw: { width, height, channels: 1 } })
27  .png()
28  .toFile("output.png");

Batch processing (throttled for 7 req/min)#

The rate limit is 7 requests per minute. Throttle the batch and back off on 429 so a large job doesn't fail partway through.

Throttled Batch (Python)

Space requests ~8.6s apart and retry 429s with exponential backoff

1import os
2import time
3import requests
4
5API = "https://api.withoutbg.com/v1.0/alpha-channel"
6HEADERS = {"X-API-Key": os.environ["WITHOUTBG_API_KEY"]}
7MIN_INTERVAL = 60 / 7  # ~8.6s between requests to stay under 7/min
8
9def get_matte(path: str, out_path: str, max_retries: int = 5) -> None:
10    for attempt in range(max_retries):
11        with open(path, "rb") as f:
12            r = requests.post(API, headers=HEADERS, files={"file": f}, timeout=60)
13        if r.status_code == 200:
14            with open(out_path, "wb") as out:
15                out.write(r.content)
16            return
17        if r.status_code == 429:
18            time.sleep(min(2 ** attempt, 30))  # exponential backoff, capped
19            continue
20        r.raise_for_status()
21    raise RuntimeError(f"Failed after {max_retries} retries: {path}")
22
23inputs = ["a.jpg", "b.jpg", "c.jpg"]
24for path in inputs:
25    get_matte(path, path.replace(".jpg", "-matte.png"))
26    time.sleep(MIN_INTERVAL)

cURL with error handling#

On error the body is JSON, not a PNG. Inspect the saved file instead of firing a second request.

cURL with Error Handling

Production-ready cURL example with proper error handling

1set -euo pipefail
2API=https://api.withoutbg.com/v1.0/alpha-channel
3
4http_code=$(curl -sS -w "%{http_code}" -o alpha-mask.png \
5  -H "X-API-Key: $WITHOUTBG_API_KEY" \
6  -F "file=@input.jpg" "$API")
7
8if [ "$http_code" != "200" ]; then
9  echo "Request failed with status: $http_code" >&2
10  cat alpha-mask.png >&2   # error body is JSON
11  rm -f alpha-mask.png
12  exit 1
13fi
Status Codes & Limits

Status Codes#

HTTP status codes and their meanings for the Alpha Matte (Binary) API
StatusDescriptionWhen it happens
401Invalid API KeyMissing or invalid API key
402Insufficient credit. Please top up API credits.Account has no credits. Check balance with /available-credit
403Credits Expired. Please top up API credits. If you have existing credits, they will be reactivated.Credits have expired. Top up to reactivate
413File size too large. Maximum file size is 10.0 MBFile exceeds 10 MB limit
415Unsupported Media Type. Supported formats are: JPEG, PNG, WebP, TIFF, BMP, GIF.Wrong file format
422Validation ErrorMissing required fields or corrupt image
429Rate limit (7 request/minute) exceededToo many requests. Implement exponential backoff
5xxInternal Server Error. Please contact support: contact@withoutbg.comTemporary server issue. Retry with backoff

Rate & Size Limits#

  • Rate limit: 7 requests/minute per API key
  • Max input size: 10 MB
Best Practices

Best Practices#

  • Resize to 1024px before sending: The model caps at 1024px, so a 1024px proxy gives the same matte quality with a far smaller request. Keep the full-res original locally and apply the matte after (see the recommended workflow).
  • Apply straight alpha: When compositing, multiply alpha by the RGB values yourself to avoid dark halos at semi-transparent edges.
  • Cache and reuse the matte: Generate multiple composites (backgrounds, shadows, blurs) from one mask without re-calling the API.
  • Throttle batches: Stay within 7 requests/minute. Space requests ~8.6s apart and back off on 429 (see the batch example).
  • Timeouts: Set HTTP timeouts of at least 60 seconds to cover upload and processing time.
  • Retries: Implement exponential backoff for transient 429 and 5xx errors.
  • Monitor credits: Poll /available-credit to track usage and set up alerts.
  • Security: Store API keys in environment variables or secrets managers, never in code repositories.
Troubleshooting

Troubleshooting#

  • 401 errors: Verify your API key is correct and included in the X-API-Key header
  • 402/403 credit errors: Check /available-credit and top up if needed
  • 413 errors: Input image exceeds 10 MB. Compress or resize before uploading
  • 415 errors: Ensure the file is one of the supported formats (JPEG, PNG, WebP, TIFF, BMP, GIF)
  • 422 errors: Verify the file field is present and contains a valid image
  • 429 rate limit: Throttle to 7 requests/minute and implement exponential backoff
  • Mask appears all black/white: Some viewers don't render grayscale PNGs well. Open in an image editor to verify the gradient
  • Halos or dark edges after compositing: You are applying premultiplied alpha. Use straight alpha instead
  • Soft edges at high resolution: Expected. Edge precision is capped at 1024px inference. Refine (erode, feather) if needed for your target resolution
Related Endpoints
Quick Checklist

Quick Checklist#

  • Image resized to max 1024px on the longer side (full-res masters: keep the original local and apply the matte after)
  • POST to /v1.0/alpha-channel
  • X-API-Key header present with valid key
  • multipart/form-data with file field
  • File is under 10 MB and in supported format
  • HTTP timeout set to at least 60 seconds
  • Save response body as *.png
  • Matte upscaled to original dimensions before applying
  • Straight alpha applied to original RGB, not premultiplied
  • Throttle batches to 7 requests/minute with exponential backoff on 429
  • Never expose API keys in client-side code