واجهة adasafe API
شغّل عمليات فحص إمكانية الوصول واقرأها من أدواتك الخاصة أو من CI أو من وكيل ذكاء اصطناعي. من خادم إلى خادم، REST، JSON. عنوان URL الأساسي https://api.adasafe.ai — كل مسار أدناه يتضمّن مسبقًا البادئة /v1 .
لا توجد درجة
يطلب كل مُكامِل رقمًا واحدًا. نحن لا نُرجعه — لأنه لا يوجد رقم صادق نقدّمه. فالامتثال لـ WCAG هو نجاح أو إخفاق لكل معيار، لذا فإن درجة مثل «متاح بنسبة 92%» ستكون مُختلَقة لا مقيسة.
بدلًا من ذلك، تحمل الاستجابات counts لكل درجة خطورة، ومستوى مخاطرة تصنيفيًا risk_level (مرتفع / متوسط / منخفض)، و coverage كتلة تُبيّن عدد الصفحات ضمن النطاق التي لم تُدقَّق. أنت تعرف دائمًا ما الذي فُحِص وما الذي لم يُفحص. لا يوجد حقل score, percent, أو grade — بحكم التصميم.
المصادقة
أنشئ مفتاحًا في صفحة مفاتيح API الخاصة بك (في الخطط المدفوعة فقط). أرسله بوصفه رمز حامل (Bearer token). المفاتيح من جهة الخادم حصريًا — فوجود مفتاح API في JavaScript المتصفّح يعني مفتاحًا مُسرَّبًا، وترفض الواجهة طلبات المتصفّح.
curl https://api.adasafe.ai/v1/me \ -H "Authorization: Bearer ada_live_your_key_here"
تشغيل عملية فحص
POST /v1/scans يحتاج إلى أمرين: ownership_confirmed: true (تُقِرّ بأنك تملك الموقع أو يحقّ لك فحصه)، وترويسة Idempotency-Key . المفتاح يجعل إعادة المحاولة آمنة — فالمفتاح نفسه يُرجع الفحص نفسه ولا يخصم من حصتك مرتين.
curl -X POST https://api.adasafe.ai/v1/scans \
-H "Authorization: Bearer ada_live_..." \
-H "Idempotency-Key: 3f9c1e7a-..." \
-H "Content-Type: application/json" \
-d '{"url": "https://example.com", "ownership_confirmed": true}'
# → 202 { "scan_id": "…", "status": "pending" }استعلم من GET /v1/scans/{id} عن الحالة (غير مكلف)، ثم اجلب GET /v1/scans/{id}/results بمجرد أن يصبح complete. أضف ?format=md للحصول على تقرير Markdown جاهز للصقه في issue أو تسليمه إلى مساعد ذكاء اصطناعي.
نقاط النهاية
- GET
/v1/meخطتك، وحصة الفحص المتبقية، والنطاقات (scopes)، وحدود المعدّل. - POST
/v1/scansتشغيل عملية فحص. يتطلّب ownership_confirmed وترويسة Idempotency-Key. - GET
/v1/scansعرض عمليات الفحص الخاصة بك، الأحدث أولًا (ترقيم صفحات بالمؤشّر). - GET
/v1/scans/{id}حالة الفحص، والأعداد، والتغطية، ومستوى المخاطرة — غير مكلف للاستعلام. - GET
/v1/scans/{id}/resultsالمخالفات الكاملة مع الإصلاحات. أضف ?format=md للحصول على Markdown. - POST
/v1/scans/batchفحص عدة صفحات كمهمة واحدة (وحدة حصة واحدة). - POST
/v1/discoverعرض الصفحات ضمن النطاق لموقعٍ ما قبل الفحص. - GET
/v1/sitesعرض مواقعك المُراقَبة. - POST
/v1/sitesإضافة موقع مُراقَب. يتطلّب ownership_confirmed. - PATCH
/v1/sites/{id}تحديث موقع مُراقَب (التسمية، والفاصل الزمني، والحالة النشطة). - DELETE
/v1/sites/{id}إيقاف مراقبة موقع. - POST
/v1/sites/{id}/scanفحص موقع مُراقَب الآن.
الحصص والحدود
تُستمدّ عمليات فحص API من المجمّع الشهري نفسه الذي تستخدمه لوحة التحكم — حصة مشتركة واحدة، لا سلّة منفصلة. عند نفاد عمليات الفحص تُرجَع 402 (الترقية للمتابعة)؛ أما التقدّم بسرعة مفرطة فيُرجع 429 مع ترويسة Retry-After (خفّف السرعة). مواقف مختلفة، وحلول مختلفة.
حول الإصلاحات
قد تحمل كل مخالفة fixمُقترحًا. وهو يذكر دائمًا source الخاص به، وما إذا كان قد جرى verified عبر إعادة فحص. أما الإصلاح المُقترَح بالذكاء الاصطناعي الذي لم يُتحقَّق منه فيُوسَم بذلك — ولا يظهر أبدًا بوصفه مؤكَّدًا. طبّق أي شيء بحُسن تقدير؛ فالفحص أداة، لا شهادة اعتماد.
Webhooks
تفضّل الدفع (Push) على الاستقصاء (Polling)؟ أضِف webhook من صفحة الإشعارات، وسيرسل adasafe عبر POST حمولة JSON موقّعة فور انتهاء أي فحص أو دفعة — بنفس البنية الصادقة للـ API: الأعداد والتغطية ومستوى خطورة تصنيفي، دون أي درجة رقمية ودون أي محتوى من الصفحة.
{
"event": "scan.completed",
"occurred_at": "2026-08-26T10:15:00+00:00",
"data": {
"type": "scan",
"id": "sc_…",
"url": "https://example.com/",
"status": "complete",
"risk_level": "High",
"counts": { "critical": 1, "serious": 3, "moderate": 5, "minor": 2, "total": 11 },
"coverage": { "pages_scanned": 1, "failed_pages": 0 },
"delta": { "new_issue_types": 2, "resolved": 1, "unchanged": 8, "first_scan": false },
"dashboard_url": "https://adasafe.ai/dashboard?scan_id=sc_…"
}
}تحمل كل عملية تسليم هذه الترويسات:
X-Adasafe-Event: scan.completed X-Adasafe-Delivery: d3f1… # stable across retries — dedupe on this X-Adasafe-Signature: ts=1756202100;h1=<hmac-sha256 hex> Content-Type: application/json User-Agent: adasafe-webhooks/1
التحقّق من التوقيع
لكل webhook مفتاح توقيع خاص به يُعرَض مرة واحدة عند إنشائه. ترويسة X-Adasafe-Signature بالصيغة ts=<unix>;h1=<hmac>. أعِد حساب HMAC-SHA256 لنص الطلب الخام مسبوقًا بالطابع الزمني، وقارِن في زمن ثابت، وارفض كل ما يزيد طابعه الزمني على خمس دقائق.
import hmac, hashlib, time
def verify(secret: str, header: str, body: bytes) -> bool:
ts, _, h1 = header.partition(";")
ts, h1 = ts.removeprefix("ts="), h1.removeprefix("h1=")
if abs(time.time() - int(ts)) > 300: # 5-minute replay window
return False
expected = hmac.new(secret.encode(), f"{ts}:".encode() + body,
hashlib.sha256).hexdigest()
return hmac.compare_digest(expected, h1)الأحداث
اختر الأحداث التي يشترك فيها كل webhook. تحمل ترويسة X-Adasafe-Event وحقل event في الحمولة الاسم:
scan.completed a single-page scan finished batch.completed a whole-site / batch scan finished monitoring.completed a scheduled monitoring run finished scan.failed a scan errored or was blocked (counts = null)
تُعاد محاولة أي استجابة خارج نطاق 2xx أو أي مهلة منتهية مع تراجع تدريجي حتى 24 ساعة. بعد 20 فشلًا متتاليًا يتعطّل الـ webhook تلقائيًا ونُبلغ المالك عبر البريد الإلكتروني. تُعيد المحاولات إرسال النص نفسه، لذا عامِل X-Adasafe-Delivery كمفتاح لمنع التكرار.