Unmerge API: split images into layers from code
Send an image, get back named transparent PNG layers with their positions. Base URL https://unmerge.app/api/v1. Every request needs Authorization: Bearer um_YOUR_KEY.
Get a key
Sign in, confirm your email address, and create a key on Account › API keys. The key is shown once. Keep it out of shared code; anyone with it can spend the credits on your account. Revoke it there if it leaks.
Credits and limits
- Same credits as the website: 1 credit per layer returned, at most 17 layers per image. You need at least 5 credits to start a split.
- Images: PNG, JPG or WebP, up to 10 MB and 4 megapixels. Send a file, a public https URL, or base64.
- Optional prompt: what to separate, in plain words, up to 500 characters.
- A split runs in the background. Poll the project until its status is no longer processing.
- Layer download URLs work for one hour. Get the project again for fresh ones.
- Projects made with the API belong to your account and are kept until you delete them in My projects or delete the account, like projects made on the website.
- Each key allows 120 requests a minute. Keys are shown once; you can have 5 active keys.
POST /layers
Upload an image and start a split. Send multipart with a file field (and optional prompt), or JSON with image_url or image_base64. Returns 202 with the project. Add an Idempotency-Key header to retry safely: the same key returns the same project. 402 means fewer than 5 credits.
curl https://unmerge.app/api/v1/layers \
-H "Authorization: Bearer $UNMERGE_API_KEY" \
-H "Idempotency-Key: poster-001" \
-F file=@poster.png \
-F prompt="the title, the person and the background"Response:
{
"id": "Xq3v9TbM2kLp0aZr",
"status": "processing",
"credits": { "reserved": 17, "charged": null, "owed": null },
"layers": null,
"workspace_url": "https://unmerge.app/workspace/Xq3v9TbM2kLp0aZr"
}GET /layers/{id}
The project. status is uploaded, processing, ready, needs_credits, failed or expired. When ready, each layer has a name, its bounds on the canvas [x1, y1, x2, y2] (null for a full background), z_index and a PNG url valid for one hour.
curl https://unmerge.app/api/v1/layers/Xq3v9TbM2kLp0aZr \
-H "Authorization: Bearer $UNMERGE_API_KEY"Response:
{
"id": "Xq3v9TbM2kLp0aZr",
"status": "ready",
"credits": { "reserved": 17, "charged": 6, "owed": null },
"layer_count": 6,
"canvas": { "width": 1024, "height": 1024 },
"layers": [
{
"index": 0,
"name": "Background",
"z_index": 0,
"bounds": null,
"url": "https://…/layer-00.png?X-Amz-Signature=…"
}
],
"urls_expire_at": "2026-10-24T13:00:00.000Z"
}POST /layers/{id}/unlock
For needs_credits: the model returned more layers than the credits held. Pays credits.owed from the balance and makes the files available. Charges once.
curl -X POST https://unmerge.app/api/v1/layers/Xq3v9TbM2kLp0aZr/unlock \
-H "Authorization: Bearer $UNMERGE_API_KEY"Response:
{ "id": "Xq3v9TbM2kLp0aZr", "status": "ready", … }GET /credits
Credits available on the account.
curl https://unmerge.app/api/v1/credits \
-H "Authorization: Bearer $UNMERGE_API_KEY"Response:
{ "credits": 86 }JSON instead of a file
curl https://unmerge.app/api/v1/layers \
-H "Authorization: Bearer $UNMERGE_API_KEY" \
-H "Content-Type: application/json" \
-d '{"image_url": "https://example.com/poster.png", "prompt": "the person and the background"}'Use image_base64 instead of image_url when the image has no public address.
Errors
Errors are JSON: { "error": "code", "message": "…" }.
| Status | error | Meaning |
|---|---|---|
| 401 | unauthorized | Missing, wrong or revoked key. |
| 402 | insufficient_credits | Fewer than 5 credits, or not enough to unlock. |
| 400 | invalid_request, invalid_prompt | The body or prompt is not what the endpoint expects. |
| 400 | image_fetch_failed | image_url could not be downloaded over https within 10 seconds. |
| 413, 415 | too_large, too_many_pixels, unsupported_type | The image is over 10 MB and 4 megapixels, or not PNG, JPG or WebP. |
| 404 | not_found | No project with this id on this account. |
| 429 | rate_limited, too_many_uploads | Over 120 requests a minute for this key, or too many uploads this week. |
| 503 | not_open | The API is switched off for now. |