البدء مع واجهة API
من الصفر إلى أول طلب ناجح: العنوان، ومفتاح API أو رمز دخول، والترويسات، ورقم شركتك، وأمثلة جاهزة للنسخ بـ curl وJavaScript وPython.
في مهنارو واجهة REST API لما تفعله على الشاشات، بنفس الصلاحيات والتحققات. هذا الدليل يأخذك من لا شيء إلى طلب ناجح في نحو خمس دقائق. كل مثال هنا شُغِّل فعلاً على خادم مهنارو، والردود المعروضة هي الردود الحقيقية (من الشركة التجريبية، رقمها 16).
العنوان
كل الطلبات تبدأ بـ:
https://api.mihnaro.com/api/v1
الطلبات والردود بصيغة JSON. طلبات الشركة بالشكل /api/v1/app/companies/{company}/… حيث {company} رقم شركتك (انظر «اعرف رقم شركتك» أدناه). القائمة الكاملة في مرجع الـ API.
احصل على مفتاح أو رمز دخول
هناك طريقتان، وكلتاهما تعمل باسم شخص حقيقي في شركتك، ولا تستطيع إلا ما يستطيعه.
مفتاح API للشركة (للتكاملات)
الأنسب لخادم يتصل بمهنارو وحده: نظام ERP، أو أداة تقارير، أو سكربت.
- ادخل إلى مهنارو بحساب لديه صلاحية إدارة مفاتيح API والـ webhooks (مالكو الشركة لديهم كل الصلاحيات).
- افتح الشركة ← مفاتيح API والـ Webhooks من القائمة الجانبية (وأيضاً من تفضيلات النظام ← إعداد التكامل).
- في تبويب مفاتيح API اختر مفتاح API جديد واملأ:
- الاسم: ما الذي سيستخدمه، مثل "مزامنة ERP".
- يعمل باسم: الشخص الذي يعمل المفتاح باسمه. المفتاح لا يستطيع إلا ما يستطيعه هذا الشخص، وضمن نطاقه (الفروع والموظفون).
- الصلاحيات: قراءة (GET)، كتابة (POST)، تحديث (PUT وPATCH)، حذف (DELETE). اختر ما تحتاجه فقط.
- عناوين IP المسموحة: افصل بينها بفواصل، أو اتركها فارغة للسماح بأي عنوان.
- تنتهي في: اتركه فارغاً بلا انتهاء.
- اختر إنشاء المفتاح. المفتاح يبدأ بـ
mhk_ويظهر مرة واحدة: انسخه الآن واحفظه في مكان آمن. مهنارو يحفظ بصمته فقط، فلا أحد يستطيع إظهاره لك مرة أخرى.
المفتاح يعمل فقط على مسارات شركته (/api/v1/app/companies/{رقم شركته}/…)، ولا يعمل على /api/v1/app/me ولا على MCP؛ استخدم رمز دخول لهما. تستطيع تعديل المفتاح أو إلغاءه من نفس الشاشة، والملغى يتوقف فوراً.
رمز دخول المستخدم (للتطبيقات وMCP)
الأنسب لتطبيق يدخل فيه كل شخص بحسابه، ولمساعدي الذكاء الاصطناعي (MCP). الرمز يعمل باسم من دخل:
curl -X POST "https://api.mihnaro.com/api/v1/app/token" \
-H "Accept: application/json" \
-H "Content-Type: application/json" \
-d '{"email":"[email protected]","password":"your password","device_name":"My integration"}'
الرد (201)، والرمز مختصر هنا:
{
"data": {
"token": "9|iZv9PuRH…",
"user": {
"id": 330, "name": "Docs QA", "email": "[email protected]",
"must_change_password": false, "password_expired": false,
"two_factor": {"available": true, "mode": "optional", "enabled": false, "required": false, "recovery_codes_left": 0},
"preferences": {"locale": "en", "theme": "system"}
},
"companies": [
{"id": 16, "name": {"en": "Demo Company", "ar": "الشركة التجريبية"}, "can_access": true, "reason": null, "two_factor_setup_required": false}
]
}
}
emailيقبل اسم المستخدم أيضاً. وdevice_nameأي اسم تعرفه لاحقاً.- مع التحقق بخطوتين، يرد الطلب الأول بـ
422و"code": "two_factor_required"؛ أرسل نفس الطلب مرة ثانية مع"code": "123456"من تطبيق المصادقة (أو رمز استرداد). - الدخول بنفس قواعد التطبيق: كلمات المرور الخاطئة تقفل الحساب مدة، والشركة الموقوفة أو الترخيص المنتهي يمنعان الدخول.
- الخروج (إلغاء هذا الرمز):
DELETE /api/v1/app/token. - هذا الطلب يسمح بـ 10 محاولات في الدقيقة.
الترويسات
أرسل في كل طلب:
Authorization: Bearer <your mhk_ key or token>
Accept: application/json
Content-Type: application/jsonعندما ترسل بيانات JSON، أوmultipart/form-dataعند رفع ملف.Accept-Language: arللرسائل والأخطاء بالعربية (الإنجليزية افتراضياً).X-Branch: <رقم الفرع>أوX-Branch: allللعمل في فرع آخر في هذا الطلب فقط (انظر مفاهيم الـ API).
اعرف رقم شركتك
- مع رمز دخول:
GET /api/v1/app/meيعرض شركاتك وأرقامها (قائمةcompaniesأعلاه). - مع مفتاح API: الرسالة التي تعرض المفتاح الجديد تقول أيضاً أين ترسله: «أرسله كـ "Authorization: Bearer <key>" إلى /api/v1/app/companies/16/…». هذا الرقم هو رقم شركتك. المفتاح يعمل على هذه الشركة فقط، وأي رقم آخر يرد بـ
403.
ثم تحقق مما تعطيك الشركة:
curl "https://api.mihnaro.com/api/v1/app/companies/16" \
-H "Authorization: Bearer $MIHNARO_TOKEN" \
-H "Accept: application/json"
بداية الرد (لكل فرع إعدادات أكثر مما يظهر هنا):
{
"data": {
"id": 16,
"name": {"en": "Demo Company", "ar": "الشركة التجريبية"},
"modules": ["hrm", "fsm"],
"license": {"status": "active", "ends_on": "2027-10-31", "access_ends_on": "2027-11-07", "warning": false},
"branches": [
{"id": 76, "name": {"en": "Baghdad HQ", "ar": "المقر - بغداد"}, "code": "BGD", "country": "IQ", "currency": "IQD", "timezone": "Asia/Baghdad", "is_main": true, "is_active": true},
{"id": 77, "name": {"en": "Basra", "ar": "البصرة"}, "code": "BSR", "country": "IQ", "currency": "IQD", "timezone": "Asia/Baghdad", "is_main": false, "is_active": true}
]
}
}
أول طلب: قائمة الموظفين
ضع المفتاح (أو الرمز) ورقم الشركة في متغيرات بيئة حتى تلصق الأمثلة كما هي:
export MIHNARO_TOKEN="mhk_your_key_here"
export MIHNARO_COMPANY=16
الشخص الذي يعمل المفتاح باسمه يحتاج صلاحية employees.view لهذا الطلب.
curl
curl "https://api.mihnaro.com/api/v1/app/companies/$MIHNARO_COMPANY/employees?per_page=2" \
-H "Authorization: Bearer $MIHNARO_TOKEN" \
-H "Accept: application/json"
JavaScript (fetch)
Node 18 أو أحدث، أو متصفح على خادمك أنت. لا تضع مفتاحاً أبداً في صفحة ويب يفتحها أي أحد.
const BASE = process.env.MIHNARO_BASE ?? 'https://api.mihnaro.com/api/v1';
const TOKEN = process.env.MIHNARO_TOKEN; // mhk_… API key or app token
const COMPANY = process.env.MIHNARO_COMPANY; // your company's ID
const response = await fetch(`${BASE}/app/companies/${COMPANY}/employees?per_page=2`, {
headers: { Authorization: `Bearer ${TOKEN}`, Accept: 'application/json' },
});
const body = await response.json();
if (!response.ok) {
throw new Error(`${response.status} ${body.code ?? ''}: ${body.message}`);
}
console.log(body.meta);
for (const employee of body.data) {
console.log(employee.employee_number, employee.name.en, employee.department_name);
}
Python (requests)
import os
import requests
BASE = os.environ.get("MIHNARO_BASE", "https://api.mihnaro.com/api/v1")
TOKEN = os.environ["MIHNARO_TOKEN"] # mhk_… API key or app token
COMPANY = os.environ["MIHNARO_COMPANY"] # your company's ID
response = requests.get(
f"{BASE}/app/companies/{COMPANY}/employees",
params={"per_page": 2},
headers={"Authorization": f"Bearer {TOKEN}", "Accept": "application/json"},
timeout=30,
)
body = response.json()
if not response.ok:
raise SystemExit(f"{response.status_code} {body.get('code', '')}: {body['message']}")
print(body["meta"])
for employee in body["data"]:
print(employee["employee_number"], employee["name"]["en"], employee["department_name"])
السكربتان يطبعان نفس الشيء:
{'current_page': 1, 'last_page': 4, 'total': 8, 'current_employees': 10, 'max_employees': 50}
EMP-0001 Ali Hassan Human Resources
EMP-0002 Sara Qasim Human Resources
الرد
200، مع سجل كل موظف (نحو 70 حقلاً؛ بعضها هنا):
{
"data": [
{
"id": 6211,
"employee_number": "EMP-0001",
"name": {"en": "Ali Hassan", "ar": "علي حسن"},
"email": "[email protected]",
"status": "active",
"branch_id": 76,
"branch_name": "Baghdad HQ",
"department_name": "Human Resources",
"job_title": {"en": "HR Director", "ar": "مدير الموارد البشرية"},
"hire_date": "2026-03-01"
},
{
"id": 6212,
"employee_number": "EMP-0002",
"name": {"en": "Sara Qasim", "ar": "سارة قاسم"},
"email": "[email protected]",
"status": "active",
"branch_id": 76,
"branch_name": "Baghdad HQ",
"department_name": "Human Resources",
"hire_date": "2025-10-01"
}
],
"meta": {"current_page": 1, "last_page": 4, "total": 8, "current_employees": 10, "max_employees": 50}
}
لاحظ أن total هو 8 بينما في الشركة 10 موظفين حاليين: القائمة تعرض الفرع الذي تعمل فيه (المقر - بغداد هنا). أضف -H "X-Branch: all" فيصير total هو 10. مفاهيم الـ API تشرح السبب.
هذه القائمة تقبل أيضاً search (الرقم أو الاسم أو البريد)، وstatus (current افتراضياً، أو active أو suspended أو terminated أو archived أو all)، وemployee_number، وbranch_id، وsalary_status (running أو stopped)، وpage وper_page (حتى 100).
عندما يحدث خطأ
الأخطاء JSON فيها message، وغالباً code. أكثرها في اليوم الأول، كما يرد بها مهنارو:
| ترى | السبب | ماذا تفعل |
|---|---|---|
401 {"message":"Unauthenticated. |
لا ترويسة Authorization، أو رمز خاطئ أو ملغى |
تحقق من الترويسة والرمز |
401 "code":"invalid_api_key" |
المفتاح خاطئ أو منتهٍ أو ملغى | أنشئ مفتاحاً جديداً |
403 "This API key works only on its own company's endpoints. |
رقم {company} في العنوان ليس شركة المفتاح |
استخدم رقم شركة المفتاح |
403 "This API key may not make this request. |
المفتاح لا يملك هذه الطريقة (مثل مفتاح قراءة يرسل POST) أو عنوان IP غير مسموح | عدّل صلاحيات المفتاح أو عناوينه |
403 "code":"branch_forbidden" |
X-Branch يذكر فرعاً لا تستطيع العمل فيه |
استخدم أحد فروعك، أو احذفه |
422 مع errors |
البيانات غير صحيحة | صحّح الحقول المذكورة في errors |
كل ما يخص الأخطاء والصفحات والتواريخ والحدود في مفاهيم الـ API.
الخطوات التالية
- مفاهيم الـ API: الصلاحيات والفروع، والصفحات والتصفية، والتواريخ والتوقيت، والأخطاء، والحدود والإصدارات.
- مرجع الـ API حسب القسم: أهم طلبات كل قسم، والمرجع الكامل المولَّد من الكود.
- الـ Webhooks: ليصلك خبر أي تغيير لحظة حدوثه.
- استخدام مهنارو من مساعد ذكاء اصطناعي (MCP).
- نزّل ملف OpenAPI واستورده في Postman أو Insomnia.
آخر تحديث: