التوثيق
تتعرّف واجهة VisionPlate البرمجية (REST) على لوحات المركبات العراقية في صور المركبات. للاطلاع على المخطط الكامل والتفاعلي، راجع مرجع الواجهة البرمجية (بالإنجليزية).
البدء
أنشئ حسابًا واشترِ رصيدًا ثم أنشئ مفتاح API من حسابك. يحتاج كل طلب إلى المفتاح في الترويسة X-Api-Key. تبدو المفاتيح بهذا الشكل vp_live_… وتُعرض مرة واحدة فقط عند إنشائها، لذا احفظ مفتاحك بأمان واستخدمه من جهة الخادم فقط وليس في شيفرة المتصفح. أرسل الصورة بصيغة multipart/form-data.
curl -X POST https://your-domain/api/v1/recognize \
-H "X-Api-Key: vp_live_your_key" \
-F "image=@car.jpg"التعرّف على لوحة
يستقبل POST /api/v1/recognize حقل ملف واحدًا باسم image (JPEG أو PNG أو WebP أو BMP). أضف ?includeCrop=true لتحصل أيضًا على صورة اللوحة المقتطعة بصيغة PNG مرمّزة بـ base64. إذا لم يُعثر على لوحة، ينجح الطلب مع "detected": false ويستهلك رصيدًا واحدًا.
{
"success": true,
"data": {
"id": "0199a0c4-6f1e-7c2b-9d3a-5b8f1e2d4c6a",
"detected": true,
"plateNumber": "12 A 34567",
"province": "baghdad",
"provinceCode": 1,
"vehicleType": "private",
"vehicleCode": 1,
"plateType": "New",
"boundingBox": { "x": 412, "y": 530, "width": 220, "height": 64 },
"fileName": "car.jpg",
"processingMs": 84.3,
"createdAtUtc": "2026-09-30T10:15:00Z",
"croppedPlatePng": null,
"timings": {
"uploadMs": 412.5, "validationMs": 1.2, "queueMs": 0.1,
"localizationMs": 61.8, "recognitionMs": 22.4, "serverMs": 503.9
}
},
"error": null,
"meta": null
}حقول الاستجابة
| الحقل | الوصف |
|---|---|
| id | المعرّف الفريد لهذه العملية في سجلك. |
| detected | تكون false إذا لم يُعثر على لوحة في الصورة. |
| plateNumber | نص اللوحة المقروء. |
| province / provinceCode | اسم المحافظة ورمزها الرقمي، عند إمكانية قراءتهما. |
| vehicleType / vehicleCode | فئة المركبة (مثل: خصوصي، عمومي، حمل) ورمزها الرقمي. |
| plateType | تصميم اللوحة: Kurdistan (old) أو Nineties أو Germany أو New. |
| boundingBox | موقع اللوحة في الصورة الأصلية بالبكسل. |
| processingMs | زمن معالجة هذه الصورة. |
| croppedPlatePng | صورة اللوحة بصيغة PNG مرمّزة بـ base64، تُرجع فقط مع includeCrop=true. |
| timings | توزيع الوقت بالملّي ثانية: الرفع، والفحص، والانتظار، وتحديد اللوحة وقراءتها، والإجمالي على الخادم. يُرسل أيضًا في الترويسة القياسية Server-Timing. |
التعرّف المجمّع
يقبل POST /api/v1/recognize/batch حتى 10 ملفات، كلٌّ منها في حقل باسم images. لكل عنصر في الاستجابة مؤشر success خاص به. الملفات التي لا تجتاز التحقق تُرجع خطأً لذلك العنصر فقط ولا تستهلك رصيدًا.
curl -X POST https://your-domain/api/v1/recognize/batch \
-H "X-Api-Key: vp_live_your_key" \
-F "images=@car1.jpg" \
-F "images=@car2.jpg"السجل
يُرجع GET /api/v1/recognitions عمليات التعرّف السابقة لمفتاحك، الأحدث أولًا. يمكنك التصفية بـ plate (تطابق جزئي)، وfrom وto (بتوقيت UTC وبصيغة ISO-8601)، والتنقل بين الصفحات بـ page وpageSize (بحد أقصى 100). تُرجع معلومات الصفحات في meta. ولجلب عنصر واحد استخدم GET /api/v1/recognitions/{id}.
curl "https://your-domain/api/v1/recognitions?page=1&pageSize=20&plate=12345" \
-H "X-Api-Key: vp_live_your_key"الاستهلاك والحدود
تُدفع الطلبات من الرصيد المسبق الدفع لحسابك: كل صورة يتم التعرّف عليها تستهلك رصيدًا واحدًا، وتتشارك جميع مفاتيحك الرصيد نفسه. اشترِ باقات الرصيد من حسابك. يعرض GET /api/v1/usage رصيدك واستهلاك هذا المفتاح خلال الشهر، وتتضمن استجابات التعرّف الترويسة X-Credits-Remaining. ولكل مفتاح أيضًا حدٌّ لعدد الطلبات في الدقيقة (429 rate_limited مع الترويسة Retry-After). وعند نفاد الرصيد تحصل على 402 insufficient_credits.
الأخطاء
تستخدم جميع الأخطاء البنية نفسها. اعتمد على الحقل code في شيفرتك؛ أما الرسالة فهي موجّهة للقارئ وقد تتغير.
{
"success": false,
"data": null,
"error": { "code": "insufficient_credits", "message": "Not enough credits for this request..." },
"meta": null
}| الحالة | الرمز | المعنى |
|---|---|---|
| 400 | missing_image | لم يُرسل ملف في الحقل المتوقع. |
| 400 | invalid_image | الملف ليس صورة صالحة. |
| 400 | unsupported_format | استخدم JPEG أو PNG أو WebP أو BMP. |
| 400 | image_too_large | حجم الملف أو عدد البكسلات يتجاوز الحد. |
| 400 | batch_too_large | عدد الملفات يتجاوز حد الدفعة. |
| 401 | unauthorized | مفتاح API مفقود أو غير معروف أو ملغى. |
| 404 | not_found | المورد غير موجود أو لا يخصّك. |
| 429 | rate_limited | تم تجاوز الحد في الدقيقة؛ راجع Retry-After. |
| 402 | insufficient_credits | نفد الرصيد؛ اشترِ باقة. |
| 500 | server_error | خطأ غير متوقع. يمكن إعادة المحاولة بأمان. |
أمثلة برمجية
using var http = new HttpClient { BaseAddress = new Uri("https://your-domain/") };
http.DefaultRequestHeaders.Add("X-Api-Key", "vp_live_your_key");
using var form = new MultipartFormDataContent();
var file = new ByteArrayContent(await File.ReadAllBytesAsync("car.jpg"));
file.Headers.ContentType = new("image/jpeg");
form.Add(file, "image", "car.jpg");
var response = await http.PostAsync("api/v1/recognize", form);
var json = await response.Content.ReadAsStringAsync();
Console.WriteLine(json);const form = new FormData();
form.append("image", fileInput.files[0]);
const res = await fetch("https://your-domain/api/v1/recognize", {
method: "POST",
headers: { "X-Api-Key": "vp_live_your_key" },
body: form,
});
const { success, data, error } = await res.json();
console.log(success ? data.plateNumber : error.message);