Skip to content

Developers

HTTP API

Same specialised text-erase model as All text and Select in the editor. Authenticate with an API key from Account → Developer. Calls run on prepaid API credits (ladder below) or on the monthly credits from a plan on Pricing.

Base URL

https://api.erasetext.com/v1

Every path below is relative to this base. HTTPS only. OpenAPI: /openapi.json.

Authentication

X-Api-Key: et_…

Creating your first key grants a one-time 50 API credit trial — 50 calls, no card. After that a key spends your prepaid API credits first, then any monthly plan credits.

MCP

Agents can call the same erase path over MCP. The server is Streamable HTTP at https://api.erasetext.com/mcp. Send the same X-Api-Key (or Authorization: Bearer et_…). erase_text spends 1 credit on success; get_account, handshake and tool listing are free. Failures are not charged.

{
  "mcpServers": {
    "erasetext": {
      "url": "https://api.erasetext.com/mcp",
      "headers": { "X-Api-Key": "et_…" }
    }
  }
}

Cursor, Claude Desktop, and other clients that speak remote MCP with headers work today. Hosted OAuth connectors are not shipped — use an API key. Manifest: /.well-known/mcp.json.

What a call costs

Every successful /erase spends 1 credit — one flat price, whatever the image size or output format. Failures are not charged, and neither is GET /account.

POST /erase

Multipart or JSON. Returns image bytes by default.

  • image_file or image_url — required
  • mask_file / mask_url — optional; omit for all-text detect
  • format=webp|png|jpg — default webp
  • resolution — short-edge target for the model, clamped to 2561024, default 512
  • paste_back — default true; keeps original pixels outside the erased area
  • return_boxes=1 — OCR quads in X-Ocr-Boxes. Only applies when you send no mask, since that is when detection runs
  • response=json — return JSON with base64 instead of raw bytes

Mask polarity: white (any channel value above 127) marks what to erase, black keeps. Send it at the same aspect ratio as the image. Omit the mask and detection builds one for every piece of text it finds.

curl -X POST \
  -H "X-Api-Key: et_…" \
  -F "[email protected]" \
  "https://api.erasetext.com/v1/erase" \
  -o out.webp

The JSON body takes the same flags but different image fields — image_url or image_file_b64 (and mask_url / mask_file_b64):

curl -X POST \
  -H "X-Api-Key: et_…" \
  -H "Content-Type: application/json" \
  -d '{"image_url":"https://…/photo.jpg","response":"json"}' \
  "https://api.erasetext.com/v1/erase"

Response

Raw image bytes with the matching Content-Type, plus these headers:

  • X-Credits-Charged — always 1 on success
  • X-Credits-Remaining — API plus web balance after the call
  • X-RateLimit-Limit, X-RateLimit-Remaining, X-RateLimit-Reset (unix seconds)
  • X-Ocr-Boxes — JSON quads, only with return_boxes=1

With response=json the body carries the same information instead:

{
  "image_base64": "…",
  "content_type": "image/webp",
  "credits_charged": 1,
  "credits_remaining": 199,
  "ocr_boxes": null
}

GET /account

curl -H "X-Api-Key: et_…" \
  "https://api.erasetext.com/v1/account"

Returns the API and web balances, your plan, and this UTC month's call count and credits spent. It never spends a credit, so it is safe to poll before a batch.

Rate limits

Counted per API key in a sliding 60-second window. Requests over the limit return 429 with Retry-After; the limit follows the plan on the account that owns the key, and prepaid credits do not raise it.

PlanRequests / minute
Free6
Lite30
Pro120
Volume+300

Need more throughput than Volume+? Talk to us.

Limits and timing

  • Image and mask must each be between 32 bytes and 25 MB, whether uploaded or fetched from a URL. JPEG, PNG and WebP are the safe input formats.
  • /erase is synchronous: it holds the connection until the image is ready. Allow up to 90 seconds — past that you get 504 and are not charged. There is no callback or polling mode yet, so set a client timeout above 90s and retry the whole call.
  • A typical call lands in a few seconds; a cold model start is the slow case the timeout covers. Concurrency is bounded by your rate limit, so spread a batch across the minute rather than firing it all at once.
  • Nothing you send is kept for the API path — bytes are processed in flight and the result is returned in the response. Only the web editor stores uploads, and those expire after an hour.
  • The /v1 prefix is the contract: fields are only added, never removed or retyped. Breaking changes would ship as a new prefix.

Developers

API credits — volume ladder

Buy once, never expires, and the unit price drops as the pack grows. One call spends 1 credit, whatever the image size — so a pack’s credit count is the number of images it erases. These are API credits: your keys spend them first, and they are not used for editor downloads — that is why they cost a fraction of a web plan. Monthly Lite / Pro / Volume+ grants cover both and still reset on your billing date, see Pricing.

Starter

Try the API at volume rates.

$261,200 API credits · never expire

$0.022 / credit

Growth

Steady catalogue pipelines.

$665,000 API credits · never expire

$0.013 / credit

Scale

Product and media teams.

$19920,000 API credits · never expire

$0.010 / credit

Volume pack

Lowest unit price.

$666100,000 API credits · never expire

$0.007 / credit

Running 100,000+ credits a month? Talk to us for a dedicated rate.

Errors

Every failure is JSON shaped { "error": "…", "code": "…" }. Branch on code, not on the prose. Some codes add fields — 402 carries required and balance, 429 carries retryAfter.

StatuscodeWhen
400bad_requestNo image, unreadable base64, wrong Content-Type, file outside the size bounds, unfetchable URL, or a retired parameter (size, engine)
401invalid_api_keyMissing, unknown or revoked key
402insufficient_creditsAPI and web balance together cannot cover the call
404not_foundUnknown path
405method_not_allowedRight path, wrong method — /erase is POST only
429rate_limitOver the per-key requests-per-minute limit
429busyThe erase backend is saturated, not you — back off and retry
500internalUnexpected failure — safe to retry once
502erase_failedThe model rejected or failed the job — not charged
503misconfiguredServer-side configuration problem; retrying will not help
504timeoutThe model did not finish inside 90s — not charged, retry