API التوثيق

كل ما تحتاجه لدمج التعرف على لوحات المركبات في تطبيقك.

محدَّث دائمًا: مرجع OpenAPI التفاعلي متاح على api.anpr.software/docs

تبحث عن التعرف على لوحات المركبات خارج دول الخليج؟

البدء السريع

ابدأ مع واجهة برمجة تطبيقات ANPR.software في أقل من 5 دقائق. اتبع هذه الخطوات لإجراء أول استدعاء API.

1. احصل على مفتاح API

سجّل حساباً مجانياً للحصول على مفتاح API. أول 100 رصيد مجاني.

سجّل مجاناً

2. أرسل أول طلب

curl -X POST "https://api.anpr.software/v1/detect" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@car_image.jpg"

3. احصل على النتيجة

{
  "success": true,
  "plates_found": 1,
  "plates": [
    {
      "plate_id": 0,
      "position": {
        "x1": 120, "y1": 340, "x2": 280, "y2": 390
      },
      "detection_confidence": 0.95,
      "text": {
        "plate_code_en": "AZ",
        "plate_code_ar": "أ م",
        "plate_number_en": "53",
        "plate_number_ar": "٥٣",
        "confidence": 0.9375,
        "min_char_confidence": 0.92
      },
      "attributes": {
        "country": "uae",
        "emirate": "dubai",
        "color": "white",
        "type": "private",
        "size": "long"
      },
      "quality": {
        "plate_width_px": 160,
        "plate_height_px": 50,
        "band": "optimal",
        "note": "plate 150px or wider - the capture size ANPR cameras are specified for"
      }
    }
  ],
  "body": { "label": "suv", "make_model": { "brand": "Toyota", "model": "Land Cruiser" } },
  "cost": 0.01,
  "credits": 2,
  "timestamp": "2026-02-14T05:16:17.412633"
}

المصادقة

جميع طلبات API المحمية تتطلب مصادقة باستخدام رمز Bearer. أدرج مفتاح API في ترويسة Authorization.

Authorization: Bearer YOUR_API_KEY

حافظ على سرية مفتاح API. لا تكشفه في الكود من جانب العميل أو المستودعات العامة.

النقاط النهائية

عنوان URL الأساسي: https://api.anpr.software

GET/health
POST/v1/detect
POST/v1/detect/{country}
POST/v1/car
POST/v1/body
POST/v1/frames
GET/v1/frames/{job_id}
POST/v1/read
GET/v1/usage
POST/v1/plate-logo

GET /health - فحص الصحة

نقطة نهائية عامة - تحقق من صحة الـ API وحالة النماذج.

الطلب

curl https://api.anpr.software/health

الاستجابة

{
  "status": "healthy",
  "models": {
    "detection": true,
    "classification": true,
    "ocr": true
  },
  "storage": true,
  "timestamp": "2026-02-14T05:16:17.412633"
}

POST /v1/detect - كشف اللوحات

نقطة نهائية محمية - تكشف كل اللوحات الظاهرة وتصنّف كلًا منها (الدولة، الإمارة، اللون، النوع، الحجم) وتقرأها بالعربية والإنجليزية. تتضمن الاستجابة أيضًا حقل body مع الملف الكامل للسيارة الرئيسية المكتشفة (نوع الهيكل، اللون، زاوية التصوير، الماركة، الموديل).

باراميترات استعلام اختيارية

camera_idمعرّف مصدر الكاميرا. عندما يطابق إحدى كاميراتك النشطة (انظر إعدادات المواقف)، تُسجَّل حركة دخول/خروج لكل لوحة مكتشفة.
main_onlyعند ضبطه على true يتخطى مسح الخلفية الكامل ويعيد لوحة السيارة الرئيسية فقط - أسرع، ويتجنب التقاط لوحات مركبات أخرى.
plate_onlyعند ضبطه على true يتخطى كل نماذج السيارة ويعيد بيانات اللوحة فقط - أسرع بنحو 2.5 مرة. يكون حقل body عندها null.
plate_attributesالقيمة الافتراضية true. عند false تعمل المرحلة الأولى فقط من مصنّف اللوحة: تبقى الدولة متوقَّعة — فهي التي تختار أوزان القراءة — وتُتخطّى خصائص الدولة (الإمارة واللون والنوع والحجم ولون النص). أرخص بتمريرة نموذج واحدة لكل مجموعة دولة في الإطار. لا يغيّر السعر.
body, color, position, brand, car_modelكلها true افتراضياً. أطفئ مصنّف سيارة واحداً في كل مرة. وضع الخمسة جميعاً على false يساوي تماماً plate_only=true، بما في ذلك الفوترة. إطفاء position يكلّفك اتجاه المواقف: فهو زاوية الرؤية التي تُطابَق بها إعدادات الدخول والخروج للكاميرا، فتصبح الحركات المسجّلة بـ camera_id بقيمة unknown.
all_carsعند ضبطه على true تُصنَّف كل سيارة في الصورة بدلًا من السيارة الرئيسية وحدها. يضيف مصفوفة cars - عنصر لكل مركبة بنوع هيكلها ولونها وزاوية تصويرها وماركتها وموديلها - ويضبط car_id على كل لوحة.

