Erased

API Reference

Base URL: https://erased.ink/api/v1

All successful responses are application/json. Errors are application/problem+json (RFC 7807) — see the Error codes page.

POST /uploads

Issue a short-lived presigned R2 PUT URL.

Request

{
  "filename": "photo.png",
  "content_type": "image/png",
  "size": 4823109
}
FieldTypeNotes
filenamestringUsed for response headers only; the server assigns the object_key.
content_typestringOne of image/png, image/jpeg, image/webp, image/avif, image/heic, image/heif, image/jxl.
sizeintegerMax 10485760 (10 MB).

Response 200

{
  "upload_url": "https://...",
  "object_key": "in/2026-05-24/job_xxx.png",
  "expires_at": "2026-05-24T10:15:00Z"
}

You must PUT the file to upload_url before expires_at.


POST /jobs

Create a processing job.

Request body — three shapes

POST /api/v1/jobs accepts three body forms. Pick one based on what you have at hand:

Content-TypeRequired fieldsBest for
multipart/form-dataimage (file, ≤10MB) or object_key; mode; options (JSON string, optional)One-shot upload-and-process. Drop-in curl -F use.
application/json + image_base64image_base64 (≤1MB decoded), content_type, modeJSON-only toolchains (Zapier, n8n). Small images.
application/json + object_keyobject_key (from POST /uploads), modeLarge files / batch — pair with the presigned upload.

Example (object_key form)

{
  "object_key": "in/2026-05-24/job_xxx.png",
  "mode": "visible"
}

Response — sync (visible, metadata)

{
  "id": "job_xxx",
  "status": "succeeded",
  "mode": "visible",
  "result_url": "https://...",
  "result_expires_at": "2026-05-25T10:00:00Z",
  "processing_ms": 412
}

Response — async (invisible, all)

{
  "id": "job_xxx",
  "status": "queued",
  "mode": "invisible",
  "poll_url": "/api/v1/jobs/job_xxx",
  "poll_after_ms": 2000
}

Response — detect (read-only, no result_url)

{
  "id": "job_xxx",
  "status": "succeeded",
  "mode": "detect",
  "processing_ms": 487,
  "report": {
    "visible": {
      "detected": true,
      "confidence": 0.87,
      "region": [1820, 120, 80, 80],
      "label": "Gemini sparkle"
    },
    "metadata": {
      "c2pa": { "present": true, "manifest": { "claim_generator": "Gemini ..." } },
      "exif_ai_tags": { "Software": "Gemini" },
      "png_text_chunks": null,
      "xmp_digital_source_type": null
    },
    "invisible_external": {
      "synthid": {
        "status": "unsupported_locally",
        "verify_url": "https://support.google.com/gemini/answer/16722517"
      }
    },
    "overall_assessment": "Likely AI-generated by Gemini. C2PA Content Credentials present."
  }
}

detect never writes an output object; the original image is unchanged.


GET /jobs/:id

Poll an async job (and a valid read for sync jobs while their record is still in KV — about a 30-minute TTL).

Response — still processing

{
  "id": "job_xxx",
  "status": "processing",
  "mode": "invisible",
  "poll_after_ms": 2000
}

Response — succeeded

Same shape as the sync success response above.

Response — failed

{
  "id": "job_xxx",
  "status": "failed",
  "mode": "invisible",
  "error_code": "pipeline_error",
  "error_message": "..."
}

Authentication tiers

detect is the only mode available without an account (100 req/hour unauthenticated). All strip modes require at least a free account.

  • Free (signed in) — sign in via Google OAuth or an email magic link at /en/sign-in. Unlocks all strip modes. No API key issued.
  • Pro ($9 / month) — issued an API key. Pass it as Authorization: Bearer uk_.... Quotas are monthly. Includes 100 buffer credits/month for overage, and detect calls are unlimited.

Rate limits

detect is the only mode usable without an account: 100 req/hour unauthenticated, 500/hour for free accounts. All other modes require a free account (signed in) or Pro.

Quota groupModesFree (signed in)Pro
lightvisible, metadata10 / day5000 / month
heavyinvisible, all3 / day500 / month
uploadsPOST /uploads200 / hunlimited
detectdetect500 / hunlimited

Exceeding a limit returns 429 with a Retry-After header and an RFC 7807 body. Daily quotas reset at 00:00 UTC. Failed jobs automatically refund the bucket charge.