API التوثيق
كل ما تحتاجه لدمج التعرف على لوحات المركبات في تطبيقك.
محدَّث دائمًا: مرجع OpenAPI التفاعلي متاح على api.anpr.software/docs
البدء السريع
ابدأ مع واجهة برمجة تطبيقات ANPR.software في أقل من 5 دقائق. اتبع هذه الخطوات لإجراء أول استدعاء API.
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
/health/v1/detect/v1/detect/{country}/v1/car/v1/body/v1/frames/v1/frames/{job_id}/v1/read/v1/usage/v1/plate-logoGET /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
}
]
}POST /v1/plate-logo - استبدال اللوحة بالشعار
يستبدل لوحة السيارة المكتشفة في الصورة بشعارك المرفوع ويعيد الصورة المعدّلة.
جرّب أداة استبدال اللوحة بالشعار المجانيةحقول النموذج (multipart/form-data)
file | مطلوب. صورة السيارة (المركبة كاملة)، بصيغة JPEG أو PNG. |
logo | مطلوب. صورة الشعار. صيغة PNG بخلفية شفافة تعطي أنظف نتيجة. |
معلمة الاستعلام
opacity | تتحكّم في مقدار تغطية اللوحة الأصلية، من 0 إلى 1 (الافتراضي 0.95). استخدم 1 لأقوى تغطية. القيم الأقل تُبقي اللوحة الأصلية ظاهرة. |
الطلب
curl -X POST "https://api.anpr.software/v1/plate-logo?opacity=0.95" \
-H "Authorization: Bearer YOUR_API_KEY" \
-F "[email protected]" \
-F "[email protected]" \
--output result.jpgاستجابة النجاح (200 OK)
جسم الاستجابة هو الصورة المعدّلة كبيانات ثنائية image/jpeg - وليس JSON. تُعاد بيانات الكشف الوصفية في ترويسات الاستجابة:
Content-Type: image/jpeg
X-Plate-Bbox: 302,802,899,970
X-Plate-Skew-Deg: 5.27
X-Plate-Quad-Method: bbox+ocr-angle
X-Plate-Detection-Confidence: 0.8
X-Response-Time-Ms: 471ملاحظة: لقراءة ترويسات X-* من جافاسكربت المتصفح، يجب أن تكون الواجهة مُهيّأة لإتاحتها عبر CORS. أما جسم الصورة نفسه فهو قابل للقراءة دائماً عبر النطاقات.
معالجة الأخطاء
عند حدوث خطأ، يُرجع الـ 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.
| الخطة | حد الطلبات | الأرصدة المضمّنة |
|---|---|---|
| Free | 20 طلب/دقيقة | 100 رصيد كل شهر |
| Starter | 60 طلب/دقيقة | 3,000 رصيد/شهر |
| Business | 100 طلب/دقيقة | 10,000 رصيد/شهر |
| Growth | 200 طلب/دقيقة | 30,000 رصيد/شهر |
| Scale | 400 طلب/دقيقة | 60,000 رصيد/شهر |