DEVELOPERS

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": "…" }.

StatuserrorMeaning
401unauthorizedMissing, wrong or revoked key.
402insufficient_creditsFewer than 5 credits, or not enough to unlock.
400invalid_request, invalid_promptThe body or prompt is not what the endpoint expects.
400image_fetch_failedimage_url could not be downloaded over https within 10 seconds.
413, 415too_large, too_many_pixels, unsupported_typeThe image is over 10 MB and 4 megapixels, or not PNG, JPG or WebP.
404not_foundNo project with this id on this account.
429rate_limited, too_many_uploadsOver 120 requests a minute for this key, or too many uploads this week.
503not_openThe API is switched off for now.

Using Claude Code, Cursor or Codex? Connect over MCP