Echtzeit-API

API zur Hintergrundentfernung: eine Anfrage rein, fertiges PNG raus.

Lade eine Datei hoch, sende eine öffentliche Bild-URL oder übergib Base64. Die meisten Einzelbilder kommen fertig in derselben HTTP-Antwort zurück, meist in wenigen Sekunden. Dauert eines länger, bekommst du eine Job-ID, mit der du das Ergebnis abrufst, ohne das Bild erneut zu senden. Für große Mengen gibt es einen Batch-Endpunkt.

1 Credit pro erfolgreichem Bild · fehlgeschlagene Bilder sind kostenlos · Schlüssel in deinem Konto

$ curl -X POST https://removebackground.dev/v1/remove \
    -H "x-api-key: $REMOVEBG_API_KEY" \
    -F 'image_file=@dog.jpg' -o dog.png

← 200 OK · image/png · meist wenige Sekunden
  dog.png gespeichert (transparent, volle Auflösung)
1 Dein Bild2 Eine HTTP-Anfrage3 PNG in der Antwort

Schnellstart

Kopieren, einfügen, YOUR_API_KEY ersetzen. Jedes Beispiel speichert das Ergebnis direkt in einer Datei; die Beispiele für JavaScript und Python warten außerdem bei einem 202.

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Bild senden

POST /v1/remove nimmt das Bild auf vier Arten entgegen. Sende eine davon; enthält eine Anfrage mehrere, gewinnt image_file, dann image_file_b64, dann image_url, dann der rohe Body. Diese Beispiele lesen deinen Schlüssel aus der Umgebungsvariable REMOVEBG_API_KEY (setze sie mit export REMOVEBG_API_KEY=…); beachte die doppelten Anführungszeichen, damit die Shell den Wert einsetzt.

curl -X POST https://removebackground.dev/v1/remove \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Multipart-Formulardaten, Feld image_file. JPG, PNG oder WebP, bis 25 MB.

Jedes Beispiel speichert den Body in einer Datei. Diese Datei ist nur dann ein Bild, wenn der Status 200 ist; siehe Antwort verarbeiten.

Antwort verarbeiten

Die meisten Einzelbilder kommen fertig in derselben Antwort zurück. Ist die Warteschlange ungewöhnlich voll und dauert ein Bild länger als etwa 55 Sekunden, bekommst du stattdessen 202 Accepted mit einer Job-ID. Der Job läuft weiter: Rufe sein Ergebnis mit der ID ab. Würdest du das Bild erneut senden, startet ein zweiter Job, der einen zweiten Credit kosten kann.

StatusBodyWas tun
200Das Bild (image/png, image/jpeg oder image/webp)Speichern. Nutze den Content-Type, um die Dateiendung zu wählen.
202JSON: { id, status, status_url, result_url }Kein Bild. Warte ein paar Sekunden und rufe dann result_url per GET ab. Sende das Bild nicht erneut.
4xx / 5xxJSON: { "error": { "code", "message" } }Kein Bild. Lies den Code (siehe Fehler) und speichere den Body nicht als Bild.

Ein vollständiges Beispiel

Verarbeitet das fertige Bild, einen 202, einen fehlgeschlagenen Job und ein lokales Zeitlimit. Es sendet das Bild nur einmal und wiederholt nur die unbedenklichen Statusabfragen.

import os
import time
import uuid

import requests

API = "https://removebackground.dev"
KEY = os.environ["REMOVEBG_API_KEY"]  # keep the key on your server
EXT = {"image/png": ".png", "image/jpeg": ".jpg", "image/webp": ".webp"}


def save(res, stem):
    """Save an image response with the right extension; raise on anything else."""
    mime = res.headers.get("Content-Type", "").split(";")[0]
    if res.status_code != 200 or mime not in EXT:
        raise RuntimeError(f"HTTP {res.status_code}: {res.text[:500]}")
    path = stem + EXT[mime]
    with open(path, "wb") as f:
        f.write(res.content)
    return path


