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-dataavoids 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
Recommended workflow#
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.
- Keep the original locally.
- Resize a copy so the longer side = 1024 px (Lanczos filter). Encode as JPEG at quality ≥ 90.
POSTthe resized copy to/v1.0/alpha-channel. Receive the grayscale PNG matte.- Upscale the matte to the original dimensions (bilinear or bicubic).
- Apply as straight alpha to the original RGB, or composite onto a new background.
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_KEYRequest#
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"
}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.pngThis 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
13fiStatus Codes#
| Status | Description | When it happens |
|---|---|---|
401 | Invalid API Key | Missing or invalid API key |
402 | Insufficient credit. Please top up API credits. | Account has no credits. Check balance with /available-credit |
403 | Credits Expired. Please top up API credits. If you have existing credits, they will be reactivated. | Credits have expired. Top up to reactivate |
413 | File size too large. Maximum file size is 10.0 MB | File exceeds 10 MB limit |
415 | Unsupported Media Type. Supported formats are: JPEG, PNG, WebP, TIFF, BMP, GIF. | Wrong file format |
422 | Validation Error | Missing required fields or corrupt image |
429 | Rate limit (7 request/minute) exceeded | Too many requests. Implement exponential backoff |
5xx | Internal Server Error. Please contact support: contact@withoutbg.com | Temporary server issue. Retry with backoff |
Rate & Size Limits#
- Rate limit: 7 requests/minute per API key
- Max input size: 10 MB
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-creditto track usage and set up alerts. - Security: Store API keys in environment variables or secrets managers, never in code repositories.
Troubleshooting#
- 401 errors: Verify your API key is correct and included in the
X-API-Keyheader - 402/403 credit errors: Check
/available-creditand 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
filefield 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#
- Background Removal (Binary):
POST /v1.0/image-without-background— Returns the ready-made cut-out (RGB + alpha) instead of just the mask - Alpha Matte (Base64):
POST /v1.0/alpha-channel-base64— Returns the alpha matte as Base64 JSON for browser/embedded workflows - Background Removal (Base64):
POST /v1.0/image-without-background-base64— Base64 variant of background removal - Credits:
GET /available-credit— Check remaining API credits
Quick Checklist#
- Image resized to max 1024px on the longer side (full-res masters: keep the original local and apply the matte after)
POSTto/v1.0/alpha-channelX-API-Keyheader present with valid keymultipart/form-datawithfilefield- 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