JPG · PNG · WebP
MP4 · MOV
ملفات API تُرفع بشكل خاص إلى تخزين مؤقت وتُحذف بعد المعالجة.
نظّف بيانات الصور والفيديو عبر API غير متزامنة وخاصة. ارفع الملف وأنشئ مهمة وانتظر الحالة النهائية ثم نزّل النتيجة.
MP4 · MOV
ملفات API تُرفع بشكل خاص إلى تخزين مؤقت وتُحذف بعد المعالجة.
تستخدم API الأرصدة المشتراة. يمكن استخدام أرصدة Advanced pack مع API، ولا يشمل Pro أرصدة API.
التنظيف في المتصفح يبقى على الجهاز ولا يرفع الملفات.
3 مهام نشطة لكل حساب
تبقى النتائج نحو 24 ساعة
احتفظ بمفاتيح API سرية واستخدمها على الخادم فقط. ملفات API تُرفع بشكل خاص، أما التنظيف في المتصفح فلا يرفع الملفات.
POST /api/v1/uploadsPOST /api/v1/jobsGET /api/v1/jobs/{id}GET /api/v1/jobs/{id}/resultGET /api/v1/usage# Bash + curl + jq. Stop on HTTP errors; do not save error JSON as an image.
set -euo pipefail
BASE='https://clearaimetadata.com'
UPLOAD=$(curl --fail-with-body -sS --max-time 120 -X POST "$BASE/api/v1/uploads" -H "Authorization: Bearer $CLEAR_AI_METADATA_API_KEY" -H 'Content-Type: image/png' --data-binary @photo.png | jq -er .uploadId)
# Keep this key and uploadId when retrying an uncertain create request.
REQUEST_ID=$(uuidgen)
JOB=$(curl --fail-with-body -sS --max-time 30 -X POST "$BASE/api/v1/jobs" -H "Authorization: Bearer $CLEAR_AI_METADATA_API_KEY" -H 'Content-Type: application/json' -H "Idempotency-Key: $REQUEST_ID" -d "$(jq -nc --arg uploadId "$UPLOAD" '{uploadId:$uploadId}')" | jq -er .id)
STATE='ready'
for attempt in $(seq 1 120); do
STATE=$(curl --fail-with-body -sS --max-time 30 "$BASE/api/v1/jobs/$JOB" -H "Authorization: Bearer $CLEAR_AI_METADATA_API_KEY" | jq -er .status)
case "$STATE" in
succeeded) break ;;
failed|canceled) echo "Job failed: $JOB" >&2; exit 1 ;;
esac
sleep 2
done
[ "$STATE" = 'succeeded' ] || { echo "Still pending: $JOB; query this job again, do not create another." >&2; exit 1; }
curl --fail -sS --max-time 300 "$BASE/api/v1/jobs/$JOB/result" -H "Authorization: Bearer $CLEAR_AI_METADATA_API_KEY" -o cleaned.pngimport { readFile, writeFile } from 'node:fs/promises';
const base = 'https://clearaimetadata.com';
const key = process.env.CLEAR_AI_METADATA_API_KEY;
const headers = { Authorization: 'Bearer ' + key };
const upload = await fetch(base + '/api/v1/uploads', {
method: 'POST',
headers: { ...headers, 'Content-Type': 'image/png' },
body: await readFile('photo.png'),
});
if (!upload.ok) throw new Error('Upload failed: ' + upload.status);
const { uploadId } = await upload.json();
const requestId = crypto.randomUUID(); // Reuse for retries with this uploadId.
const created = await fetch(base + '/api/v1/jobs', {
method: 'POST',
headers: {
...headers,
'Content-Type': 'application/json',
'Idempotency-Key': requestId,
},
body: JSON.stringify({ uploadId }),
});
if (!created.ok) throw new Error('Job failed: ' + created.status);
const { id } = await created.json();
let current;
for (let attempt = 0; attempt < 120; attempt += 1) {
const response = await fetch(base + '/api/v1/jobs/' + id, { headers });
if (response.status === 429 || response.status === 503) {
await new Promise(resolve => setTimeout(resolve, Math.min(60, Number(response.headers.get('Retry-After')) || 5) * 1000));
continue;
}
if (!response.ok) throw new Error('Status failed: ' + response.status);
current = await response.json();
if (current.status === 'succeeded' || current.status === 'failed') break;
await new Promise((resolve) => setTimeout(resolve, 2000));
}
if (current?.status !== 'succeeded') throw new Error('Job did not succeed');
const result = await fetch(base + '/api/v1/jobs/' + id + '/result', { headers });
if (!result.ok) throw new Error('Download failed: ' + result.status);
await writeFile('cleaned.png', Buffer.from(await result.arrayBuffer()));import os, time, uuid, requests
base = 'https://clearaimetadata.com'
headers = {'Authorization': 'Bearer ' + os.environ['CLEAR_AI_METADATA_API_KEY']}
with open('photo.png', 'rb') as image:
upload = requests.post(base + '/api/v1/uploads', headers={**headers, 'Content-Type': 'image/png'}, data=image, timeout=120)
upload.raise_for_status()
upload_id = upload.json()['uploadId']
created = requests.post(
base + '/api/v1/jobs',
headers={**headers, 'Content-Type': 'application/json', 'Idempotency-Key': str(uuid.uuid4())},
json={'uploadId': upload_id}, timeout=30,
)
created.raise_for_status()
job_id = created.json()['id']
current = {'status': 'ready'}
for _ in range(120):
response = requests.get(base + '/api/v1/jobs/' + job_id, headers=headers, timeout=30)
if response.status_code in (429, 503):
time.sleep(min(60, int(response.headers.get('Retry-After', '5'))))
continue
response.raise_for_status()
current = response.json()
if current['status'] in ('succeeded', 'failed'):
break
time.sleep(2)
if current['status'] != 'succeeded':
raise RuntimeError('Job did not succeed')
result = requests.get(base + '/api/v1/jobs/' + job_id + '/result', headers=headers, timeout=300)
result.raise_for_status()
with open('cleaned.png', 'wb') as output:
output.write(result.content){"uploadId":"7a6e...","credits":1,"expiresAt":"..."}
{"id":"job_...","status":"ready","credits":1}
{"id":"job_...","status":"succeeded","progress":100}
{"balance":499,"apiUsesTotal":12,"apiAvailable":true}| 400 | INVALID_REQUEST | Check the JSON body, UUID and required headers. |
| 401 | INVALID_API_KEY | Use an active Bearer key from /account/api. |
| 402 | INSUFFICIENT_CREDITS | Buy any credit pack; Pro does not include API credits. |
| 404 | UPLOAD_NOT_FOUND / NOT_FOUND | The upload or job does not belong to this account, or expired. |
| 409 | IDEMPOTENCY_CONFLICT | The idempotency key was already used with another upload. |
| 409 | UPLOAD_ALREADY_USED | Each upload belongs to one job. Retry that job with its original idempotency key, or upload a new file. |
| 409 | RESULT_NOT_READY | The job has not succeeded yet; poll the status endpoint. |
| 410 | RESULT_EXPIRED | The download window has expired; submit a new job. |
| 413 | FILE_TOO_LARGE | Images are limited to 10 MiB and videos to 25 MiB. |
| 415 | UNSUPPORTED_FORMAT | Use JPEG, PNG, WebP, MP4 or MOV. |
| 429 | RATE_LIMITED / UPLOAD_LIMIT / CONCURRENCY_LIMIT | Respect Retry-After and reduce concurrent work. |
| 503 | API_UNAVAILABLE / PROCESSOR_OFFLINE | The API or the local processor is temporarily unavailable. |