الطلب

curl -X POST "https://api.anpr.software/v1/detect?camera_id=cam-north-01" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@car_image.jpg" \
  -F 'params={"location":"gate-1","lane":"entry"}'

الاستجابة (تم العثور على لوحات)

{
  "success": true,
  "plates_found": 1,
  "plates": [
    {
      "plate_id": 0,
      "position": {
        "x1": 120,
        "y1": 340,
        "x2": 280,
        "y2": 390
      },
      "detection_confidence": 0.95,
      "text": {
        "plate_code_en": "AZ",
        "plate_code_ar": "أ م",
        "plate_number_en": "53",
        "plate_number_ar": "٥٣",
        "confidence": 0.9375,
        "min_char_confidence": 0.92,
        "characters": [
          { "char": "A", "ocr_class": "A", "script": "en", "confidence": 0.96, "bbox": [12, 6, 28, 40] },
          { "char": "Z", "ocr_class": "Z", "script": "en", "confidence": 0.94, "bbox": [30, 6, 46, 40] },
          { "char": "5", "ocr_class": "5", "script": "en", "confidence": 0.92, "bbox": [70, 5, 88, 41] },
          { "char": "3", "ocr_class": "3", "script": "en", "confidence": 0.93, "bbox": [90, 5, 108, 41] }
        ],
        "plate_number_ar_source": "transliterated",
        "plate_code_ar_source": "detected"
      },
      "attributes": {
        "country": "uae",
        "emirate": "dubai",
        "color": "white",
        "type": "private",
        "size": "long",
        "text_color": "black"
      },
      "quality": {
        "plate_width_px": 160,
        "plate_height_px": 50,
        "band": "optimal",
        "note": "plate 150px or wider - the capture size ANPR cameras are specified for"
      }
    }
  ],
  "body": {
    "label": "suv",
    "confidence": 0.87,
    "probs": {
      "sedan": 0.04, "hatchback": 0.01, "wagon": 0.01, "coupe": 0.02,
      "convertible": 0.00, "suv": 0.87, "pickup": 0.04, "minivan": 0.01
    },
    "car_bbox": { "x1": 120, "y1": 240, "x2": 980, "y2": 880 },
    "car_confidence": 0.94,
    "color": { "name": "white", "hex": "#f2f2f2", "rgb": [242, 242, 242] },
    "position": {
      "label": "back",
      "confidence": 0.97,
      "probs": { "front": 0.005, "back": 0.97, "side": 0.005, "semiside_front_left": 0.005, "semiside_front_right": 0.005, "semiside_back_left": 0.005, "semiside_back_right": 0.005 },
      "probs_coarse": { "front": 0.005, "back": 0.97, "side": 0.005, "semi_side": 0.02 }
    },
    "brand": {
      "label": "Toyota",
      "confidence": 0.82,
      "probs": { "Toyota": 0.82, "Lexus": 0.06, "Nissan": 0.05, "Honda": 0.04, "Mitsubishi": 0.03 }
    },
    "model": {
      "label": "Toyota|Land Cruiser",
      "confidence": 0.71,
      "probs": { "Toyota|Land Cruiser": 0.71, "Toyota|Prado": 0.12, "Lexus|LX": 0.08, "Nissan|Patrol": 0.06, "Toyota|Fortuner": 0.03 }
    },
    "make_model": {
      "brand": "Toyota",
      "brand_confidence": 0.82,
      "brand_source": "stage2",
      "model": "Land Cruiser",
      "model_full": "Toyota|Land Cruiser",
      "model_confidence": 0.71,
      "brand_uncertain": false,
      "decision": "agreement"
    }
  },
  "cost": 0.01,
  "credits": 2,
  "timestamp": "2026-02-14T05:16:17.412633"
}

الاستجابة (بدون لوحات)

