Background removal of many images
const url = 'https://api.stack.foldbun.com/v1/batch/remove-background';const options = { method: 'POST', headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'}, body: '{"model":"birefnet","items":[{"image":{"id":"img_3b1f0c5e9a7d42c8b6e1f0a9d8c7b6a5f4e3d2c1b0a998877665544332211000"},"options":{"output":"cutout"}}]}'};
try { const response = await fetch(url, options); const data = await response.json(); console.log(data);} catch (error) { console.error(error);}curl --request POST \ --url https://api.stack.foldbun.com/v1/batch/remove-background \ --header 'Authorization: Bearer <token>' \ --header 'Content-Type: application/json' \ --data '{ "model": "birefnet", "items": [ { "image": { "id": "img_3b1f0c5e9a7d42c8b6e1f0a9d8c7b6a5f4e3d2c1b0a998877665544332211000" }, "options": { "output": "cutout" } } ] }'Model birefnet (default). Items are POST /v1/remove-background bodies without model. Semantics, modes, limits and the event format are described on the BatchRequest, BatchItem
and BatchSummary schemas and in the Overview. Server-Sent Events are recommended; JSON mode is not.
Authorizations
Section titled “Authorizations”Parameters
Section titled “Parameters”Header Parameters
Section titled “Header Parameters”1 to 128 printable ASCII characters. Within an account, a key is remembered for 24 hours: repeating the request
with the same body returns the original response (header Idempotent-Replayed: true) without charging or
running the call again. The same key with a different body is 409 idempotency_conflict. See the Overview.
Request Bodyrequired
Section titled “Request Bodyrequired”The model, the items and an optional time limit.
A batch of single calls to one endpoint. model is set once (omit it where the endpoint has a default
model); an item must not contain model. Every item is validated before anything runs: a structural error
is 400 invalid_request whose message names items[i], and nothing is billed. Images in items can only be
{"id": "img_..."} handles. Items run strictly one after another, so the order of the array is the order of
execution. At most 1,000 items and 4 MiB per request. Idempotency-Key makes item i use the derived key
"b <key> <i>": repeating the same batch replays finished items (replayed: true, no charge), runs the others,
and an item whose content changed fails with idempotency_conflict.
Limits: event-stream mode runs for at most 600 s, JSON mode for at most 90 s (JSON mode is not
recommended beyond a few items). timeoutSec can only shorten them; a larger value is clamped without an
error. When the limit passes, no new item starts, the running item is cancelled (not billed) and every item
not finished is expired; the results of finished items are kept. A client disconnect stops the batch the same
way. At most 1 to 4 batch requests can be open per account at once, depending on the tier (429 too_many_batches).
object
Model id for all items. Optional where the endpoint has a default model.
Single-call request bodies of the endpoint, without model, in execution order.
The request body of the single-call endpoint without model; images only as {"id": "img_..."}.
object
Time limit for the whole batch in seconds, counted from the arrival of the request. Can only shorten the mode limit (600 s event stream, 90 s JSON).
Example
{ "model": "birefnet", "items": [ { "image": { "id": "img_3b1f0c5e9a7d42c8b6e1f0a9d8c7b6a5f4e3d2c1b0a998877665544332211000" }, "options": { "output": "cutout" } } ]}Responses
Section titled “Responses”The batch ran (items may still have failed individually: the request itself only fails before execution,
with the normal error envelope). With Accept: text/event-stream the body is a stream of events, flushed
one by one: progress first, then item per finished item, summary last. Otherwise it is one JSON
document, or one CBOR document with Accept: application/cbor.
Events in the form event: <name> / data: <one-line JSON>, separated by a blank line. Names: progress (BatchProgress), item (BatchItem), summary (BatchSummary, last).
Example
event: progressdata: {"done":0,"remaining":2}
event: itemdata: {"index":0,"status":"ok","result":{"id":"call_0193...","model":"dinov3","cost":0.05,"balance":9.95}}
event: progressdata: {"done":1,"remaining":1,"etaWaitMs":850}
event: itemdata: {"index":1,"status":"error","error":{"code":"insufficient_balance","message":"insufficient balance: this call can cost up to 0.05 credits"}}
event: summarydata: {"counts":{"ok":1,"error":1,"expired":0},"cost":0.05,"balance":0.01,"elapsedMs":2310}The JSON-mode response (not recommended; see BatchRequest).
object
One entry per item, sorted by index.
The outcome of one item; the data of an item event and an element of BatchResponse.items.
object
Position of the item in the request.
ok: the call succeeded and was billed. error: it failed and was not billed. expired: the batch time limit passed before the item finished; not billed.
On ok: exactly the success response of the single call, including id, cost, balance, billing and timing.
object
On error: the error of the single call (an insufficient balance fails only this item; the next items are still tried).
object
Stable error code
Human-readable explanation.
True when the item was answered from an earlier batch under the same Idempotency-Key; nothing ran or was charged.
The final summary event, and summary of the JSON response.
object
Number of items per status.
object
Items with status ok.
Items with status error.
Items with status expired.
Credits charged by this request (replayed items are not charged again).
Account balance when the batch ended.
Time from the arrival of the request to the end of the batch in milliseconds.
Example
{ "items": [ { "status": "ok" } ]}The JSON-mode response (not recommended; see BatchRequest).
object
One entry per item, sorted by index.
The outcome of one item; the data of an item event and an element of BatchResponse.items.
object
Position of the item in the request.
ok: the call succeeded and was billed. error: it failed and was not billed. expired: the batch time limit passed before the item finished; not billed.
On ok: exactly the success response of the single call, including id, cost, balance, billing and timing.
object
On error: the error of the single call (an insufficient balance fails only this item; the next items are still tried).
object
Stable error code
Human-readable explanation.
True when the item was answered from an earlier batch under the same Idempotency-Key; nothing ran or was charged.
The final summary event, and summary of the JSON response.
object
Number of items per status.
object
Items with status ok.
Items with status error.
Items with status expired.
Credits charged by this request (replayed items are not charged again).
Account balance when the batch ended.
Time from the arrival of the request to the end of the batch in milliseconds.
Headers
Section titled “Headers”Server-generated request id (16 hexadecimal characters); present on every response. Quote it when contacting support.
default
Section titled “default”The error envelope. The HTTP status follows the code; only retryable: true errors are worth repeating
unchanged. A failed call costs 0.
| Status | Codes |
|---|---|
| 400 | invalid_request, invalid_image (the image passed the upload checks but could not be decoded), unsupported |
| 401 | unauthorized |
| 402 | insufficient_balance |
| 403 | model_locked |
| 404 | not_found, image_not_found |
| 409 | idempotency_conflict, request_in_progress |
| 413 | payload_too_large |
| 429 | rate_limited, daily_limit_reached, too_many_batches (all with Retry-After) |
| 500 | internal_error |
| 502 | upstream_error, bad_model_output |
| 503 | model_unavailable, model_busy, unavailable (all with Retry-After) |
| 504 | upstream_timeout |
model_unavailable also covers a short loss of contact with the only GPU worker serving the model: for about a
minute after the loss, interactive calls answer it at once with a short Retry-After (5 s), while sync and
batch calls stay queued until their own deadline instead of failing.
Meaning and retry guidance for each code: Errors.
Body of every error response.
object
The error.
object
Stable machine-readable error code. Branch on this, not on message. Listed with the HTTP statuses under Responses.
Human-readable explanation. The wording can change.
True when repeating the same request unchanged can succeed.
Suggested wait before a retry in milliseconds; 0 when there is no hint.
Example
{ "error": { "code": "model_busy", "message": "model sam3 is busy; retry shortly", "retryable": true, "retryAfterMs": 5000 }}Headers
Section titled “Headers”Whole seconds to wait before retrying; present on 429 and 503.
Server-generated request id (16 hexadecimal characters); present on every response. Quote it when contacting support.