API

Remove Image Backgrounds in Ruby and Rails with an API (Net::HTTP, Faraday, Active Storage)

September 6, 20265 min readBy BG Clear Editorial

remove.bg shipped an official Ruby gem, which is why a surprising number of Rails apps have background removal wired into Active Storage callbacks. With remove.bg's API ending on 1 December 2026, those apps need a new endpoint. The bgclear API takes the same request fields, and Ruby's standard library already speaks multipart, so this is a short one: Net::HTTP, Faraday, then a Rails job that attaches the result.

In this guide

Net::HTTP, no gems

set_form with a multipart/form-data content type builds the request correctly, including the file part.

require "net/http"
require "uri"

API = URI("https://www.bgclear.ai/api/v1/remove")

def remove_background(path, out, size: "auto")
  req = Net::HTTP::Post.new(API)
  req["Authorization"] = "Bearer #{ENV.fetch("BGCLEAR_API_KEY")}"
  req.set_form(
    [["image_file", File.open(path, "rb"), { filename: File.basename(path) }],
     ["size", size],            # preview (free, ≤800px) | full (1 credit) | auto
     ["format", "png"]],        # png | webp | jpg
    "multipart/form-data"
  )

  res = Net::HTTP.start(API.host, API.port, use_ssl: true, read_timeout: 60) { |http| http.request(req) }
  unless res.is_a?(Net::HTTPSuccess)
    error = JSON.parse(res.body)["error"] rescue { "message" => res.body }
    raise "bgclear #{res.code}: #{error["message"]}"
  end
  File.binwrite(out, res.body)
  puts "credits left: #{res["X-Credits-Remaining"]}"
end

remove_background("photo.jpg", "photo-no-bg.png")

Faraday, with JSON mode for URL inputs

require "faraday"
require "faraday/multipart"

conn = Faraday.new("https://www.bgclear.ai/api/v1") do |f|
  f.request :multipart
  f.request :url_encoded
  f.headers["Authorization"] = "Bearer #{ENV.fetch("BGCLEAR_API_KEY")}"
  f.options.timeout = 60
end

# file upload → bytes
res = conn.post("remove", image_file: Faraday::Multipart::FilePart.new("photo.jpg", "image/jpeg"),
                          size: "auto")
File.binwrite("photo-no-bg.png", res.body) if res.success?

# URL input → JSON with hosted result URL (24 h, no auth)
res = conn.post("remove") do |r|
  r.headers["Content-Type"] = "application/json"
  r.headers["Accept"] = "application/json"
  r.body = { image_url: "https://example.com/shoe.jpg", size: "auto", format: "webp", bg_color: "ffffff" }.to_json
end
data = JSON.parse(res.body)   # "url", "width", "height", "credits_charged", "credits_remaining"

Rails: an Active Storage job that attaches the cutout

Run it from after_commit on the model, never inline in the request; the job retries with a back-off on 429 and stops cleanly on 402.

class RemoveBackgroundJob < ApplicationJob
  queue_as :default
  retry_on Net::ReadTimeout, wait: :polynomially_longer, attempts: 5

  def perform(product)
    return unless product.photo.attached?

    product.photo.open do |file|
      req = Net::HTTP::Post.new(URI("https://www.bgclear.ai/api/v1/remove"))
      req["Authorization"] = "Bearer #{Rails.application.credentials.bgclear_api_key}"
      req["Idempotency-Key"] = "product-#{product.id}-#{product.photo.checksum}"  # safe retries
      req.set_form([["image_file", file, { filename: product.photo.filename.to_s }],
                    ["size", "full"], ["format", "png"]], "multipart/form-data")

      res = Net::HTTP.start(req.uri.host, req.uri.port, use_ssl: true, read_timeout: 90) { |h| h.request(req) }

      case res
      when Net::HTTPSuccess
        product.cutout.attach(io: StringIO.new(res.body), filename: "#{product.id}-cutout.png",
                              content_type: "image/png")
      when Net::HTTPTooManyRequests
        retry_job(wait: res["X-RateLimit-Reset"].to_i.seconds)
      when Net::HTTPPaymentRequired
        raise "bgclear: out of credits — https://www.bgclear.ai/api-pricing/"
      else
        raise "bgclear #{res.code}: #{res.body}"
      end
    end
  end
end

Images over 4 megapixels should go through /api/v1/jobs with an X-Callback-Url pointing at a controller action — the bulk guide covers the callback receiver.

Coming from the remove.bg gem

The gem's RemoveBg.from_file("photo.jpg", size: "auto") maps to the Net::HTTP snippet with size unchanged; format:, bg_color: and crop: keep their names; type:, roi:, scale:, position: and add_shadow: have no equivalent and are ignored. The gem's zip output (format: "zip") is the one thing to replace — request png or webp instead. Credits expire at remove.bg on 1 December 2026; the full mapping is on the remove.bg API alternative page.

Frequently asked questions

Is there a bgclear gem?

No — the API is plain multipart or JSON over HTTPS and Ruby's standard library handles it, as shown. A Faraday connection is the nicest wrapper if you prefer one.

Can I get a white background for product listings?

Yes: send bg_color: "ffffff" (any hex) and format: "jpg" for the smallest marketplace-ready file.

What is the cost?

Full-resolution results are one credit each — $9 for 100, $39 for 500, $129 for 2,000; credits never expire. Preview-size results (≤800 px) are free.

How do I test edge quality first?

Use size: "preview" on a dozen of your own images — it is free and unlimited — and compare hair and glass edges before switching to full.

Ship it with the bgclear API

remove.bg-compatible endpoints, credits from $9 for 100 images, no subscription. Pay, get a key, make your first call in under two minutes.

Get API credits →

Tools for this guide

Background Removal API Free

background removal api free

Canva Background Remover Alternative

canva background remover alternative

Cheapest Background Remover API

cheapest background remover api

Keep reading

API

Remove Image Backgrounds in PHP and Laravel with an API (cURL, Guzzle, Http Client)

Plain PHP with cURL, Guzzle multipart, Laravel's Http client with attach(), a queued job for bulk, and the two-line change if you used the remove.bg PHP package.

API

Remove Image Backgrounds in Python with an API (requests, 20 Lines)

A complete Python walkthrough: single image, URL input, JSON responses, a folder script with safe retries, and async jobs for large files — no ML libraries, just requests.

API

Bulk Background Removal via API: Async Jobs, Batches of 50 and Webhooks

How to process a catalogue of thousands of images without babysitting a script: batch submission, callbacks instead of polling, credit accounting, and what to do when the queue is full.

API

7 remove.bg API Alternatives Compared (2026): Price per Image, Free Tier, Drop-in Compatibility

With remove.bg closing on 1 Dec 2026, here is what the alternatives actually charge per image, what you get free, and which ones let you keep your existing request code.