{
  "success": true,
  "plates_found": 0,
  "plates": [],
  "body": {
    "label": "sedan",
    "confidence": 0.72,
    "probs": {
      "sedan": 0.72, "hatchback": 0.08, "wagon": 0.03, "coupe": 0.09,
      "convertible": 0.01, "suv": 0.05, "pickup": 0.01, "minivan": 0.01
    },
    "car_bbox": null,
    "car_confidence": null,
    "color": { "name": "black", "hex": "#1a1a1a", "rgb": [26, 26, 26] },
    "position": {
      "label": "front",
      "confidence": 0.94,
      "probs": { "front": 0.94, "back": 0.01, "side": 0.01, "semiside_front_left": 0.01, "semiside_front_right": 0.01, "semiside_back_left": 0.01, "semiside_back_right": 0.01 },
      "probs_coarse": { "front": 0.94, "back": 0.01, "side": 0.01, "semi_side": 0.04 }
    },
    "brand": {
      "label": "Nissan",
      "confidence": 0.68,
      "probs": { "Nissan": 0.68, "Toyota": 0.11, "Honda": 0.09, "Hyundai": 0.07, "Kia": 0.05 }
    },
    "model": {
      "label": "Nissan|Altima",
      "confidence": 0.54,
      "probs": { "Nissan|Altima": 0.54, "Nissan|Maxima": 0.18, "Toyota|Camry": 0.12, "Honda|Accord": 0.10, "Hyundai|Sonata": 0.06 }
    },
    "make_model": {
      "brand": "Nissan",
      "brand_confidence": 0.68,
      "brand_source": "stage2",
      "model": "Altima",
      "model_full": "Nissan|Altima",
      "model_confidence": 0.54,
      "brand_uncertain": false,
      "decision": "agreement"
    }
  },
  "cost": 0.005,
  "credits": 1,
  "timestamp": "2026-02-14T05:16:17.412633"
}

عدة سيارات في صورة واحدة

افتراضيًا تصف الاستجابة سيارة واحدة: الأبرز في الصورة، عبر حقل body. تُعاد بقية اللوحات في الصورة أيضًا، لكن لا شيء يوضّح لأي سيارة تعود - لذا إذا خزّنت النتيجة، فإن إسناد body لكل لوحة يسجّل السيارة الواحدة تحت هويات متعددة. مرّر all_cars=true فتُصنَّف كل سيارة بذاتها ضمن مصفوفة cars، مع وسم كل لوحة بـ car_id السيارة التي تقع عليها.

الطلب

curl -X POST "https://api.anpr.software/v1/detect?all_cars=true&main_only=true" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@parking_camera.jpg"

الاستجابة

{
  "success": true,
  "plates_found": 2,
  "plates": [
    {
      "plate_id": 0,
      "car_id": 0,
      "position": { "x1": 334, "y1": 583, "x2": 401, "y2": 625 },
      "detection_confidence": 0.861,
      "text": {
        "plate_code_en": "GC", "plate_number_en": "74523",
        "plate_code_ar": "", "plate_number_ar": "",
        "confidence": 0.941, "min_char_confidence": 0.902
      },
      "attributes": { "country": "uae", "emirate": "dubai", "color": "white", "type": "private" }
    },
    {
      "plate_id": 1,
      "car_id": 1,
      "position": { "x1": 1599, "y1": 392, "x2": 1651, "y2": 410 },
      "detection_confidence": 0.769,
      "text": {
        "plate_code_en": "", "plate_number_en": "138813",
        "confidence": 0.812, "min_char_confidence": 0.633
      },
      "attributes": { "country": "uae", "emirate": "abudhabi", "color": "white", "type": "private" }
    }
  ],
  "cars": [
    {
      "car_id": 0,
      "plate_ids": [0],
      "car_bbox": { "x1": 206, "y1": 300, "x2": 588, "y2": 682 },
      "car_confidence": 0.934,
      "label": "suv",
      "confidence": 0.8342,
      "color": { "name": "gray", "hex": "#818488", "rgb": [129, 136, 138] },
      "position": { "label": "front", "confidence": 0.9831 },
      "make_model": {
        "brand": "Jeep", "brand_confidence": 0.751,
        "model": "Cherokee", "model_full": "Jeep|Cherokee", "model_confidence": 0.6658,
        "brand_uncertain": false, "decision": "agreement"
      }
    },
    {
      "car_id": 1,
      "plate_ids": [1],
      "car_bbox": { "x1": 1385, "y1": 229, "x2": 1702, "y2": 466 },
      "car_confidence": 0.384,
      "label": "suv",
      "confidence": 0.8053,
      "color": { "name": "dark_gray", "hex": "#56585b", "rgb": [86, 88, 91] },
      "position": { "label": "semiside_front_right", "confidence": 1.0 },
      "make_model": {
        "brand": "Nissan", "brand_confidence": 0.8313,
        "model": "Patrol", "model_full": "Nissan|Patrol", "model_confidence": 0.4233,
        "brand_uncertain": false, "decision": "agreement"
      }
    }
  ],
  "body": { "label": "suv", "make_model": { "brand": "Jeep", "model": "Cherokee" } },
  "cost": 0.02,
  "credits": 4,
  "timestamp": "2026-08-04T11:19:24.350986"
}
  • ترتيب cars حسب ثقة الكشف، ويظل body مطابقًا لـ cars[0]، لذا لا يتأثر أي تكامل يقرأ body فقط.
  • اللوحة التي لا تقع على سيارة مكتشفة تحمل car_id: null. تُعاد وتُقرأ كالمعتاد - لكنها ببساطة دون خصائص مركبة، بدل أن تستعير خصائص سيارة أخرى.
  • السيارة التي تعذّرت قراءة لوحتها تظهر في cars مع plate_ids فارغة.
  • مع camera_id تُسجَّل كل سيارة كحركة موقف مستقلة بخصائصها واتجاهها. وجمعه مع main_only=true يعيد اللوحات الواقعة على سيارة مكتشفة فقط - الخيار المعتاد للكاميرا الثابتة.
  • يكلّف تمريرة واحدة لمصنّفات السيارة لكل سيارة مكتشفة. وقراءة اللوحة من قصاصة سيارتها غالبًا أوضح من قراءتها من الإطار الكامل.
  • يمسح كشف السيارات الإطار على شكل مربعات متداخلة بدل النظر إليه مرة واحدة، فتُكتشف المركبات البعيدة عن الكاميرا بدل تجاهلها - في إطار حقيقي لموقف فيه ست سيارات، تم التعرف على 4 بدل 2. كما يتناسب حجم مدخلات الكشف مع صورتك، فيحافظ إطار كاميرا عريض بعرض 2560 بكسل على وضوح اللوحات الصغيرة أمام النموذج.

