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.

5 min readSume
All posts

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.

  • getData sends 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 when terminal is true: completed, failed, or canceled.
  • The Idempotency-Key makes a resend of the same body return the original job instead of a second paid one.
  • fsPromises.writeFile takes a Buffer, so the PNG bytes go to disk unchanged. The artifact url is 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.

From the RMBG 1.0 schema in the Sume API reference and API pricing, read 2026-09-29.
QuestionAnswer
Images per requestOne image_url, a public HTTPS URL
OutputMirrored PNG artifacts with alpha
Waitingsync holds at most 30 seconds; otherwise poll status_url
Result before completion/result answers 409 job_not_completed until result_ready is true
Webhook URLPublic HTTPS only; localhost, private-network, and non-HTTPS URLs are rejected
Price$0.0225 per image

Sources

Related posts

More in Developers

All Developers posts

Written by Sume