Remove background from image in Node.js (JavaScript API)
Remove an image background from Node.js: call a background-removal API with fetch on your server, poll the job, and save the transparent PNG.

To remove the background from an image in Node.js, call a background-removal API from your server with fetch: send the image's URL, wait for the job, then write the returned transparent PNG to disk. Keep the call on the server, because the API key must never reach browser JavaScript.
With Sume the call is POST /v1/rmbg-1.0/remove, at $0.0225 per image. Sume facts come from the RMBG 1.0 schema in the Sume API reference, served by the API reference docs, plus Authentication and Webhooks; Node.js facts come from its Global objects and File system pages. All were read on 2026-09-29.
What does the Node.js script look like?
Node.js has a global, browser-compatible fetch() (no longer experimental since v21.0.0), so the script needs no packages. Save it as cutout.mjs and run it with SUME_API_KEY set. image_url is the only required field; there is no model field.
getDatasends the key as a Bearer header and throws on any non-2xx answer, so an error stops the script with the response body.- The loop waits
next_poll_after_seconds, the suggested minimum delay, between polls, and stops whenterminalis true: completed, failed, or canceled. - The
Idempotency-Keymakes a resend of the same body return the original job instead of a second paid one. fsPromises.writeFiletakes aBuffer, so the PNG bytes go to disk unchanged. The artifacturlis a public Sume CDN URL, so that download sends no key.
import { writeFile } from "node:fs/promises";
const auth = { Authorization: `Bearer ${process.env.SUME_API_KEY}` };
async function getData(url, init = {}) {
const res = await fetch(url, { ...init, headers: { ...auth, ...init.headers } });
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
return (await res.json()).data;
}
const job = await getData("https://api.sume.com/v1/rmbg-1.0/remove", {
method: "POST",
headers: { "Content-Type": "application/json", "Idempotency-Key": "rmbg-portrait-v1" },
body: JSON.stringify({ image_url: "https://example.com/inputs/portrait.jpg", mode: "async" }),
});
let status = await getData(job.status_url);
while (!status.terminal) {
await new Promise((r) => setTimeout(r, (status.next_poll_after_seconds ?? 2) * 1000));
status = await getData(job.status_url);
}
if (status.sume_status !== "completed") throw new Error(`cutout ${status.sume_status}`);
const { result } = await getData(job.result_url);
const png = await fetch(result.artifacts[0].url);
await writeFile("cutout.png", Buffer.from(await png.arrayBuffer()));Can I remove the background in the browser?
Not by calling the API from browser JavaScript. Sume's safety rules say not to place API keys in frontend JavaScript or mobile apps; browser and mobile clients should call your backend, and your backend attaches the key. So the browser sends the image URL to your own route, and that route runs the call above. Validate the input and enforce your own authorization before forwarding it.
The image itself must be at a public HTTPS URL; the request schema has no field for file bytes. How to get a public URL for an image covers hosting.
Should I poll or use a webhook?
Polling, as in the script, suits one-off calls. For a server that handles many images, send mode: "webhook" with a webhook_url: Sume posts one event when the job completes, fails, or is canceled, signed when webhook signing is configured, and there are no progress callbacks. Remove background from images in bulk compares the two for many images.
Verify the signature over the raw body before trusting the event; Express raw body for webhook signatures shows a receiver. Keep polling available as a backup for missed deliveries.
What does it cost, and what are the limits?
Each removal costs $0.0225 per image, plus a 5.5% agent fee by default, and the public catalog says the price does not vary by image size.
| Question | Answer |
|---|---|
| Images per request | One image_url, a public HTTPS URL |
| Output | Mirrored PNG artifacts with alpha |
| Waiting | sync holds at most 30 seconds; otherwise poll status_url |
| Result before completion | /result answers 409 job_not_completed until result_ready is true |
| Webhook URL | Public HTTPS only; localhost, private-network, and non-HTTPS URLs are rejected |
| Price | $0.0225 per image |
Sources
Related posts
More in Developers
- Replicate API rate limits: 600 creates a minute, then 429
Replicate's API allows 600 prediction creates and 3,000 other requests per minute. Low credit and no card tighten it; over the limit you get a 429.
- Runway API rate limit: usage tiers, concurrency and 429s
Runway's API has no requests-per-minute limit. Usage tiers cap concurrency per model, generations per 24 hours and monthly spend.
- Scheduled AI runs: default spend cap is $1.00, only lowerable
A scheduled Action's spend cap defaults to $1.00 when unset. A per-run generation_spend_cap_usd is clamped to the smaller value. null lifts the ceiling.
- Seedance 2.5 API key: get one and send a first request
Create a Sume API key, POST to /v1/videos with model seedance-2.5, poll the job and download the file. One curl request, the auth rules and the fields to set.
Written by Sume