POST /v1/detect/ - كشف بدولة معروفة

مطابق لـ ‎/v1/detect‎ لكن دولة اللوحة مثبّتة بقيمة المسار، فيُتجاوز تصنيف الدولة بالكامل - استدلال أسرع. استخدمه عندما لا ترى كاميرتك أو موقعك سوى لوحات دولة واحدة. القيم المدعومة: uae, saudi_arabia, kuwait, qatar, bahrain, oman. اجمعه مع ‎plate_only=true‎ لأسرع استجابة ممكنة.

curl -X POST "https://api.anpr.software/v1/detect/uae?plate_only=true" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@car_image.jpg"

POST /v1/frames - الكاميرات المتدفقة

ينفّذ ‎/v1/detect‎ النماذج قبل أن يجيب، وهو المطلوب عندما ينتظر أحدهم النتيجة. أما الكاميرا التي تبث باستمرار فمسألة مختلفة: يستغرق الاستدلال نحو ثانية، فيتكدّس موقع يرسل عشرات الإطارات في الثانية خلفه وتنتهي مهلته. يستقبل ‎/v1/frames‎ الإطار ويعود فورًا - بقياس 49 طلبًا في الثانية ووسيط 14 ملّي ثانية - بينما يجري الكشف على عامل خلفه. تُكتب النتائج في بيانات المواقف وتُرسل إلى ويب هوك plate_detected لديك، ويمكنك أيضًا الاستعلام عنها.

الطلب

curl -X POST "https://api.anpr.software/v1/frames?camera_id=cam-north-01" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "[email protected]"

الاستجابة

{
  "success": true,
  "accepted": true,
  "job_id": "e345ba0fd88f44099279d378f689667a",
  "camera_id": "cam-north-01",
  "status": "queued",
  "superseded_job_id": "008c3608a2d240b19fd4341504677192",
  "pending_cameras": 2,
  "timestamp": "2026-08-04T18:37:24.101Z"
}

يُعالَج أحدث إطار فقط لكل كاميرا

هذا هو الجزء الذي ينبغي فهمه قبل البناء عليه. يحتفظ الطابور بإطار واحد معلّق لكل كاميرا. فإذا وصل إطار أحدث من الكاميرا نفسها قبل أن يلتقط العامل الإطار السابق، تنتهي المهمة الأقدم بحالة superseded ولا تُعالَج ولا تُحتسب في الفوترة. وتخبرك الاستجابة بذلك عبر الحقل superseded_job_id.

  • يتحدّد حجم التراكم بعدد كاميراتك لا بسرعة إرسالك. 40 إطارًا في الثانية أو 400 - عمق الطابور نفسه.
  • يرى العاملون دائمًا الحالة الراهنة للكاميرا. أما طابور «الوارد أولًا يخرج أولًا» فكان سيتأخر أكثر كل ثانية، فتقرأ لوحات من مشهد تغيّر أصلًا.
  • الإطارات المُهمَلة هي الزائدة عن الحاجة - السيارات المتوقفة نفسها، التي تندمج في الحركة المسجّلة لها سلفًا. في دفعة من 30 إطارًا عبر كاميرتين، عولجت 3 إطارات واستُبدل 27.

باراميترات الاستعلام

