واجهة API للتعرف الضوئي على عداد المياه
واجهة API للتعرف الضوئي على عداد المياه. توثّق هذه الصفحة واجهة HTTP API العامة التي توفرها الواجهة الخلفية للموقع لعمليات التكامل الخارجية.
ابدأ برفع صورة حقيقية
سجل أولا، وارفع صورة عداد المياه الخاصة بك في مساحة العمل، ثم أنشئ مفتاح API عندما تكون جاهزا للتكامل.
ملخص
- استخدم الواجهة الخلفية لموقع الويب لجميع عمليات التكامل الخارجية.
- لا تتصل بـ waterMeterAi مباشرةً من برامج الجهات الخارجية.
- يشارك API المفتوح نفس المستخدمين والحصة وذاكرة التخزين المؤقت والمهام وقواعد التدقيق مثل بوابة الويب.
- يمكن للواجهة الخلفية استهداف خدمات AI لاحقة مختلفة من خلال تكوين النشر.
- تشتمل استجابات المهام الآن على كائن result_summary عام حتى تتمكن الخدمات المختلفة من عرض أنواع نتائج مختلفة.
المصادقة
- قم بتسجيل الدخول إلى موقع الويب وقم بإنشاء مفتاح API في صفحة المفاتيح API.
- يظهر المفتاح API الكامل مرة واحدة فقط عند إنشائه.
- أرسل المفتاح في رأس Authorization مع كل طلب.
Authorization: Bearer wm_xxxxxxxxxxxxxxxxx
API Key Permissions and Limits
- Each API key can have independent scopes, an IPv4/IPv6/CIDR allowlist, a total requests-per-minute limit, and a task submissions-per-minute limit.
- A valid key without the required scope or outside its source IP allowlist returns 403.
- Every valid-key request consumes the total request limit, including requests rejected by scope, IP, or submission policy.
- Batch requests consume one total request unit and one submission unit per uploaded file.
- Rate-limited responses return 429 with Retry-After and both X-RateLimit-* and X-SubmissionLimit-* headers.
- Task creation also has a per-key concurrency limit and returns X-ConcurrencyLimit-* headers; a concurrency rejection uses 429.
- For batch concurrency, only files that pass image validation reserve slots, and success headers report the actual active slots after task binding.
Retry-After: 30 X-RateLimit-Limit: 60 X-RateLimit-Remaining: 59 X-RateLimit-Reset: 1785902400 X-SubmissionLimit-Limit: 10 X-SubmissionLimit-Remaining: 9 X-ConcurrencyLimit-Limit: 3 X-ConcurrencyLimit-Active: 1 X-ConcurrencyLimit-Remaining: 2
قواعد التحميل
- الحد الأقصى لحجم الملف: 20MB لكل صورة.
- التنسيقات المدعومة: JPEG, PNG, WEBP.
- تتحقق الواجهة الخلفية من محتوى الملف الفعلي، وليس فقط امتداد الملف.
تنفيذ حجم التحميل
- تقبل التحميلات المجمعة ما يصل إلى 8 صور بشكل افتراضي، بحد أقصى 20 ميجابايت لكل صورة وحد أقصى لمحتوى الملف يبلغ 20 ميجابايت.
- الملف أو الدفعة التي تتجاوز الحد الخاص بها تُرجع 413 قبل التحقق من صحة الصورة أو إنشاء المهمة؛ لم يتم إنشاء دفعة جزئية.
- تفرض الواجهة الخلفية عدد البايتات المستلمة فعليًا حتى في حالة فقدان Content-Length أو استخدام النقل المقسم.
حالات المهمة
- queued: تم قبوله وفي انتظار معالجة AI.
- running: قيد المعالجة حاليًا، أو تم تسليمه بالفعل إلى المرسل وما زال يجري الاستقصاء عن النتيجة النهائية.
- batch_waiting_ai: كل عنصر في الدفعة ينتظر عودة خدمة AI عبر الإنترنت.
- batch_running: تم تسليم الدفعة بالفعل إلى المرسل ولا تزال قيد المعالجة.
- done: تم الانتهاء بنجاح.
- failed: فشلت المعالجة.
- waiting_ai: في قائمة الانتظار حتى تعود خدمة AI إلى الاتصال، ثم تُستأنف تلقائيًا.
مصادر النتائج
- fresh: تم إنشاؤه بواسطة تشغيل AI جديد.
- cached_exact: يطابق ذاكرة التخزين المؤقت للإصدار AI الحالي.
- cached_stale: AI غير متصل، تم إرجاع أحدث نتيجة مخزنة مؤقتًا.
- pending: لا توجد نتيجة نهائية بعد.
- failed: فشلت المهمة.
- عندما لا تكون المهمة done بعد، تحقق من error_message لمعرفة آخر سبب لإعادة المحاولة أو الانتظار.
الحصة والفوترة
- استخدم `GET /api/open/quota` قبل إرسال أحمال عمل كبيرة إذا كان التكامل يحتاج إلى تجنب فشل الحصة.
- عمليات AI الجديدة فقط ذات `fresh` تستهلك الحصة.
- نتائج `cached_exact` و `cached_stale` و `pending` و `failed` لا تستهلك الحصة.
- الحسابات المجانية تستخدم الحصة اليومية أولا. الحسابات المدفوعة تستخدم حزم الحصة الدورية النشطة، ثم الحصة المؤقتة أو الثابتة حسب سياسة الخلفية.
- عند نفاد الحصة، يعيد إرسال المهمة `429` ورسالة خطأ بدلا من إنشاء مهمة جديدة.
التخزين المؤقت وحداثة النتيجة
- تخزن الخلفية النتائج الناجحة حسب بصمة الصورة وإصدار AI، بما في ذلك namespace للخدمة اللاحقة.
- `cached_exact` يعني أن الصورة نفسها لديها نتيجة ناجحة لإصدار AI الحالي، لذلك لم تكن هناك حاجة إلى تشغيل AI جديد.
- `cached_stale` يعني أن خدمة AI غير متصلة وأن الخلفية أعادت أحدث نتيجة تاريخية متاحة.
- عندما تكون `is_latest_ai_version` تساوي false، خزّن النتيجة كبيانات تاريخية قابلة للاستخدام لكنها تحتاج إلى مراجعة.
- لا تفترض أن كل مهمة `done` استهلكت الحصة؛ تحقق من `result_source`.
Task completion webhooks
- Send signed task completion events to your HTTPS endpoint with automatic retries.
- This API key is inactive. Existing records remain available, but new, enabled, test, and secret-rotation operations are blocked.
X-WaterMeter-Webhook-Id: whev_new_event X-WaterMeter-Webhook-Replay-Of: whev_original_event replay_of_event_id: whev_original_event blocked endpoint management: HTTP 409 canceled delivery status: canceled
GET/api/open/quota
/api/open/quotaقراءة الحصة الحالية والاستخدام المتبقي.
طلب مثال
curl -X GET "https://watermeterai.com/api/open/quota" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
مثال الاستجابة
{
"ok": true,
"email": "[email protected]",
"quota": {
"account_type": "free",
"daily_limit": 20,
"used": 3,
"remaining": 17,
"day_tag": "2026-06-01",
"is_unlimited": false,
"monthly_remaining": 0,
"monthly_bonus_remaining": 0,
"fixed_remaining": 0,
"nearest_expire_at": null,
"quota_summary_text": "Free daily quota: 3/20 used today. Remaining: 17."
}
}GET/api/open/ai-status
/api/open/ai-statusاقرأ حالة الخدمة العامة لتقديم المهمة والنتائج الاحتياطية المخزنة مؤقتًا.
طلب مثال
curl -X GET "https://watermeterai.com/api/open/ai-status" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
مثال الاستجابة
{
"ok": true,
"is_online": true,
"busy": false,
"active_jobs": 0,
"public_status": "online",
"public_status_label": "online",
"public_status_reason": "ready",
"accepts_new_tasks": true,
"can_return_cached_result": true,
"queue_state": "idle",
"queue_count": 0,
"current_ai_version": "water_v2:wm-ai-v2-2026-06-01",
"last_checked_at": "2026-06-01T06:15:30Z"
}POST/api/open/tasks
/api/open/tasksقم بتحميل صورة واحدة وإنشاء مهمة واحدة.
طلب مثال
curl -X POST "https://watermeterai.com/api/open/tasks" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx" \ -F "file=@D:\data\meter_001.jpg"
مثال الاستجابة
{
"ok": true,
"task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
"status": "queued",
"result_source": "pending",
"visibility": "private",
"ai_online": true,
"is_latest_ai_version": false,
"final_reading": "-",
"result_summary": {
"resultKind": "unknown",
"primaryLabel": "Result",
"primaryValue": "-",
"secondaryLabel": "Detail",
"secondaryValue": "-",
"summaryText": "No result is available yet."
},
"error_message": "",
"created_at": "2026-06-01T06:16:10Z"
}GET/api/open/tasks/{task_id}
/api/open/tasks/{task_id}قراءة حالة مهمة واحدة والقراءة النهائية.
طلب مثال
curl -X GET "https://watermeterai.com/api/open/tasks/task_a" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
مثال الاستجابة
{
"ok": true,
"task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
"status": "done",
"result_source": "fresh",
"ai_online": true,
"is_latest_ai_version": true,
"final_reading": "123.45",
"meter_type": "pointer",
"success": "yes",
"result_summary": {
"resultKind": "water_meter",
"primaryLabel": "Final Reading",
"primaryValue": "123.45",
"secondaryLabel": "Meter Type",
"secondaryValue": "pointer",
"summaryText": "Water meter recognition finished."
},
"error_message": "",
"created_at": "2026-06-01T06:16:10Z"
}GET/api/open/tasks
/api/open/tasksاقرأ المهام الأخيرة المملوكة للمستخدم الرئيسي الحالي API.
طلب مثال
curl -X GET "https://watermeterai.com/api/open/tasks?limit=20" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
مثال الاستجابة
{
"ok": true,
"items": [
{
"task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
"status": "done",
"result_source": "cached_exact",
"final_reading": "123.45",
"meter_type": "pointer",
"success": "yes",
"result_summary": {},
"ai_online": true,
"is_latest_ai_version": true,
"created_at": "2026-06-01T06:16:10Z",
"error_message": ""
}
]
}POST/api/open/batches
/api/open/batchesتحميل صور متعددة في طلب واحد.
طلب مثال
curl -X POST "https://watermeterai.com/api/open/batches" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx" \ -F "files=@D:\data\meter_001.jpg" \ -F "files=@D:\data\meter_002.jpg"
مثال الاستجابة
{
"ok": true,
"batch_id": "5a14f4e5f6d34fdabce00e62c0dd0001",
"status": "batch_running",
"total_count": 2,
"done_count": 0,
"failed_count": 0,
"pending_count": 2,
"items": [
{
"index": 0,
"file_name": "meter_001.jpg",
"task_id": "task_a",
"status": "queued",
"result_source": "pending",
"final_reading": "-",
"failure_kind": "",
"error_message": ""
},
{
"index": 1,
"file_name": "meter_002.jpg",
"task_id": "task_b",
"status": "queued",
"result_source": "pending",
"final_reading": "-",
"failure_kind": "",
"error_message": ""
}
]
}GET/api/open/batches/{batch_id}
/api/open/batches/{batch_id}اقرأ تقدم الدفعة وحالات المهام لكل ملف.
طلب مثال
curl -X GET "https://watermeterai.com/api/open/batches/5a14f4e5f6d34fdabce00e62c0dd0001" \ -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
مثال الاستجابة
{
"ok": true,
"batch_id": "5a14f4e5f6d34fdabce00e62c0dd0001",
"status": "batch_done",
"total_count": 2,
"done_count": 2,
"failed_count": 0,
"pending_count": 0,
"items": [
{
"index": 0,
"file_name": "meter_001.jpg",
"task_id": "task_a",
"status": "done",
"result_source": "fresh",
"final_reading": "123.45",
"failure_kind": "",
"error_message": ""
},
{
"index": 1,
"file_name": "meter_002.jpg",
"task_id": "task_b",
"status": "done",
"result_source": "cached_exact",
"final_reading": "456.78",
"failure_kind": "",
"error_message": ""
}
]
}التدفق الموصى به
- تحقق من `GET /api/open/ai-status` قبل إرسال أحمال العمل الكبيرة.
- قم بتخزين `task_id` أو `batch_id` في نظامك الخاص مباشرة بعد الإرسال.
- تعامل مع `queued`، و`running`، و`waiting_ai`، و`batch_waiting_ai`، و`batch_running` كحالات غير نهائية وواصل التحقق الدوري من الحالة.
- استخدم الطلبات المجمعة عندما يكون مسار الشبكة إلى الواجهة الخلفية بطيئًا وتدعم الخدمة المنشورة الوضع الدفعي.
- تتدفق الطلبات المجمعة حاليًا عبر `webBackend -> dispatchCenter -> waterMeterAi`.
- `batch_waiting_ai` يعني أن كل عنصر لا يزال في انتظار خدمة AI ولم يبدأ التشغيل فعليًا بعد.
- عندما تكون الخدمة المنشورة `CAD`، استخدم `POST /api/open/tasks` حاليًا واعتبر التحميل المجمع غير متاح.
ملاحظات الخطأ
- 400: طلب غير صالح، أو أن الخدمة المنشورة لا تدعم التحميل المجمع.
- 401: مفتاح API مفقود أو غير صالح أو منتهي الصلاحية أو معطل.
- 403: the user account is not active, the key lacks the required scope, or the source IP is outside the key allowlist.
- 404: لم يتم العثور على المهمة أو الدفعة، أو أنها غير مملوكة للمستخدم الحالي.
- 413: الملف كبير جدًا.
- 415: نوع صورة غير مدعوم أو محتوى صورة غير صالح.
- 429: quota exhausted or the API key request, submission, or concurrency limit was exceeded.
تحميل 400 دفعة غير متاح
{
"detail": "batch upload is not supported for business: cax"
}401 مفتاح API مفقود أو غير صالح
{
"ok": false,
"error": "unauthorized",
"message": "Missing or invalid API key."
}413 ملف كبير جدًا
{
"ok": false,
"error": "file_too_large",
"message": "Maximum file size is 20MB."
}استنفدت الحصة 429
{
"ok": false,
"error": "quota_exhausted",
"message": "Quota exhausted.",
"quota": {
"remaining": 0,
"quota_summary_text": "Free daily quota: 20/20 used today. Remaining: 0."
}
}هل أنت جاهز لاختبار سير العمل؟
استخدم مساحة العمل على الويب للصورة الأولى، ثم انتقل إلى مفاتيح API عندما يناسبك شكل النتيجة.