Examples
End-to-end snippets for the three common flows: anonymous detect, Pro-key visible strip, and Pro-key async invisible strip. See the API reference for the full surface.
curl — detect mode (no auth)
# 1. Presign
curl -X POST https://erased.ink/api/v1/uploads \
-H 'content-type: application/json' \
-d '{"filename":"test.png","content_type":"image/png","size":12345}'
# → {"upload_url":"...","object_key":"in/...","expires_at":"..."}
# 2. Upload (content-type must match step 1)
curl -X PUT "<upload_url>" --data-binary @test.png \
-H 'content-type: image/png'
# 3. Detect
curl -X POST https://erased.ink/api/v1/jobs \
-H 'content-type: application/json' \
-d '{"object_key":"in/...","mode":"detect"}'
# → {"id":"...","status":"succeeded","mode":"detect","report":{...}}curl — visible strip with a Pro API key
# Strip a visible watermark with a Pro API key
curl -X POST https://erased.ink/api/v1/jobs \
-H 'authorization: Bearer uk_...' \
-H 'content-type: application/json' \
-d '{"object_key":"in/...","mode":"visible"}'
# → {"id":"...","status":"succeeded","mode":"visible","result_url":"https://...","processing_ms":412}curl — async invisible strip with polling
# Async (invisible) — submit, then poll
curl -X POST https://erased.ink/api/v1/jobs \
-H 'authorization: Bearer uk_...' \
-H 'content-type: application/json' \
-d '{"object_key":"in/...","mode":"invisible"}'
# → {"id":"job_xxx","status":"queued","poll_url":"/api/v1/jobs/job_xxx","poll_after_ms":2000}
curl -H 'authorization: Bearer uk_...' \
https://erased.ink/api/v1/jobs/job_xxx
# → eventually: {"id":"...","status":"succeeded","mode":"invisible","result_url":"...","processing_ms":78421}JavaScript (browser, native fetch)
// Browser, using native fetch — no auth needed for visible
async function eraseVisible(file) {
const presign = await fetch("/api/v1/uploads", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({
filename: file.name,
content_type: file.type,
size: file.size,
}),
}).then((r) => r.json());
await fetch(presign.upload_url, {
method: "PUT",
body: file,
headers: { "content-type": file.type },
});
const job = await fetch("/api/v1/jobs", {
method: "POST",
headers: { "content-type": "application/json" },
body: JSON.stringify({ object_key: presign.object_key, mode: "visible" }),
}).then((r) => r.json());
return job.result_url;
}Python (httpx)
# Pro tier, async polling for an invisible-watermark strip
import httpx, pathlib, time
API = "https://erased.ink/api/v1"
KEY = "uk_..." # Pro API key
path = pathlib.Path("photo.png")
headers = {"authorization": f"Bearer {KEY}"}
# 1. Presign
presign = httpx.post(f"{API}/uploads", headers=headers, json={
"filename": path.name,
"content_type": "image/png",
"size": path.stat().st_size,
}).json()
# 2. Upload
httpx.put(
presign["upload_url"],
content=path.read_bytes(),
headers={"content-type": "image/png"},
)
# 3. Submit (async)
job = httpx.post(f"{API}/jobs", headers=headers, json={
"object_key": presign["object_key"],
"mode": "invisible",
}).json()
# 4. Poll
while job["status"] in ("queued", "processing"):
time.sleep(job.get("poll_after_ms", 2000) / 1000)
job = httpx.get(f"{API}/jobs/{job['id']}", headers=headers).json()
if job["status"] == "succeeded":
print(job["result_url"])
else:
print("failed:", job.get("error_code"), job.get("error_message"))