camera_idمطلوب. يجب أن يكون إحدى كاميراتك النشطة - الكاميرات غير المعروفة تُرفض بـ 404 بدل إدراجها في الطابور.
main_onlyالقيمة الافتراضية true. اللوحات الواقعة على السيارة المكتشفة فقط، وهو ما تريده الكاميرا الثابتة عادةً.
all_carsالتعرف على كل سيارة في الإطار بشكل منفصل، كما في ‎/v1/detect‎.
plate_onlyتخطّي نماذج السيارة بالكامل وإعادة بيانات اللوحة فقط.
plate_attributesكما في ‎/v1/detect‎. يُحمل داخل المهمة ليلتزم به العامل.
countryتثبيت دولة اللوحة، كما في ‎/v1/detect/‎.

متابعة إطار

يعيد ‎GET /v1/frames/‎ حالة المهمة، ونتيجة الكشف الكاملة بعد اكتمالها. تُحفظ سجلات المهام لمدة ساعة. ويعيد ‎GET /v1/frames‎ عمق الطابور الحالي.

curl "https://api.anpr.software/v1/frames/e345ba0fd88f44099279d378f689667a" \
  -H "Authorization: Bearer YOUR_API_KEY"
queuedفي انتظار عامل.
processingاستلمها أحد العاملين.
doneتمت المعالجة - يحتوي result على نفس محتوى استجابة ‎/v1/detect‎.
supersededاستبدلها إطار أحدث من الكاميرا نفسها. لم تُعالَج ولم تُحتسب.
failedحدث خطأ ما؛ يوضّحه الحقل error.

الفوترة والحدود

تُحتسب عليك الإطارات التي تُعالَج فعليًا، لكل لوحة، تمامًا كما في ‎/v1/detect‎. أما الإطارات المستبدَلة فلا تكلّف شيئًا - في الدفعة أعلاه، بلوحة واحدة لكل إطار بسعر 0.005 دولار، 0.015 دولار بدل 0.15 دولار لو عولجت الثلاثون كلها. وتبقى حصتك الشهرية سارية عند الإرسال، بينما لا يسري حد الطلبات في الدقيقة: فمن المتوقع أن تتجاوزه الكاميرا المتدفقة، وقاعدة «إطار واحد لكل كاميرا» هي ما يضبط العمل الفعلي. الحد الأقصى لحجم الإطار 2 ميغابايت.

POST /v1/car - التعرف على السيارات

نقطة نهائية محمية - تكتشف السيارة الرئيسية في الصورة وتعيد ملفها الكامل - نوع الهيكل واللون السائد وزاوية التصوير والماركة والموديل - دون كشف لوحات أو قراءة. يمكن إيقاف أي مكوّن عبر باراميتر استعلام لتخطي نموذجه وتسريع الاستجابة.

مفاتيح المكوّنات (باراميترات استعلام، جميعها true افتراضيًا)

body_typeتصنيف نوع الهيكل (8 فئات)
colorتحليل اللون السائد
positionتصنيف زاوية التصوير
brandتصنيف الماركة (181 ماركة)
car_modelتصنيف الموديل (2,003 فئة)

الطلب

curl -X POST "https://api.anpr.software/v1/car" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@car_image.jpg"

الاستجابة

{
  "success": true,
  "body": {
    "label": "coupe",
    "confidence": 0.7519,
    "probs": {
      "sedan": 0.037, "hatchback": 0.0268, "wagon": 0.0068, "coupe": 0.7519,
      "convertible": 0.0668, "suv": 0.059, "pickup": 0.0128, "minivan": 0.039
    },
    "car_bbox": { "x1": 234, "y1": 616, "x2": 1166, "y2": 1071 },
    "car_confidence": 0.956,
    "color": { "name": "silver", "hex": "#b9c2cb", "rgb": [185, 194, 203] },
    "position": {
      "label": "semiside_front_left",
      "confidence": 0.9998,
      "probs": { "front": 0.0, "back": 0.0, "side": 0.0, "semiside_front_left": 1.0, "semiside_front_right": 0.0, "semiside_back_left": 0.0, "semiside_back_right": 0.0 },
      "probs_coarse": { "front": 0.0, "back": 0.0, "side": 0.0, "semi_side": 1.0 }
    },
    "brand": {
      "label": "Porsche",
      "confidence": 0.7751,
      "probs": { "Porsche": 0.7751, "Hyundai": 0.0037, "Volkswagen": 0.0034, "Honda": 0.0033, "Toyota": 0.003 }
    },
    "model": {
      "label": "Porsche|911",
      "confidence": 0.6876,
      "probs": { "Porsche|911": 0.6876, "Porsche|Boxster": 0.0042, "Li|L6": 0.0031, "Volkswagen|beetle": 0.0023, "Porsche|Cayman": 0.0014 }
    },
    "make_model": {
      "brand": "Porsche",
      "brand_confidence": 0.7751,
      "brand_source": "stage2",
      "model": "911",
      "model_full": "Porsche|911",
      "model_confidence": 0.6876,
      "brand_uncertain": false,
      "decision": "agreement"
    }
  },
  "cost": 0.005,
  "credits": 1,
  "timestamp": "2026-07-04T12:00:00.000000"
}

