Remove background from images in PHP with the LassoCut API
PHP can remove an image background with the curl extension it already has, with Guzzle, or with Laravel's HTTP client. This guide gives a tested cURL call, the same request in Guzzle with proper error handling, a Laravel version with retries, and the one property to change in the community mtownsend/remove-bg package.
Quickstart
Every request needs your key in the X-Api-Key header and exactly one image source. This example uses size=preview, which is covered by your account's 50 free previews a month (up to 10 a day). The PHP curl extension is the only requirement.
$ch = curl_init("https://api.lassocut.com/v1.0/removebg");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["X-Api-Key: " . getenv("LASSOCUT_API_KEY")],
CURLOPT_POSTFIELDS => ["image_file" => new CURLFile("photo.jpg"), "size" => "preview"],
CURLOPT_RETURNTRANSFER => true,
]);
$png = curl_exec($ch);
file_put_contents("no-bg.png", $png);
echo curl_getinfo($ch, CURLINFO_HTTP_CODE), "\n";
Tested against the production API on 27 September 2026 with this exact request; it returned a valid PNG.
The same call with Guzzle
Guzzle builds the multipart body from an array. http_errors => false lets you read the JSON error instead of catching a ClientException.
<?php
// composer require guzzlehttp/guzzle
require 'vendor/autoload.php';
use GuzzleHttp\Client;
use GuzzleHttp\Psr7\Utils;
$client = new Client(['base_uri' => 'https://api.lassocut.com/v1.0/', 'timeout' => 120]);
$res = $client->post('removebg', [
'headers' => ['X-Api-Key' => getenv('LASSOCUT_API_KEY')],
'multipart' => [
['name' => 'image_file', 'contents' => Utils::tryFopen('photo.jpg', 'r'), 'filename' => 'photo.jpg'],
['name' => 'size', 'contents' => 'full'],
['name' => 'format', 'contents' => 'png'],
],
'http_errors' => false, // read the JSON error body instead of catching an exception
]);
if ($res->getStatusCode() === 200) {
file_put_contents('no-bg.png', (string) $res->getBody());
echo 'credits charged: ', $res->getHeaderLine('X-Credits-Charged'), PHP_EOL;
} else {
$error = json_decode((string) $res->getBody(), true);
echo $res->getStatusCode(), ' ', $error['errors'][0]['title'] ?? 'unknown error', PHP_EOL;
}
A relative removebg against a base_uri ending in /v1.0/ resolves to /v1.0/removebg, so keep the trailing slash. Utils::tryFopen comes with guzzlehttp/psr7, installed alongside Guzzle.
Using it from Laravel
Laravel's Http client (Laravel 10 or later) wraps Guzzle. Keep the key in config/services.php rather than calling env() in your code, so it still works once the config is cached:
// config/services.php: 'lassocut' => ['key' => env('LASSOCUT_API_KEY')],
use Illuminate\Http\Client\RequestException;
use Illuminate\Support\Facades\Http;
use Illuminate\Support\Facades\Storage;
$response = Http::withHeaders(['X-Api-Key' => config('services.lassocut.key')])
->timeout(120)
->retry(3, 2000, fn ($e) => $e instanceof RequestException
&& in_array($e->response->status(), [429, 503]), throw: false)
->attach('image_file', Storage::get($path), basename($path))
->post('https://api.lassocut.com/v1.0/removebg', ['size' => 'full', 'format' => 'png']);
if ($response->successful()) {
Storage::put('cutouts/' . pathinfo($path, PATHINFO_FILENAME) . '.png', $response->body());
} else {
logger()->warning('LassoCut', $response->json('errors.0', []));
}
- With
attach(), the array passed topost()is sent as multipart fields next to the file. retry()here retries only429and503, with a fixed 2-second pause; it does not readRetry-After. Withthrow: false, the last response is returned instead of an exception.- For more than a handful of images, dispatch one queued job per image instead of looping inside a web request: a full-size call can take several seconds, longer on the first call after a quiet period. Limits: 22 MB per upload, 500 megapixel-images per minute per account.
Point an existing PHP client at LassoCut
Already using the mtownsend/remove-bg package (Composer) to call remove.bg? Its endpoint is a public property you can set after constructing the client:
$removebg = new \Mtownsend\RemoveBg\RemoveBg(getenv("LASSOCUT_API_KEY"));
$removebg->endpoint = 'https://api.lassocut.com/v1.0/removebg';
$removebg->file('photo.jpg')->save('no-bg.png');
Verified from the package's source on GitHub (mtownsend5512/remove-bg), read on 27 September 2026. It is a third-party, community-maintained package: not produced by LassoCut and not affiliated with remove.bg. For any other HTTP client, set its base URL to https://api.lassocut.com/v1.0 and keep the same X-Api-Key header.
Useful options
| Field | Example | Description |
|---|---|---|
size | preview, full, auto | Preview costs 0.25 credit; full and 50MP cost 1 credit; auto picks the largest size your balance allows. |
format | png, jpg, webp | Auto (default) returns PNG when the result has transparency, JPG otherwise. |
type | person, product, car | Selects the model. Auto (default) detects the subject. |
crop, crop_margin | true, "30px" | Crops the result to the subject, with an optional margin. |
bg_color | "81d4fa" | Fills the background with a hex colour, a colour name, or hex with alpha. |
Full list, including framing, shadows and background images: API reference.
Marketplace preset and shadow
A marketplace preset frames the cut-out on the canvas, white background and file size that marketplace expects, and shadow_type=cast adds a cast shadow. The response header X-Compliance says whether the result meets the rules LassoCut checks. With a preset, crop, crop_margin, scale and position are ignored. See marketplace presets.
$ch = curl_init("https://api.lassocut.com/v1.0/removebg");
curl_setopt_array($ch, [
CURLOPT_HTTPHEADER => ["X-Api-Key: " . getenv("LASSOCUT_API_KEY")],
CURLOPT_POSTFIELDS => [
"image_file" => new CURLFile("product.jpg"),
"preset" => "amazon",
"shadow_type" => "cast",
"shadow_angle" => 45,
],
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HEADER => true,
]);
$raw = curl_exec($ch);
$size = curl_getinfo($ch, CURLINFO_HEADER_SIZE);
preg_match('/^x-compliance:\s*(.+)$/mi', substr($raw, 0, $size), $m);
echo "compliance: ", trim($m[1] ?? "n/a"), "
";
file_put_contents("amazon.jpg", substr($raw, $size));
Common errors
Errors return JSON: {"errors": [{"code": "…", "title": "…"}]}. A non-2xx response still returns a body; check curl_getinfo($ch, CURLINFO_HTTP_CODE) and decode it with json_decode($png, true) when it isn't 200. Nothing is charged on an error.
| Status | When | code |
|---|---|---|
| 400 | No image, or two sources given | missing_source, multiple_sources |
| 402 | Not enough credits for this size | title Insufficient credits |
| 403 | Missing or wrong X-Api-Key | titles Missing API Key, API Key invalid |
| 429 | Rate limit reached | title Rate limit exceeded, with Retry-After |
Full list: API reference.
Next steps
Read the full API reference for every parameter and header, or the migration guide if you're moving code that already calls remove.bg. No key yet? Create a free account, or try LassoCut on your image first, no key required.