Production results and integration reference for AI-powered image processing workflows.
You'll need a Runflow account, an API key, and enough credit to run a batch. About two minutes end to end.
Sign up at app.runflow.io and confirm your email.
Go to Settings → API Keys and create one. Copy it immediately — the full secret is only shown at creation. Keys start with rf_live_.
Add credits in your account billing settings. Batches are admission-gated — if the projected cost exceeds your balance, the request is rejected with 402 INSUFFICIENT_CREDITS and nothing is created or charged.
curl -X POST https://api.runflow.io/v1/models/runflow/dyver-removal/batches \
-H "Authorization: Bearer $RUNFLOW_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": [
{
"image_url": "https://cdn.example.com/shirt.jpg",
"config": {
"elements": ["model_removal", "tag_removal", "product_isolation", "background_removal"]
}
}
]
}'
You'll get back a batch ID. Poll GET /v1/batches/{id}, or set a callback_url to receive results via webhook. The API tab has the full contract.
Process images one at a time, or batch up to 100 per request. Each item runs independently — partial success is first-class, and you only pay for items that succeed. Results come back via webhook or polling.
runflow/dyver-removalA 4-in-1 pipeline. Pick any combination of operations per item — they always run in the fixed order below, skipping any you didn't ask for. The response returns every stage as a separate image (the intermediates) plus a final composite. Match result_* in the URL to pick out the final; intermediates are named after their stage (e.g. bg_remover_00001_.webp).
model_removal
tag_removal
product_isolation
background_removal
{
"image_url": "https://cdn.example.com/shirt.jpg",
"config": {
"elements": ["tag_removal", "background_removal"],
"aspect_ratio": "1:1",
"product_isolation_prompt": "the white sneaker"
},
"client_ref": "sku-123"
}
elements is required — one or more of the operations above. aspect_ratio and product_isolation_prompt are optional. client_ref is your own label; we echo it back verbatim so you can match items to your records.
For one-off runs, skip the batch wrapper and hit the singleton endpoint. Same per-item body, wrapped in input.
POST https://api.runflow.io/v1/models/runflow/dyver-removal/runs
Authorization: Bearer {api_key}
Content-Type: application/json
{
"input": {
"image_url": "https://cdn.example.com/shirt.jpg",
"config": { "elements": ["tag_removal", "background_removal"] }
},
"callback_url": "https://you.example/webhooks/runflow",
"metadata": { "sku": "123" }
}
Poll GET /v1/runs/{run_id} or wait for the callback. Per-run callbacks fire once at terminal state with event run.completed, run.failed, or run.cancelled:
{
"event": "run.completed",
"run_id": "01984c44-...",
"status": "succeeded",
"output": {
"image_urls": [
"https://.../tag_remover_00001_.webp",
"https://.../bg_remover_00001_.webp",
"https://.../result_00001_.webp"
]
},
"duration_ms": 18420,
"created_at": "2026-04-16T10:00:00Z",
"completed_at": "2026-04-16T10:00:18Z",
"metadata": { "sku": "123" }
}
If the run fails or is cancelled, output is null and status is failed or cancelled. Webhook signing and retry behavior are the same as batches (see below).
POST https://api.runflow.io/v1/models/runflow/dyver-removal/batches
Authorization: Bearer {api_key}
Content-Type: application/json
{
"input": [
{
"image_url": "https://cdn.example.com/a.jpg",
"config": { "elements": ["tag_removal", "background_removal"] },
"client_ref": "sku-123"
},
{
"image_url": "https://cdn.example.com/b.jpg",
"config": { "elements": ["model_removal"] }
}
],
"callback_url": "https://you.example/webhooks/runflow",
"metadata": { "campaign": "spring-drop" }
}
{
"id": "01984c44-...",
"status_code": "queued",
"items_total": 2,
"items_succeeded": 0,
"items_failed": 0,
"items": [
{ "id": "01984c45-...", "sequence_index": 0, "client_ref": "sku-123", "run_id": "01984c46-...", "status_code": "queued" },
{ "id": "01984c47-...", "sequence_index": 1, "client_ref": null, "run_id": "01984c48-...", "status_code": "queued" }
],
"output": null,
"created_at": "2026-04-16T10:00:00Z"
}
Every item comes back with four correlation handles — id, sequence_index, client_ref, and run_id. Use whichever fits your system.
GET /v1/batches/{batch_id} — done when items_succeeded + items_failed + items_cancelled == items_total.
Set callback_url on create. We POST one signed webhook at terminal state — batch.succeeded, batch.partial_succeeded, batch.failed, or batch.cancelled.
At terminal, batch.output lists every item in order, each with its original input plus either an output or an error. No cross-referencing needed.
{
"status_code": "partial_succeeded",
"items_succeeded": 1,
"items_failed": 1,
"cost": "0.410000",
"output": {
"items": [
{
"sequence_index": 0,
"status_code": "succeeded",
"client_ref": "sku-123",
"input": { "image_url": "...", "config": { "elements": ["tag_removal", "background_removal"] } },
"output": { "image_urls": [
"https://.../tag_remover_00001_.webp",
"https://.../bg_remover_00001_.webp",
"https://.../result_00001_.webp"
] }
},
{
"sequence_index": 1,
"status_code": "failed",
"input": { "image_url": "...", "config": { "elements": ["model_removal"] } },
"error": { "kind": "upstream_failed", "message": "..." }
}
],
"succeeded": 1,
"failed": 1,
"total": 2
}
}
Create an org-scoped secret once. The raw secret is returned at creation time only — store it safely.
POST /v1/callback-secrets
{ "label": "webhook-prod" }
→ { "id": "...", "secret": "rf_whsec_...", "label": "webhook-prod" }
Every delivery then carries three headers:
Runflow-Signature: v1=9f3a1e...
Runflow-Timestamp: 1745234442
Runflow-Request-Id: 01984d10-7c2b-7f3e-8b4d-1a2b3c4d5e6f-1
Verify by computing HMAC-SHA256(secret, timestamp + "." + raw_body) and comparing against the v1= value. Reject timestamps more than five minutes off. Retries reuse the delivery ID — dedupe by stripping the trailing -{attempt_number} from Runflow-Request-Id.
{
"code": "VALIDATION_ERROR",
"message": "Request validation failed",
"errors": [
{ "loc": ["body", "input", 0, "image_url"], "msg": "field required", "type": "missing" }
]
}
Watch for 401 UNAUTHORIZED (bad key), 402 INSUFFICIENT_CREDITS (admission-gated, nothing is created or charged), 404 NOT_FOUND, 422 VALIDATION_ERROR (per-field detail in errors[]), and 429 RATE_LIMITED (respect Retry-After).
Limits: up to 100 items per batch · client_ref ≤ 255 chars · metadata ≤ 16 KB · callback_url must be HTTPS.
Need higher batch sizes? The 100-item cap is the current default — reach out to your Runflow contact and we'll raise it for your org.