كائن make_model هو الحكم المدمج للماركة والموديل والحقل الموصى بالبناء عليه. عند خلاف لا يمكن حسمه بين المصنّفَين تحجب الواجهة الإجابة (null مع brand_uncertain: true) بدلًا من التخمين؛ ويخبرك حقل decision بقاعدة الدمج التي أنتجت الحكم.

اعرف المزيد عن تغطية التعرف على السيارات وحالات الاستخدام

POST /v1/body - تصنيف هيكل المركبة

نقطة نهائية محمية - تصنّف السيارة وتعيد نفس شكل استجابة ‎/v1/car‎ مع تفعيل كل المكوّنات.

الطلب

curl -X POST "https://api.anpr.software/v1/body" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@car_image.jpg"

الاستجابة

{
  "success": true,
  "body": {
    "label": "suv",
    "confidence": 0.87,
    "probs": {
      "sedan": 0.04,
      "hatchback": 0.01,
      "wagon": 0.01,
      "coupe": 0.02,
      "convertible": 0.00,
      "suv": 0.87,
      "pickup": 0.04,
      "minivan": 0.01
    },
    "car_bbox": { "x1": 120, "y1": 240, "x2": 980, "y2": 880 },
    "car_confidence": 0.94,
    "color": { "name": "white", "hex": "#f2f2f2", "rgb": [242, 242, 242] },
    "position": {
      "label": "back",
      "confidence": 0.97,
      "probs": { "front": 0.005, "back": 0.97, "side": 0.005, "semiside_front_left": 0.005, "semiside_front_right": 0.005, "semiside_back_left": 0.005, "semiside_back_right": 0.005 },
      "probs_coarse": { "front": 0.005, "back": 0.97, "side": 0.005, "semi_side": 0.02 }
    },
    "brand": {
      "label": "Toyota",
      "confidence": 0.82,
      "probs": { "Toyota": 0.82, "Lexus": 0.06, "Nissan": 0.05, "Honda": 0.04, "Mitsubishi": 0.03 }
    },
    "model": {
      "label": "Toyota|Land Cruiser",
      "confidence": 0.71,
      "probs": { "Toyota|Land Cruiser": 0.71, "Toyota|Prado": 0.12, "Lexus|LX": 0.08, "Nissan|Patrol": 0.06, "Toyota|Fortuner": 0.03 }
    },
    "make_model": {
      "brand": "Toyota",
      "brand_confidence": 0.82,
      "brand_source": "stage2",
      "model": "Land Cruiser",
      "model_full": "Toyota|Land Cruiser",
      "model_confidence": 0.71,
      "brand_uncertain": false,
      "decision": "agreement"
    }
  },
  "cost": 0.005,
  "credits": 1,
  "timestamp": "2026-02-14T05:16:17.412633"
}

نقطة نهائية قديمة: يُفضّل للتكاملات الجديدة استخدام ‎/v1/car‎ التي تضيف مفاتيح لكل مكوّن لاستجابات أسرع.

الفئات الممكنة: sedan (سيدان)، hatchback (هاتشباك)، wagon (واغن)، coupe (كوبيه)، convertible (كابريوليه)، suv (دفع رباعي)، pickup (بيك أب)، minivan (ميني فان). تُرجَع الفئة "unknown" فقط عند فشل تحميل النموذج - اعرضها بصفة "غير متاح".

تكون قيمة car_bbox هي null عندما لا يجد كاشف السيارة مركبة بثقة عالية وتعمل المُصنِّفة على الصورة كاملة كحل احتياطي. لا ترسم إطار قص عند كونها null.

قيمة confidence هي درجة softmax العليا (0–1) وليست معايَرة - اعتبر التصنيف هو الإجابة وليس الحجم. يحتوي كائن probs على التوزيع الكامل لجميع الفئات الثمانية.

POST /v1/read - قراءة لوحة مقصوصة

نقطة نهائية محمية - ارفع صورة لوحة مقصوصة مسبقًا لتصنيفها وقراءتها مباشرة. يُتخطى كشف اللوحات، ما يجعلها أسرع عندما تملك قصاصة لوحة معزولة أصلًا.

الطلب

curl -X POST "https://api.anpr.software/v1/read" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "file=@plate_crop.jpg"

الاستجابة

