Metadata Cleaning API

Remove metadata from images, videos, PDFs and RAW photos with one request. Every file is checked after cleaning, and we only call it clean when we can prove it.

Paste these docs into ChatGPT, Claude or your coding agent

Get a key

The API is part of the Business plan ($49 a month, or $449 a year). Subscribe and create keys on the API keys page. Keys start with amc_live_ and are shown once, so store yours somewhere safe. You can revoke a key at any time.

Send it with every request:

Authorization: Bearer amc_live_...

Quick start

Upload a file to /v1/clean as a form field named file:

curl -X POST https://api.aimetadatacleaner.com/v1/clean \
  -H "Authorization: Bearer $AMC_API_KEY" \
  -F [email protected]

You get back a report of what was found and removed, and a link to the cleaned file:

{
  "status": "clean",
  "file_type": "MOV",
  "kind": "video",
  "removed": ["Dates and times", "Device make and model", "GPS location",
              "Timed metadata tracks (e.g. face detection, scene data)"],
  "kept": [],
  "left": {},
  "notes": [],
  "size_in": 73905295,
  "size_out": 73221270,
  "seconds": 1.3,
  "download_url": "https://api.aimetadatacleaner.com/v1/files/45e1e41dddf84308a16486cc1bbb830f",
  "expires_in": 900,
  "usage": { "jobs_used": 12, "job_limit": 10000 }
}

Download the cleaned file from download_url. No key is needed for this, so you can pass the link on. It works once and expires after 15 minutes.

curl -o holiday-clean.mov "https://api.aimetadatacleaner.com/v1/files/45e1e41d..."

What the status means

StatusMeaning
cleanNothing identifying is left, and the content is proven unchanged (video and audio data, RAW sensor data, or image pixels, depending on the file).
unverifiedWe produced a file but can't prove it's clean. left and problems say why. Example: a RAW file from a camera too new for any raw decoder.
HTTP 422We couldn't clean it without risking damage, so no file is returned and the job isn't counted.

kept lists data left in on purpose, with the reason in notes. Example: RAW files keep camera make, model and lens, because raw editors need them to show the photo correctly.

Supported files

KindFormatsWhat's removed
ImagesJPEG, PNG, WebPEXIF, GPS, XMP, IPTC, C2PA Content Credentials, AI generation data (prompts, parameters)
VideoMP4, MOV, M4V, 3GP, MKV, WebMGPS, device, dates, C2PA, XMP, author, and hidden per-frame data tracks. Not re-encoded, so there's no quality loss.
PDFPDFAuthor, software, dates, XMP, C2PA, metadata inside embedded photos, and digital signatures (optional)
RAWCR2, CR3, NEF, ARW, RAF, RW2, DNGGPS, serial numbers, owner, dates, shutter count, XMP. The photo data is untouched. Nikon files keep their serial number and shutter count, because Nikon uses them to decode the photo's colours.

Not supported yet: AVI (convert to MP4 first) and password-protected PDFs.

Options

Pass as query parameters or as extra form fields.

OptionApplies toEffect
mode=reencodeImagesDefault. Redraws the image so none of the original file's bytes remain, and makes it harder to match with reverse image search. Changes are invisible.
mode=stripImagesRemoves metadata only. Pixels stay byte-for-byte identical.
format=jpeg|png|webpImagesOutput format. Default: the same as the input.
keep_signature=truePDFKeep digital signatures. They still name the signer and will show as invalid, because cleaning changes the file. Default: removed.
curl -X POST "https://api.aimetadatacleaner.com/v1/clean?mode=strip" \
  -H "Authorization: Bearer $AMC_API_KEY" \
  -F [email protected]

Limits

Business
Files per month10,000
Data per month1 TB uploaded
Largest file2 GB
Requests per minute60

Monthly limits reset on the 1st (UTC). Files that fail or aren't supported don't count. Check where you stand with:

curl https://api.aimetadatacleaner.com/v1/usage -H "Authorization: Bearer $AMC_API_KEY"

Errors

Errors come back as JSON with a code you can act on:

{ "error": { "code": "job_limit", "message": "You've used all 10,000 server jobs this month. ..." } }
HTTPCodeWhat to do
401missing_key, invalid_keyCheck the Authorization header, or create a new key
402job_limit, data_limitMonthly allowance used; it resets on the 1st
413file_too_largeThe file is over 2 GB
415unsupported_typeSee supported files above
422could_not_cleanThe file couldn't be cleaned safely; the message says why
429rate_limitedWait for the Retry-After seconds
503busyRetry after Retry-After seconds

Python

import requests

API = "https://api.aimetadatacleaner.com"
headers = {"Authorization": "Bearer " + API_KEY}

with open("photo.jpg", "rb") as f:
    r = requests.post(f"{API}/v1/clean", headers=headers, files={"file": f})
r.raise_for_status()
report = r.json()

if report["status"] == "clean":
    cleaned = requests.get(report["download_url"])
    open("photo-clean.jpg", "wb").write(cleaned.content)
else:
    print("Not verified clean:", report["left"], report["problems"])

JavaScript (Node 18+)

import { readFile, writeFile } from 'node:fs/promises';

const form = new FormData();
form.append('file', new Blob([await readFile('report.pdf')]), 'report.pdf');

const res = await fetch('https://api.aimetadatacleaner.com/v1/clean', {
  method: 'POST',
  headers: { Authorization: `Bearer ${process.env.AMC_API_KEY}` },
  body: form,
});
const report = await res.json();
if (!res.ok) throw new Error(report.error.message);

const file = await fetch(report.download_url);
await writeFile('report-clean.pdf', Buffer.from(await file.arrayBuffer()));

Your files

Files are processed on our server in Germany and never kept. The upload is deleted as soon as cleaning finishes, and the cleaned file is deleted once you download it, or after 15 minutes if you don't. We record the file type, size and result for billing and support, never the file name or contents.

Questions or a use case the limits don't fit? Contact us.