def remove_background(image_url, stem="result", max_wait=300):
    s = requests.Session()
    s.headers["x-api-key"] = KEY

    # One key per image: resending with the same key returns the same job, never a second
    # charge, so this POST is safe to retry after a timeout or a dropped connection.
    idem = {"Idempotency-Key": str(uuid.uuid4())}
    for attempt in range(3):
        try:
            res = s.post(f"{API}/v1/remove", data={"image_url": image_url}, headers=idem, timeout=(10, 120))
            break
        except requests.ConnectionError:
            if attempt == 2:
                raise
            time.sleep(2)
    if res.status_code != 202:
        return save(res, stem)  # 200 = the image; anything else raises

    # 202: still processing. Wait for the same job; never send the image again.
    job_id = res.json()["id"]
    deadline = time.monotonic() + max_wait
    while time.monotonic() < deadline:
        time.sleep(2)  # the API sends Retry-After: 2
        res = s.get(f"{API}/v1/jobs/{job_id}/result", timeout=30)
        if res.status_code == 409 and res.json()["error"]["code"] == "not_ready":
            continue
        return save(res, stem)  # the image, or the job's own error
    raise TimeoutError(f"Job {job_id} is still running. Check it later at /v1/jobs/{job_id}.")


print(remove_background("https://example.com/photo.jpg"))

Benötigt Python 3 und requests (pip install requests).

  • Wenn du dein Skript stoppst, stoppt das nicht den Job; er kann trotzdem fertig werden und berechnet werden. Sein Ergebnis erscheint in deinem Studio.
  • Die Zeitlimits legst du selbst fest, sie sind kein Versprechen von uns; die meisten Bilder sind in wenigen Sekunden fertig.
  • Der remove.bg-kompatible Endpunkt verhält sich anders: Er antwortet nie mit 202 (siehe unten).

Authentifizierung

Sende deinen API-Schlüssel im Header x-api-key. Erstelle und widerrufe Schlüssel auf deiner Kontoseite; jeder Aufruf verbraucht Credits dieses Kontos. Alle Endpunkte liegen unter https://removebackground.dev und akzeptieren CORS-Anfragen, aber CORS macht einen Schlüssel nicht sicher für den Einsatz in einer Webseite: Bewahre ihn auf deinem Server auf (siehe Sicherheit). Fehler kommen als JSON: { "error": { "code": "…", "message": "…" } }.

Der vollständige Vertrag ist als OpenAPI 3.1 (openapi.json) veröffentlicht, für Client-Generatoren, Postman oder Tests; KI-Coding-Assistenten können mit llms.txt starten.

POST /v1/remove

Echtzeit. Entfernt den Hintergrund aus einem Bild. In der Regel ist das fertige Bild der Antwort-Body (image/png, image/jpeg oder image/webp), meist nach wenigen Sekunden. Parameter können Formularfelder, JSON-Schlüssel oder Query-String-Werte sein; du kannst auch die rohen Bild-Bytes per POST senden, mit Content-Type: image/jpeg, image/png, image/webp oder application/octet-stream. Maximal 25 MB. Alle Eingabemethoden unter Bild senden.