{
  "success": true,
  "text": {
    "plate_code_en": "AZ",
    "plate_code_ar": "أ م",
    "plate_number_en": "53",
    "plate_number_ar": "٥٣",
    "characters": [
      { "char": "A", "ocr_class": "A", "script": "en", "confidence": 0.96, "bbox": [12, 6, 28, 40] },
      { "char": "5", "ocr_class": "5", "script": "en", "confidence": 0.92, "bbox": [70, 5, 88, 41] }
    ],
    "plate_number_ar_source": "transliterated",
    "plate_code_ar_source": "detected"
  },
  "confidence": 0.94,
  "attributes": {
    "country": "uae",
    "emirate": "dubai",
    "color": "white",
    "type": "private",
    "size": "long",
    "text_color": "black"
  },
  "quality": {
    "plate_width_px": 220,
    "plate_height_px": 70,
    "band": "optimal",
    "note": "plate 150px or wider - the capture size ANPR cameras are specified for"
  },
  "cost": 0.005,
  "credits": 1,
  "timestamp": "2026-02-14T05:16:17.412633"
}

GET /v1/usage - إحصائيات الاستخدام

نقطة نهائية محمية - احصل على إحصائيات الاستخدام والرصيد المتبقي.

الطلب

curl "https://api.anpr.software/v1/usage?days=30" \
  -H "Authorization: Bearer YOUR_API_KEY"

الاستجابة (Free)

{
  "tier": "free",
  "plan": "free",
  "credits": {
    "balance": 94,
    "held": 0,
    "unit": "credits",
    "unit_price": 0.005,
    "never_expires": true
  },
  "limits": {
    "monthly_limit": 1000,
    "requests_remaining": 997,
    "rate_limit_per_minute": 20
  },
  "usage_this_month": {
    "requests": 3,
    "plates_detected": 2,
    "cost": 0.03
  },
  "period_days": 30,
  "daily_usage": [
    {
      "date": "2026-02-14",
      "requests": 3,
      "plates_detected": 2,
      "cost": 0.03
    }
  ]
}

الاستجابة (Business)

{
  "tier": "business",
  "plan": "business",
  "credits": {
    "balance": 8432,
    "held": 0,
    "unit": "credits",
    "unit_price": 0.005,
    "never_expires": true
  },
  "limits": {
    "monthly_limit": 60000,
    "requests_remaining": 58750,
    "rate_limit_per_minute": 100
  },
  "usage_this_month": {
    "requests": 1250,
    "plates_detected": 980,
    "cost": 11.15
  },
  "period_days": 30,
  "daily_usage": [
    {
      "date": "2026-02-13",
      "requests": 320,
      "plates_detected": 245,
      "cost": 2.825
    },
    {
      "date": "2026-02-14",
      "requests": 180,
      "plates_detected": 142,
      "cost": 1.61
    }
  ]
}

معالجة الأخطاء

عند حدوث خطأ، يُرجع الـ API رمز حالة HTTP مناسب ورسالة خطأ.

الرمزالوصف
400طلب غير صالح - صورة أو معلمات غير صالحة
401غير مصرّح - مفتاح API مفقود أو غير صالح
402الدفع مطلوب - رصيد غير كافٍ (برو/مؤسسات)
429تجاوز حد الطلبات - طلبات كثيرة جداً
500خطأ في الخادم - حاول مرة أخرى لاحقاً

أمثلة استجابات الأخطاء

401 Unauthorized

{"detail": "Missing Authorization header"}
{"detail": "Invalid API key"}

429 Rate Limited

{"detail": "Rate limit exceeded. Maximum 20 requests per minute for free tier."}
{"detail": "Monthly limit exceeded. Maximum 1000 requests per month for free tier."}

402 Out of Credits

{"detail": "Out of credits. Required: 2, remaining: 0. Top up at https://anpr.software/dashboard/billing — $0.005 per credit, credits never expire — or turn on auto top-up so this does not happen again."}

400 Bad Request

{"detail": "Invalid image"}

المعلمات المخصصة (params)

يمكنك إرفاق بيانات وصفية مخصصة بأي طلب كشف. تُخزَّن مع نتيجة الكشف وتُمرَّر كما هي إلى نقطة نهاية الـ webhook الخاصة بك. هذا مفيد لتمرير معرّفاتك الخاصة مثل المواقع ومعرّفات المسارات وأرقام البوابات أو أي سياق يحتاجه نظامك لمعالجة الـ webhook.

كيفية إرسال المعلمات

عند استدعاء ‎/v1/detect‎ أو ‎/v1/read‎، أدرج حقل نموذج params في جسم POST متعدد الأجزاء يحتوي على كائن JSON مشفر، إلى جانب رفع الملف.

cURL

curl -X POST "https://api.anpr.software/v1/detect" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -F "[email protected]" \
  -F 'params={"location":"gate-1","lane":"entry","site":"warehouse-a"}'

JavaScript (fetch)

const form = new FormData();
form.append("file", imageFile);
form.append("params", JSON.stringify({ location: "gate-1", lane: "entry" }));

