AdScaled BG Remover API
Server-side background removal, metadata stripping, PDF and text clean-up without AI (Pro plan, API key).
Server-side versions of the AdScaled BG Remover tools: background removal, metadata stripping, PDF clean-up and text clean-up. The algorithms are the same classic (non-AI) algorithms the website runs in the browser.
Send the raw file as the request body and receive the processed file. Files are processed in memory and never stored; the output never carries metadata.
Plans. The API is part of Pro. Every call that succeeds counts as one operation. Pro includes 2,000 operations per calendar month (UTC). After that, each operation uses one prepaid credit (packs of 1,000 or 10,000 operations on the pricing page; referral bonuses are credits too). Credits never expire. When both the monthly quota and the credits are used up, the API answers 402 quota_exceeded. Failed calls are not counted.
Limits (Pro). File 15 MB, image 16 megapixels, text 2 MB, 30 requests per minute. Jobs run one after another on the server; a job that takes longer than 45 seconds is stopped (504 timeout), a full queue answers 503 busy with Retry-After.
Rate limit headers. Responses carry the IETF RateLimit-Policy and RateLimit headers (draft-ietf-httpapi-ratelimit-headers): flood = 300 requests per 60 s per client IP for every /api path, api = 30 requests per 60 s per account for authenticated calls, api-bad-key = 20 invalid keys per 600 s per IP. A 429 adds Retry-After in seconds; wait that long instead of retrying in a loop.
- OpenAPI 3.1 specification: https://bgremover.adscaled.media/api/openapi.json
- Base URL: https://bgremover.adscaled.media
- Machine-readable list of operations (no key needed): https://bgremover.adscaled.media/api/v1/tools
- API catalog (RFC 9727): https://bgremover.adscaled.media/.well-known/api-catalog
- Developer page with examples: https://bgremover.adscaled.media/developers
- Site guide for AI agents: https://bgremover.adscaled.media/llms.txt
Authentication
Send an API key as Authorization: Bearer asc_.... Keys are created on the account page of a Pro account; they can be limited to scopes (convert = processing endpoints, usage = GET /api/v1/usage), IP addresses and a lifetime. GET /api/v1/tools needs no key. Browsers may call the API from any origin (CORS *, no cookies).
Plans and limits
- The API is part of the Pro plan: 2000 operations per calendar month (UTC), then prepaid credits. Every successful call is one operation; failed calls are not counted.
- File 15 MB, image 16 megapixels, text 2 MB per request.
- Jobs run one after another; a job over 45 seconds is stopped (
504 timeout), a full queue answers503 busywithRetry-After. - Files are processed in memory and never stored; outputs carry no metadata.
Rate limits
Responses carry RateLimit-Policy and RateLimit headers (draft-ietf-httpapi-ratelimit-headers). Each policy is listed by name:
flood: 300 requests per 60 s per client IP, shared by all/apipaths.api: 30 requests per 60 s per account for calls with a valid key.api-bad-key: 20 invalid API keys per 600 s per client IP; after that every request from the address gets429until the window ends.
Example: RateLimit-Policy: "flood";q=300;w=60, "api";q=30;w=60 and RateLimit: "flood";r=297;t=41, "api";r=29;t=60 (q quota, w window in seconds, r requests left, t seconds until the window frees a request). A 429 response adds Retry-After in seconds: wait that long, do not retry in a loop.
Errors
Errors are always JSON { "error": { "code": "...", "message": "..." } } (schema Error in the OpenAPI document, referenced by every 4xx, 5xx and default response); the code is stable, the message is for people.
Versioning and deprecation
The version is part of the path (/api/v1/). Within v1 changes are only additive: new operations, new optional parameters, new response fields or headers; info.version follows semantic versioning. A breaking change gets a new path version (/api/v2/) and v1 keeps working alongside it. Before an operation or a version is retired, it is marked deprecated: true in this document, the notice is published on the developer page, and its responses carry a Deprecation header (RFC 9745), a Sunset header with the shutdown date (RFC 8594) and a Link header with rel="deprecation" pointing to the notice. A deprecated operation stays available for at least 90 days after the deprecation is announced. No operation is deprecated at the moment.
Endpoints
GET /api/v1/tools (listApiOperations)
List of operations, accepted inputs, parameters and limits.
Public, no API key needed. Lists every endpoint with its accepted inputs, parameters (names, types, allowed values, defaults) and the Pro limits. Not counted as an operation.
Authentication: none.
Example:
curl https://bgremover.adscaled.media/api/v1/tools
Responses:
200: Machine-readable description of every endpoint (no API key needed)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
GET /api/v1/usage (getApiUsage)
Quota, credits and limits of the key's account.
Needs the usage scope. Does not count as an operation.
Authentication: API key (Bearer).
Example:
curl https://bgremover.adscaled.media/api/v1/usage \
-H 'Authorization: Bearer asc_YOUR_KEY'
Responses:
200: Usage401:invalid_api_key(missing, wrong or revoked key) orkey_expired403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/remove-background (removeBackground)
Remove (or replace) the background of an image.
Classic segmentation without AI. Works best on solid or contrasting backgrounds, product photos, logos and green/blue screens. Hair or fur on a busy background and complex scenes are not separated well; use mode=rect with a tight rectangle. The image is decoded with EXIF orientation applied; the output carries no metadata.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
mode | query | no | string, one of auto, solid, chroma, rect, default auto | auto = background touching the border (photos, products); solid = one flat colour (color, detected when missing); chroma = green/blue screen (key or custom color); rect = GrabCut inside rect |
color | query | no | string | solid: background colour; chroma: custom key colour (#rrggbb, URL-encode # as %23) |
key | query | no | string, one of green, blue, default green | chroma screen colour |
tolerance | query | no | integer, 0..100 | How different from the background a pixel may be and still be removed. Defaults: auto 18, solid 12, chroma 40. |
softness | query | no | integer, 0..100, default 20 | chroma only: width of the soft transition |
contiguous | query | no | boolean, default true | solid only: remove only background connected to the border (false = the colour everywhere) |
rect | query | no | string | rect mode (required): x,y,width,height of the object in pixels of the oriented image |
grow | query | no | integer, -50..50, default 0 | Grow (+) or shrink (-) the kept area in pixels |
feather | query | no | number, 0..50, default 0 | Soften the edge (px) |
fillHoles | query | no | boolean, default false | Fill background holes fully enclosed by the object |
removeIslands | query | no | integer, 0..1000000, default 0 | Drop kept specks smaller than this many pixels |
bg | query | no | string, default transparent | transparent, a colour #rrggbb, or blur (blurred original background) |
blur | query | no | integer, 1..50, default 12 | Blur radius for bg=blur |
decontaminate | query | no | boolean, default true | Remove background colour bleeding into semi-transparent edges |
trim | query | no | boolean, default false | Crop to the object (not with bg=blur) |
padding | query | no | integer, 0..1000, default 0 | Margin around the object after trim (px) |
format | query | no | string, one of png, webp, jpg, default png | jpg needs an opaque background (bg=#rrggbb or blur) |
quality | query | no | integer, 1..100, default 90 | webp/jpg quality |
Request body (image/*, application/octet-stream): Raw image bytes: JPEG, PNG, WebP, AVIF or GIF (first frame). SVG and BMP are refused (415).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/remove-background?mode=auto&format=png' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @photo.jpg \
-o photo-no-bg.png
Responses:
200: The processed image (<name>-no-bg.pngetc.)400:invalid_parameter: a query parameter is missing or out of range, or does not fit the file (e.g. a page that does not exist); the message says which401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/strip-metadata (stripMetadata)
Remove metadata (EXIF, GPS, XMP, IPTC, document properties) from an image, PDF or Office file.
JPEG, PNG and WebP are cleaned without re-encoding (pixels untouched; the orientation flag and colour profile are kept by default). PDFs lose the document information dictionary, XMP, page thumbnails and the file ID; Office (DOCX, XLSX, PPTX) and OpenDocument files lose core/app/custom properties (author, company, last editor…), thumbnails and comment author names. GIF, BMP and AVIF are refused (415 unsupported).
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
keepOrientation | query | no | boolean, default true | Keep the EXIF orientation flag so photos stay upright |
keepColorProfile | query | no | boolean, default true | Keep the ICC colour profile |
Request body (application/octet-stream): JPEG, PNG or WebP image, PDF, or Office / OpenDocument file (DOCX, XLSX, PPTX, ODT, ODS, ODP). Password-protected files are refused (422 encrypted).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/strip-metadata' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @photo.jpg \
-o photo-clean.jpg
Responses:
200: The cleaned file in the same format as the input (Content-Type= the detected input type)400:invalid_parameter: a query parameter is missing or out of range, or does not fit the file (e.g. a page that does not exist); the message says which401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/inspect-metadata (inspectMetadata)
List the metadata found in an image, PDF or Office file.
Read-only: lists the metadata fields (EXIF, GPS, XMP, IPTC, PDF info, Office properties) and flags sensitive ones. Counts as one operation.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
Request body (application/octet-stream): JPEG, PNG or WebP image, PDF, or Office / OpenDocument file (DOCX, XLSX, PPTX, ODT, ODS, ODP). Password-protected files are refused (422 encrypted).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/inspect-metadata' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @report.pdf
Responses:
200: Found fields (values shortened to 500 characters)401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/pdf/remove-pages (removePdfPages)
Delete pages from a PDF.
Deletes the given 1-based pages and ranges; at least one page must remain.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
pages | query | yes | string | 1-based page numbers and ranges to delete; at least one page must remain |
Request body (application/pdf): Raw PDF bytes (not password-protected).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/pdf/remove-pages?pages=2,4-5' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @report.pdf \
-o report-trimmed.pdf
Responses:
200: The PDF without the pages400:invalid_parameter: a query parameter is missing or out of range, or does not fit the file (e.g. a page that does not exist); the message says which401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/pdf/remove-blank-pages (removeBlankPdfPages)
Delete blank pages from a PDF.
A page is blank when it draws nothing visible (no text, images or filled shapes; space-only text counts as blank). Scanned pages count as blank when they carry almost no ink (the normal level, the browser default). At least one page must remain.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
Request body (application/pdf): Raw PDF bytes (not password-protected).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/pdf/remove-blank-pages' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @scan.pdf \
-o scan-no-blank-pages.pdf
Responses:
200: The PDF without blank pages401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/pdf/clean (cleanPdf)
Remove annotations, links, forms, attachments, JavaScript, bookmarks, metadata or thumbnails from a PDF.
Removes the chosen interactive or hidden parts from a PDF; the visible page content stays.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
X-Filename | header | no | string | Original file name (used for the output name in Content-Disposition). ?filename= works too. |
parts | query | no | string, default annotations,links,forms,attachments,javascript,metadata | Comma list of: annotations, links, forms, attachments, javascript, bookmarks, metadata, thumbnails |
Request body (application/pdf): Raw PDF bytes (not password-protected).
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/pdf/clean?parts=annotations,links,javascript' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
--data-binary @report.pdf \
-o report-clean.pdf
Responses:
200: The cleaned PDF400:invalid_parameter: a query parameter is missing or out of range, or does not fit the file (e.g. a page that does not exist); the message says which401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.
POST /api/v1/text (cleanText)
Clean up text (duplicate lines, empty lines, spaces, accents, emojis, HTML tags…).
Applies the text operations in the given order with their default options and returns UTF-8 text.
Authentication: API key (Bearer).
| Parameter | In | Required | Type | Description |
|---|---|---|---|---|
ops | query | yes | string | Comma list applied in order: duplicate-lines, empty-lines, line-breaks, extra-spaces, leading-trailing-spaces, accents, emojis, html-tags, punctuation, numbers, urls, emails, phones, non-ascii |
Request body (text/plain): UTF-8 text (a BOM is dropped) or UTF-16 with a BOM.
Example:
curl -X POST 'https://bgremover.adscaled.media/api/v1/text?ops=duplicate-lines,extra-spaces' \
-H 'Authorization: Bearer asc_YOUR_KEY' \
-H 'Content-Type: text/plain; charset=utf-8' \
--data-binary @notes.txt \
-o notes-clean.txt
Responses:
200: The cleaned text (UTF-8)400:invalid_parameter: a query parameter is missing or out of range, or does not fit the file (e.g. a page that does not exist); the message says which401:invalid_api_key(missing, wrong or revoked key) orkey_expired402:quota_exceeded: monthly quota and credits are both used up403:plan_required(the plan has no API),scope_denied(key without the scope),ip_denied(address not in the key's allowlist)413:fileTooBig,textTooBig,tooManyPixels: over the plan limit (checked from Content-Length and the image header before decoding)415:unsupported,svg,video,audio,mismatch(extension does not match the content),binary422:empty,unreadableSize,decode,corrupt,encrypted(password-protected PDF/Office),failed(e.g. every page of the PDF is blank)429:rate_limited: too many requests per minute (per account, or 300 per IP for all of /api), or too many invalid keys from one address. Wait for Retry-After seconds.500:server_error: unexpected server error. Not counted; safe to retry later.503:busy: the processing queue is full. Retry after the number of seconds in Retry-After.504:timeout: the job took longer than 45 seconds and was stopped. Not counted.default: Any other error status (for example404 not_foundfor a mistyped path); always the same JSON error body.