ParameterTypBeschreibung
image_filefileDas Bild (JPG, PNG oder WebP) als Multipart-Formulardaten.
image_file_b64stringDas Bild als Base64, mit oder ohne Präfix data:image/…;base64, (25 MB nach dem Dekodieren). Praktisch aus JSON heraus.
image_urlstringEine öffentliche http(s)-URL des Bildes. Wir laden es herunter (bis zu 3 Weiterleitungen, 15 s). Werden mehrere gesendet, gewinnt image_file, dann image_file_b64, dann image_url, dann der rohe Body.
formatpng | jpg | webpAusgabeformat. Standard: png. JPG hat keine Transparenz: Es wird auf bg_color oder Weiß reduziert.
bg_colorFarbeFüllt den Hintergrund: Hex (ffffff, #fff), rgb(255, 255, 255) oder white, black, red, green, blue, yellow, gray / grey. transparent (Standard) lässt ihn transparent.
sizepreview | medium | hd | fullMegapixel-Obergrenze, Seitenverhältnis bleibt erhalten, nie hochskaliert: preview ≤ 0,25 MP, medium ≤ 1,5 MP, hd ≤ 4 MP, full (Standard) die Originalauflösung (bis 25 MP). Wird ignoriert, wenn width oder height gesetzt ist.
croptrue | false | W:HSchneidet auf den Begrenzungsrahmen des Motivs zu. Mit Seitenverhältnis (1:1, 4:5, 4:3, 16:9 …) wird der Rahmen danach rund um das Motiv auf dieses Verhältnis erweitert (nie verkleinert); Bereiche außerhalb des Fotos sind transparent (oder bg_color). Standard: false.
paddingpx | Bruchteil | %Mit crop: Rand, der an jeder Seite hinzugefügt wird. 0.1 oder 10% = ein Zehntel der Breite (links/rechts) bzw. Höhe (oben/unten) des Motivs; "10%,7.5%" legt horizontal und vertikal getrennt fest; 24px (oder eine ganze Zahl über 1 ohne Einheit) sind Pixel, bis 500. Standard: 0.
channelsrgba | rgb | alphargba (Standard): transparenter Freisteller. rgb: deckend, auf bg_color oder Weiß reduziert. alpha: Graustufen-PNG-Maske (Weiß = Motiv), gleiche Größe und gleicher Zuschnitt wie der Freisteller. type=mask funktioniert weiterhin als Alias für alpha.
width / height1–6000Exakte Ausgabegröße in Pixeln, angewendet nach crop (überschreibt size). Ist nur einer der Werte gesetzt, folgt der andere dem Seitenverhältnis. Nie verzerrt.
roix1 y1 x2 y2Interessensbereich, in px oder % (z. B. 0% 0% 50% 100%). Nur das Motiv darin bleibt erhalten; alles außerhalb wird Hintergrund. Koordinaten beziehen sich auf das Originalbild. Standard: das ganze Bild.
fitcontain | cover | scale-downMit width und height. contain (Standard): einpassen, zentriert, der Rest transparent (oder bg_color). cover: den Rahmen füllen, Überstand rund um das Motiv wird abgeschnitten. scale-down: wie contain, aber nie vergrößert.

Optionen werden in dieser Reihenfolge angewendet: roi, size (bzw. später width/height), crop + padding + Seitenverhältnis, width/height + fit, dann channels oder Hintergrundfarbe, dann das Format. Jede Option kostet gleich 1 Credit. Unbekannte Parameter werden ignoriert.

Beispiel: HD-JPG auf Weiß, auf das Motiv zugeschnitten mit 40 px Rand

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@product.jpg' \
  -F 'bg_color=ffffff' \
  -F 'format=jpg' \
  -F 'size=hd' \
  -F 'crop=true' \
  -F 'padding=40' \
  -o product-no-bg.jpg

Beispiel: quadratisches Marktplatz-Bild, Motiv zentriert mit 10% Rand

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -F 'image_file=@product.jpg' \
  -F 'crop=1:1' -F 'padding=10%' \
  -F 'width=1000' -F 'height=1000' \
  -F 'format=jpg' -F 'bg_color=white' \
  -o product-square.jpg

Beispiel: Base64 rein, Alphamaske raus

printf '{"image_file_b64":"%s","channels":"alpha"}' "$(base64 < portrait.jpg | tr -d '\n')" > request.json

curl -X POST https://removebackground.dev/v1/remove \
  -H 'x-api-key: YOUR_API_KEY' \
  -H 'Content-Type: application/json' \
  --data-binary @request.json \
  -o portrait-mask.png

200 OK

Die Bild-Bytes, mit diesen Headern:

HeaderBedeutung
X-Image-Width / X-Image-HeightGröße des Ergebnisses in Pixeln (auch als X-Width / X-Height gesendet).
X-Request-IDDeine X-Request-ID, falls du eine gesendet hast, sonst eine generierte ID. Gib sie an, wenn du den Support kontaktierst.
X-Processing-Time-MsFür die Anfrage benötigte Zeit (auch X-Processing-Ms).
X-Matte-Confidence0–1: wie eindeutig die Maske ist (Mittelwert von |2a − 1| über alle Pixel, a = Alpha). Nahe 1 ist ein sauberer Freisteller; niedrigere Werte bedeuten viele weiche oder unsichere Kanten.
X-Matte-Ambiguous-RatioAnteil der Pixel mit Alpha echt zwischen 0,1 und 0,9 (Haare, Glas, Bewegungsunschärfe). Nützlich, um Bilder zur Prüfung zu markieren.
X-Credits-RemainingDein Guthaben nach diesem Bild.
X-Removal-IdID des gespeicherten Ergebnisses.
X-Job-IdID des Jobs hinter der Anfrage (nutzbar mit /v1/jobs/:id).

202 Accepted (Fallback bei langen Warteschlangen)

Ist das Bild nicht innerhalb von etwa 55 Sekunden fertig, etwa wenn die Warteschlange ungewöhnlich voll ist, bekommst du 202 mit JSON { id, status, status_url, result_url } (plus Location und Retry-After: 2). Frage status_url ab, bis done true ist, und lade dann result_url herunter. Berechnet wird einmal, nur bei Erfolg. Sende das Bild nicht ohne Idempotency-Key erneut: Das startet einen zweiten Job. Ein vollständiges Beispiel findest du unter Antwort verarbeiten.

GET /v1/jobs/:id

Status eines Jobs, der mit /v1/remove oder /v1/batch erstellt wurde. Gleicher Schlüssel; du siehst nur deine eigenen Jobs.

FeldBedeutung
statusqueued, processing, succeeded, partial, failed oder canceled
donetrue, sobald nichts mehr zu tun ist
total, succeeded, failed, skippedAnzahl der Bilder
credits_chargedvon diesem Job verbrauchte Credits (1 pro erfolgreichem Bild)
status_url, result_urlwo du abfragst und wo du herunterlädst
items[]pro Bild: position, input, status, error { code, message } und bei Erfolg removal_id, width, height, format, result_url

GET /v1/jobs/:id/result

Die Bild-Bytes eines fertigen Jobs, mit denselben Headern wie /v1/remove. ?item=N wählt ein Bild eines Batch-Jobs (Standard: 0). Antwortet mit 409 not_ready und Retry-After: 2, solange er noch läuft, oder mit dem eigenen Fehler des Bildes, falls es fehlgeschlagen ist.

POST /v1/batch

Reiht bis zu 100 Bild-URLs als einen Job ein: JSON { "image_urls": ["https://…", …], "format": "jpg", "bg_color": "ffffff", "size": "hd", "crop": "1:1", "padding": "10%" }, mit denselben Optionen wie /v1/remove (auch channels, width, height und fit). Antwortet sofort mit 202 und { id, status, total, invalid, duplicates, status_url }. Frage den Job ab und rufe dann die result_url jedes Elements ab. 1 Credit pro erfolgreichem Bild; höchstens 3 offene Batch-Jobs pro Konto. Eine Schritt-für-Schritt-Anleitung mit Beispielantworten findest du unter Batches von A bis Z.

remove.bg-kompatibler Endpunkt

Die Self-Service-API von remove.bg endet am 1 December 2026, 09:00 CET (Ankündigung). Bestehende remove.bg-Integrationen funktionieren hier mit einer geänderten Zeile: https://api.remove.bg/v1.0/removebg → https://removebackground.dev/v1.0/removebg, mit einem removebackground.dev-Schlüssel im selben X-Api-Key-Header. Gleiche Warteschlange, gleich 1 Credit pro erfolgreichem Bild, gleiche Ausgabequalität wie /v1/remove. Migrationsanleitung.

POST /v1.0/removebg

Multipart-, urlencoded- oder JSON-Body mit den Parameternamen von remove.bg. Antwortet mit den Bild-Bytes und den Headern von remove.bg, oder mit { "data": { "result_b64", "foreground_top", "foreground_left", "foreground_width", "foreground_height" } }, wenn du Accept: application/json sendest. Fehler haben das Format von remove.bg: { "errors": [{ "title", "code", "detail" }] }. Anders als /v1/remove antwortet er nie mit 202: Er wartet bis zu 110 Sekunden und liefert dann einen 503-Timeout. Der Job läuft weiter und wird bei Erfolg berechnet – eine Wiederholung dieser Anfrage startet also einen zweiten Job.

ParameterStatusHinweise
image_file / image_file_b64 / image_urlUnterstütztMultipart-, urlencoded- oder JSON-Body. JPG, PNG oder WebP bis 25 MB.
sizeUnterstütztauto, full, 4k und 50MP liefern die Originalauflösung (bis 25 MP); preview, small und regular ≈ 0,25 MP; medium 1,5 MP; hd 4 MP. Immer 1 Credit.
formatUnterstütztauto (PNG bei Transparenz, sonst JPG), png, jpg, webp und zip (color.jpg + alpha.png).
crop / crop_marginUnterstütztpx oder % des Motivs, 1–4 Werte im CSS-Stil („10% 20%“ = vertikal, horizontal); höchstens 500px oder 50% pro Seite.
roiUnterstützt„x1 y1 x2 y2“ in px oder %: Nur das Motiv innerhalb des Bereichs bleibt erhalten.
scale / positionUnterstütztscale 10%–100% oder original; position center, original oder „x% y%“.
channelsUnterstütztrgba (Freisteller) oder alpha (Graustufenmaske).
bg_colorUnterstütztHex mit oder ohne # (81d4fa) oder ein Farbname. Bei 8-stelligem Hex bleibt die Farbe erhalten, der Alphawert entfällt.
bg_image_url / bg_image_fileUnterstütztDer Freisteller wird über dein Hintergrundbild gelegt, das per cover auf die Ausgabegröße eingepasst wird.
Accept: application/jsonUnterstütztLiefert { data: { result_b64, foreground_top, foreground_left, foreground_width, foreground_height } }.
type / type_levelAkzeptiert, ignoriertDas Motiv wird automatisch erkannt; X-Type ist immer „other“.
semitransparencyAkzeptiert, ignoriertWeiche Kanten und halbtransparente Bereiche kommen unverändert aus der Maske des Modells.
shadow_type / shadow_opacity / add_shadowAkzeptiert, ignoriertEs werden keine Schatten hinzugefügt.
Lang laufende AnfragenAbweichungWir warten bis zu 110 Sekunden; ist ein Bild bis dahin nicht fertig, bekommst du einen wiederholbaren 503 (keine Kosten, außer es wurde fertig).

Beispiel

curl -H "X-Api-Key: $REMOVEBG_API_KEY" \
  -F 'image_file=@photo.jpg' -F 'size=auto' \
  -F 'crop=true' -F 'crop_margin=10%' -F 'bg_color=ffffff' \
  -o no-bg.jpg https://removebackground.dev/v1.0/removebg

Antwort-Header

HeaderBedeutung
X-Width / X-HeightGröße des Ergebnisses in Pixeln.
X-Credits-ChargedVon diesem Bild verbrauchte Credits: immer 1 (fehlgeschlagene Bilder kosten 0).
X-TypeImmer „other“ (die Motiverkennung ist automatisch).
X-Foreground-Top / -Left / -Width / -HeightBegrenzungsrahmen des Motivs im Ergebnis, in Pixeln.
X-Request-IDGibt deine X-Request-ID zurück oder eine generierte ID. Zusätzlich.
X-Matte-Confidence / X-Matte-Ambiguous-RatioWie sauber die Maske ist (0–1) und der Anteil weicher Pixel. Zusätzlich: nützlich, um Bilder zur Prüfung zu markieren.

Fehler

StatusBedeutung
400Ungültiger Parameter oder ungültiges Bild (Codes wie invalid_size, invalid_crop_margin, missing_source, file_too_large, unknown_foreground).
402insufficient_credits: Lade auf der Preisseite auf.
403auth_failed: X-Api-Key fehlt oder ist ungültig.
429rate_limit_exceeded.
500 / 503Verarbeitung fehlgeschlagen, Zeitüberschreitung oder der Dienst ist kurz nicht verfügbar. Erneut versuchen; fehlgeschlagene Bilder sind kostenlos.

GET /v1.0/account

Dein Guthaben im Kontoformat von remove.bg: { "data": { "attributes": { "credits": { "total", "subscription": 0, "payg", "enterprise": 0 }, "api": { "free_calls": 0, "sizes": "all" } } } }. Alle Credits werden nach Bedarf gekauft und verfallen nie, daher ist total gleich payg. GET https://removebackground.dev/v1.0/account mit deinem X-Api-Key.

Fehler (/v1-Endpunkte)

Fehlgeschlagene Bilder werden nie berechnet.

StatusCodesBedeutung
400missing_image, invalid_url, invalid_body, invalid_json, invalid_image_b64, invalid_format, invalid_bg_color, invalid_size, invalid_crop, invalid_padding, invalid_type, invalid_channels, invalid_width, invalid_height, invalid_fit, invalid_roi, fetch_failed, fetch_timeout, rejected, too_many_images, invalid_imagesDie Anfrage oder die Bild-URL ist nicht verwendbar.
401unauthorizedx-api-key fehlt, ist falsch oder widerrufen.
402insufficient_credits, out_of_creditsDein Guthaben ist leer. Lade auf der Preisseite auf.
404not_foundDiesen Job gibt es nicht (oder er gehört nicht dir).
409not_ready, canceled, idempotency_key_reusedGET …/result, während der Job noch läuft (nach 2 s erneut versuchen), der Job wurde abgebrochen, oder ein Idempotency-Key wurde für eine andere Anfrage wiederverwendet.
410result_unavailableDas Ergebnis wurde gelöscht oder ist abgelaufen.
413too_largeDas Bild ist größer als 25 MB.
422processing_failed, invalid_image, missing_uploadDie Datei ist kein lesbares Bild. Nicht berechnet.
429rate_limited, too_many_batchesÜber dem Anfragelimit pro Konto (Retry-After abwarten), oder du hast bereits 3 laufende Batch-Jobs.
502model_unavailable, upstream_error, …Wir konnten das Bild auch nach Wiederholungen nicht verarbeiten. Nicht berechnet.
503server_paused, unavailableDie API ist pausiert (vor dem Start) oder kurz nicht verfügbar. Später erneut versuchen.

Batches von A bis Z

1. Absenden

curl -X POST https://removebackground.dev/v1/batch \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{ "image_urls": ["https://example.com/front.jpg", "https://example.com/back.jpg"], "format": "png", "size": "hd" }'

Bis zu 100 öffentliche Bild-URLs plus beliebige Optionen von /v1/remove. Die beiden Platzhalter-URLs oben würden bis zu 2 Credits kosten, wenn es echte Bilder wären. Die Antwort kommt sofort:

202 Accepted
{
  "id": "3f6c2a9e-8d1b-4c7a-9e2f-5b8d0a1c4e77",
  "status": "queued",
  "total": 2,
  "invalid": 0,
  "duplicates": 0,
  "status_url": "https://removebackground.dev/v1/jobs/3f6c2a9e-8d1b-4c7a-9e2f-5b8d0a1c4e77"
}

invalid zählt Einträge, die keine http(s)-URLs sind, und duplicates zählt Wiederholungen; beide werden verworfen und nie berechnet. Speichere die id: Damit nimmst du den Job nach einem Neustart wieder auf.

2. Job abfragen

GET /v1/jobs/:id alle paar Sekunden, bis done den Wert true hat. status wechselt von queued zu processing und endet als succeeded, partial (einige Bilder fehlgeschlagen) oder failed. Ein Element, das erneut versucht wird, zeigt retrying.

{
  "id": "3f6c2a9e-…",
  "status": "partial",
  "done": true,
  "total": 2, "succeeded": 1, "failed": 1, "skipped": 0,
  "credits_charged": 1,
  "items": [
    { "position": 0, "input": "https://example.com/front.jpg", "status": "succeeded",
      "removal_id": "…", "width": 1600, "height": 1200, "format": "png",
      "result_url": "https://removebackground.dev/v1/jobs/3f6c2a9e-…/result?item=0" },
    { "position": 1, "input": "https://example.com/back.jpg", "status": "failed",
      "error": { "code": "fetch_failed", "message": "…" } }
  ]
}

3. Jedes Ergebnis herunterladen

GET /v1/jobs/:id/result?item=N für jedes erfolgreiche Element (oder nutze dessen result_url). item ist die nullbasierte position. Die Positionen folgen deiner Liste, nachdem ungültige und doppelte URLs entfernt wurden. Ist einer der beiden Zähler größer als 0, ordne die Ergebnisse daher über input statt über den Index zu.

  • Ein Batch zählt nicht mehr zum Limit von 3 offenen Batches, sobald done true ist.
  • Die API hat keinen Abbruch-Endpunkt, keine Webhooks und keinen ZIP-Download. Batches, die auf der Bulk-Seite gestartet wurden, kannst du dort abbrechen oder als ZIP herunterladen.

Wiederholungen, Duplikate und Abrechnung

Sende einen Idempotency-Key, dann kosten Wiederholungen nie doppelt. Füge POST /v1/remove oder POST /v1/batch einen Idempotency-Key-Header hinzu (eine beliebige eindeutige Zeichenkette mit bis zu 255 Zeichen, z. B. eine UUID), ein Schlüssel pro Bild oder Batch. Sendest du dieselbe Anfrage mit demselben Schlüssel erneut, bekommst du den Job der ersten Anfrage mit Idempotent-Replayed: true: kein neuer Job und keine neue Abrechnung, selbst wenn die erste Anfrage noch läuft. Derselbe Schlüssel mit einem anderen Bild oder anderen Optionen ergibt 409 idempotency_key_reused. Die Schlüssel gehören zu deinem Konto und verfallen nicht.

Ohne Schlüssel erzeugt jeder POST einen neuen Job, und jeder erfolgreiche Job kostet 1 Credit (der remove.bg-kompatible POST /v1.0/removebg hat keine Schlüssel). Das Lesen eines Jobs (GET /v1/jobs/…) ist immer kostenlos und kann beliebig wiederholt werden.

IDEMPOTENCY_KEY=$(uuidgen)   # one per image; send the same one on every retry

curl -X POST https://removebackground.dev/v1/remove \
  -H "x-api-key: $REMOVEBG_API_KEY" \
  -H "Idempotency-Key: $IDEMPOTENCY_KEY" \
  -F 'image_file=@photo.jpg' \
  -o photo-no-bg.png

Was einen Credit kostet

SituationKosten
Anfrage vor der Verarbeitung abgelehnt (falscher Schlüssel, falsche Option, zu groß, keine Credits mehr)Kostenlos.
Das Bild kann nicht verarbeitet werden (422 ungültiges Bild, 502 nach unseren Wiederholungen)Kostenlos.
Das Bild ist erfolgreich1 Credit, einmal berechnet, bei Erfolg. Unsere eigenen internen Wiederholungen kosten nichts extra.
Du bekommst einen 202Noch nichts. Der Job läuft weiter und kostet nur bei Erfolg 1 Credit.
Dein Client hat beim Warten ein Timeout oder trennt die VerbindungDer Job läuft weiter und wird bei Erfolg berechnet. Das Ergebnis erscheint in deinem Studio.
Du sendest dieselbe Anfrage zweimal mit demselben Idempotency-KeyEin Job, höchstens 1 Credit. Die Wiederholung bekommt denselben Job (Header Idempotent-Replayed: true).
Du sendest dasselbe Bild zweimal ohne SchlüsselZwei separate Jobs; jeder erfolgreiche kostet 1 Credit.
Du lädst ein fertiges Ergebnis erneut herunterKostenlos, so oft du willst, solange es gespeichert ist.
Ein Batch ist teilweise erfolgreich1 Credit pro erfolgreichem Bild; credits_charged am Job zeigt die Summe.
Ein Batch enthält dieselbe URL zweimalWiederholungen innerhalb eines Batches werden vor dem Einreihen verworfen und nie berechnet. Identische URLs in verschiedenen Batches sind separate Jobs.
Die Credits gehen während eines Batches ausBereits fertige Bilder bleiben bezahlt; der Rest wird als skipped (out_of_credits) markiert und ist kostenlos. Kauf Credits und sende die übrigen URLs als neuen Batch.

Wann wiederholen

Was passiert istWas tun
GET /v1/jobs/:id oder …/result schlägt fehl (Netzwerkfehler, 5xx)Unbedenklich zu wiederholen: Das Lesen eines Jobs erzeugt nie Arbeit oder Kosten. Warte zwischen den Versuchen etwas länger.
GET …/result antwortet 409 not_readyWarte die Retry-After-Zeit ab (2 s) und frag erneut. Sende das Bild nicht noch einmal.
GET …/result antwortet 410 result_unavailableDas gespeicherte Ergebnis wurde gelöscht. Das Bild erneut zu verarbeiten ist ein neuer Job und kostet 1 Credit.
POST antwortet 400, 413 oder 422Korrigiere zuerst die Anfrage oder das Bild; unverändert gesendet bekommst du dieselbe Antwort.
POST antwortet 401 oder 402Korrigiere den Schlüssel oder lade auf. Keine Schleife.
POST antwortet 429 rate_limitedWarte die Sekunden aus Retry-After ab und sende dann erneut (mit demselben Idempotency-Key). Mehr als 60 Bilder pro Minute? Nutze POST /v1/batch: eine Anfrage für bis zu 100.
POST /v1/batch antwortet 429 too_many_batchesWarte, bis einer deiner 3 offenen Batches fertig ist (frag ihn ab), und sende dann.
POST /v1/… antwortet 503 (unavailable, server_paused)Es wurde kein Job erstellt. Versuch es nach kurzer Wartezeit erneut. (Beim remove.bg-kompatiblen Endpunkt ist es anders: Dort bedeutet ein 503-Timeout, dass der Job noch läuft.)
POST /v1/remove antwortet 502Dieser Job ist fehlgeschlagen und wurde nicht berechnet. Eine Wiederholung ist ein neuer Job.
POST hat ein Timeout, die Verbindung bricht ab oder du bekommst 500Mit Idempotency-Key: Sende dieselbe Anfrage mit demselben Schlüssel erneut; du bekommst den ursprünglichen Job. Ohne Schlüssel existiert der Job vielleicht schon und wird eventuell berechnet: Prüfe zuerst dein Studio.
POST antwortet 409 idempotency_key_reusedDieser Schlüssel wurde bereits für ein anderes Bild oder andere Optionen verwendet. Erzeuge für jedes neue Bild einen neuen Schlüssel.

Limits und Speicherung

LimitWertFehler bei Überschreitung
Bilddatei25 MB (25 × 1024 × 1024 Bytes); JPG, PNG oder WebP, anhand der Datei-Bytes erkannt413 too_large · 422 processing_failed
Base64- / JSON-Body25 MB nach dem Dekodieren (der Request-Body darf etwa ein Drittel größer sein)413 too_large
EingabeauflösungBilder über 25 MP werden vor der Verarbeitung auf 25 MP verkleinert—
AusgabegrößeBreite und Höhe jeweils 1–6000 px400 invalid_width / invalid_height
Download per image_urlnur http(s), 15 s Timeout, bis zu 3 Weiterleitungen; private, Loopback- und Link-Local-Adressen werden bei jeder Weiterleitung abgelehnt400 invalid_url · fetch_failed · fetch_timeout
Wartezeit in POST /v1/removeEtwa 55 s, dann 202 mit der Job-ID202
Batch-Größe100 Bild-URLs pro POST /v1/batch400 too_many_images
Offene Batches3 unfertige Jobs mit mehreren Bildern pro Konto (Einzelbilder zählen nicht)429 too_many_batches
Anfragerate60 Anfragen pro Minute und Konto, über POST /v1/remove, /v1/batch und /v1.0/removebg hinweg. Ein Batch zählt einmal, egal wie groß. Das Lesen von Jobs ist nicht begrenzt429 rate_limited (mit Retry-After)

Wie lange Ergebnisse gespeichert werden

Jedes Ergebnis wird nach der Erstellung 48 Stunden lang privat in deinem Konto gespeichert und danach gelöscht. Bis dahin kannst du es kostenlos erneut herunterladen, mit GET /v1/jobs/:id/result oder in deinem Studio. Danach antworten Ergebnis-Links mit 410 result_unavailable; das Bild erneut zu verarbeiten ist ein neuer Job. Job-Statusdaten bleiben lesbar, auch wenn das Bild weg ist. Wie Uploads behandelt werden, steht in der Datenschutzerklärung; wir verwenden deine Bilder nicht zum Trainieren von Modellen.

Sicherheit

Bewahre deinen API-Schlüssel auf einem Server auf, den du kontrollierst. Pack ihn nicht in Browser-Code, mobile Apps, öffentliche Repositorys oder URLs. Wenn deine eigenen Nutzer Hintergründe entfernen sollen, leite ihre Bilder über dein Backend und ergänze dort eine eigene Anmeldung und Ausgabelimits.

  • Die API erlaubt CORS, damit sie aus Tools und serverseitigem Code funktioniert. Das macht es aber nicht sicher, einen Schlüssel in eine Webseite einzubauen: Dort kann ihn jeder lesen.
  • Alle Schlüssel eines Kontos nutzen dasselbe Credit-Guthaben. Erstelle auf deiner Kontoseite einen eigenen Schlüssel pro App oder Umgebung, damit du einen widerrufen kannst, ohne die anderen zu beeinträchtigen.
  • Wenn ein Schlüssel öffentlich wird, widerrufe ihn sofort auf der Kontoseite (er funktioniert dann sofort nicht mehr) und erstelle einen neuen. Wir speichern nur einen Hash jedes Schlüssels und können ihn dir daher nicht noch einmal anzeigen.

Fehlerbehebung

SymptomWas dahintersteckt
Mein PNG lässt sich nicht öffnenDer Body war JSON (ein 202-Job oder ein Fehler), kein Bild. Prüfe HTTP-Status und Content-Type, bevor du speicherst.
Mein Skript hatte ein Timeout, aber das Bild erscheint im StudioDer Job lief weiter, nachdem du aufgehört hast zu warten. Ruf ihn mit seiner Job-ID ab, statt erneut zu senden.
Mir wurde ein Bild doppelt berechnetEs wurde zweimal ohne Idempotency-Key gesendet (oft eine automatische Wiederholung nach einem Timeout). Sende einen Schlüssel pro Bild und verwende ihn bei Wiederholungen erneut.
Die URL öffnet sich im Browser, aber die API kann sie nicht abrufenDer Host verlangt vielleicht Cookies oder einen Login, blockiert Server, leitet mehr als 3-mal weiter, braucht über 15 s, oder die signierte URL ist abgelaufen. Lade die Datei stattdessen hoch.
Mein Batch ist auf halbem Weg stehen gebliebenSieh dir items[] im Job an: Fehlgeschlagene Elemente haben einen Fehlercode; übersprungene Elemente mit out_of_credits bedeuten, dass das Guthaben aufgebraucht war.
Eine Option scheint nichts zu bewirkenUnbekannte Parameternamen werden stillschweigend ignoriert. Prüfe die Schreibweise anhand der Parametertabelle. Bei /v1.0/removebg werden einige remove.bg-Optionen akzeptiert, aber ignoriert (siehe die dortige Tabelle).
Der Hintergrund ist nicht transparentJPG kann nicht transparent sein. Nutze format=png oder webp und lass bg_color weg.
Der Ergebnis-Link liefert 410Das gespeicherte Ergebnis wurde gelöscht. Eine erneute Verarbeitung kostet 1 Credit.