await fetch("/v1/detect", {
  method: "POST",
  headers: { Authorization: `Bearer ${token}` },
  body: form,
});

Python (requests)

import json, requests

resp = requests.post(
    "https://api.anpr.software/v1/detect",
    headers={"Authorization": f"Bearer {token}"},
    files={"file": open("photo.jpg", "rb")},
    data={"params": json.dumps({"location": "gate-1", "lane": "entry"})},
)

ما يستقبله الـ webhook الخاص بك

عند تقديم المعلمات، تتضمنها حمولة الـ webhook في المستوى الأعلى:

{
  "event": "plate_detected",
  "timestamp": "2026-02-01T11:30:00.123456",
  "data": {
    "success": true,
    "plates_found": 1,
    "plates": [ ... ],
    "cost": 0.005,
    "credits": 1,
    "timestamp": "2026-02-01T11:30:00"
  },
  "params": {
    "location": "gate-1",
    "lane": "entry"
  }
}

عند عدم إرسال معلمات، يكون حقل params غائباً ببساطة من الحمولة (وليس null). التكاملات الحالية لا تتأثر.

القواعد

  • يجب أن تكون params كائن JSON صالح (وليس مصفوفة أو نص أو رقم)
  • يمكن أن تكون القيم أي نوع JSON صالح (نص، رقم، منطقي، كائن متداخل، مصفوفة، null)
  • لا يوجد حد حجم صارم، لكن اجعلها معقولة (بضعة كيلوبايت كحد أقصى)
  • تُخزَّن المعلمات مع نتيجة الكشف وتُمرَّر إلى الـ webhooks الخاصة بك

حالات استخدام شائعة

  • camera_id — تحديد مكان التقاط الصورة (ملاحظة: camera_id هو أيضًا باراميتر استعلام مخصص يسجّل حركات المواقف)
  • building_id / location_id — تحديد الموقع الفعلي
  • gate_id — تحديد بوابة الدخول/الخروج في أنظمة المواقف
  • session_id — الربط مع تتبع الجلسات الخاص بك
  • أي أزواج مفتاح-قيمة مخصصة يحتاجها نظامك

كم تكلّف كل استدعاء

عدّادان بالسعر نفسه، $0.005 لكل منهما: رصيد واحد لكل لوحة تتم معالجتها، ورصيد واحد لكل مركبة يتم تحليلها — يُحتسب مرة واحدة لكل مركبة مهما كان عدد المصنّفات الخمسة التي عملت.

الصورة التي لا تعطي أياً منهما تكلّف رصيداً واحداً على أي حال: النماذج عملت. ولا يُحتسب شيء على طلب يُرفض قبل الاستدلال (402 أو 403 أو 429).

الاستدعاءالأرصدة
POST /v1/detectرصيدان لسيارة واحدة بلوحة واحدة — واحد للوحة وواحد للمركبة. كل لوحة إضافية أو مركبة موصوفة إضافية تضيف رصيداً.
POST /v1/detect?plate_only=trueرصيد واحد للوحة واحدة. مصنّفات السيارة لا تعمل، فلا توجد مركبة تُحتسب.
POST /v1/detect?all_cars=trueرصيد لكل لوحة، ورصيد لكل مركبة موصوفة. المركبة المعدودة الصغيرة جداً (described: false) لا تكلّف شيئاً.
POST /v1/readرصيد واحد — لوحة واحدة بلا مركبة. اللوحة المقصوصة لا تحوي سيارة.
POST /v1/bodyرصيد واحد — مركبة واحدة بلا لوحة.
POST /v1/carرصيد واحد — مركبة واحدة بلا لوحة. ويبقى رصيداً واحداً مهما تركت من المصنّفات الخمسة يعمل: الوحدة هي المركبة لا النموذج.
POST /v1/framesالإرسال مجاني. العامل يحتسب كل إطار يعالجه وفق العدّادين أعلاه؛ والإطار المستبدَل لا يُعالَج ولا يُحتسب.

كل استجابة تحمل credits و cost. وتكون cost صفراً عندما تدفع حصتك الشهرية المجانية ثمن الاستدعاء.

حدود الطلبات

تُطبَّق حدود الطلبات لكل مفتاح API وتعتمد على باقة اشتراكك. عند تجاوز الحد يعيد الـ API الرمز 429 مع ترويسة Retry-After.

الخطةحد الطلباتالأرصدة المضمّنة
Free20 طلب/دقيقة100 رصيد كل شهر
Starter60 طلب/دقيقة3,000 رصيد/شهر
Business100 طلب/دقيقة10,000 رصيد/شهر
Growth200 طلب/دقيقة30,000 رصيد/شهر
Scale400 طلب/دقيقة60,000 رصيد/شهر