One photo is a click. Three hundred is a plan. There are three ways to clean in bulk here, and three questions choose between them: how many files, how often, and how sensitive.
Quick comparison
| Route | Best for | Per batch | Where processed | Needs |
|---|---|---|---|---|
| Browser | Occasional, sensitive | Guest 1, free 5, Starter 25, Pro 100, Business 500 | Images and PDFs on your device; video and RAW on our server | Nothing |
| API | Scripts, schedules, other software | One file per request, unlimited requests | Our server | Any account, Free included |
| AI assistant (MCP) | A folder you can describe in words | Up to 200 per request, two at a time | Our server | Any account, Free included |
Browser: when confidentiality matters most
Drop the files, press Clean, download one .zip. Images and PDFs stay on your device. Daily allowance for those: 50 as a guest, 500 on a free account, unlimited on paid plans. A few dozen files is comfortable. Start with the image or PDF tool.
API: when the job repeats
Each request sends one file and returns the clean one, with results in headers. Endpoints: /api/v1/clean/image, /pdf, /video, /raw (see the API docs). Allowances match the site: 500 images and PDFs a day on a free account, no daily cap on paid plans, monthly video and RAW quotas everywhere.
for f in *.jpg; do
curl -s -X POST https://metadatatools.io/api/v1/clean/image \
-H "Authorization: Bearer $KEY" \
-F "file=@$f" -o "clean-$f" -D headers.txt
grep -i "x-metadata-remaining" headers.txt
doneimport fs from "node:fs";
const KEY = process.env.KEY;
const files = fs.readdirSync(".").filter((f) => /\.(jpe?g|png|webp)$/i.test(f));
for (const name of files) {
const form = new FormData();
form.append("file", new Blob([fs.readFileSync(name)]), name);
const res = await fetch("https://metadatatools.io/api/v1/clean/image", {
method: "POST",
headers: { Authorization: `Bearer ${KEY}` },
body: form,
});
if (!res.ok) { console.error(name, res.status, await res.text()); continue; }
console.log(name, "removed", res.headers.get("x-metadata-removed"), "left", res.headers.get("x-metadata-remaining"));
fs.writeFileSync(`clean-${name}`, Buffer.from(await res.arrayBuffer()));
}| Response | Meaning | What to do |
|---|---|---|
| 429 with Retry-After | More than 120 requests a minute | Wait, then retry |
429 daily_quota_exceeded | Today's image and PDF allowance is spent | Wait for midnight UTC or upgrade |
429 job_quota_exceeded | This month's video or RAW allowance is spent | Check GET /api/v1/usage, which costs nothing |
| 413 | File above your plan's size limit | Skip or upgrade |
| 415 | Unsupported file type | Skip |
| 422 | Damaged or encrypted file | Log and move on |
Video and RAW requests wait while the file is processed, so allow a long timeout. Write output to another folder or add a suffix so originals are never overwritten.
AI assistant: when describing the job is quicker than scripting it
The MCP server, included on every plan, lets you say “clean everything in ~/Photos/shoot and tell me what was in it.” A request covers up to 200 files, two at a time. Each copy is saved beside its original as name-clean.ext and every file is reported. Folders are not searched recursively and existing clean copies are skipped, so repeating a request is harmless. Setup: removing metadata with Claude, Cursor or ChatGPT.
Which one?
- Under about 30 images or PDFs, or anything sensitive: browser.
- Hundreds of files, or recurring: API.
- One folder, already working in Claude or Cursor: assistant.
- Video or RAW in bulk: API or assistant; mind monthly quotas and per-file size.
Do the sums: 300 photos equal 300 images, which one day on a free account (500 a day) covers. If they are RAW, each spends a monthly RAW cleaning instead: 10 on Free, 100 on Starter, 1,000 on Pro, wherever you start, because RAW is always processed on our server.
Good habits for any bulk run
- Clean copies; never make a clean file your only original.
- Count files in and out and scan the log for anything not verified clean.
- Spot-check one with
exiftool -a -G1 -s fileor the metadata viewer. - Keep originals privately; they record where and when.
- Rename on purpose, as file names carry places and dates.