توثيق ربط الـ API

استقبل أحداث الحضور والانصراف والإجازات في نظامك الخارجي فور حدوثها.

رجوع
نظرة سريعة

API Key: لسحب البيانات من نجمة الرواد (Pull) — يُستخدم في رأس Authorization: Bearer nr_...

Webhook: لدفع الأحداث من نجمة الرواد لنظامك (Push) — POST بصيغة JSON إلى الرابط الذي تحدده

• كل الطلبات موقّعة بـ HMAC-SHA256 للتحقق من مصدرها

Webhooks
ستستقبل POST request عند وقوع أي حدث اشتركت فيه.

Headers

Content-Type: application/json
X-Najmat-Event: attendance.check_in
X-Najmat-Signature: <hmac_sha256_hex_of_body>

Body (مثال حدث حضور)

{
  "event": "attendance.check_in",
  "timestamp": "2026-07-19T08:15:32.000Z",
  "data": {
    "employee_id": "EMP-001",
    "employee_name": "محمد أحمد",
    "user_id": "uuid...",
    "check_in_time": "2026-07-19T08:15:32.000Z",
    "location": { "lat": 24.71, "lng": 46.68 },
    "is_late": false,
    "late_minutes": 0
  }
}

الأحداث المتاحة

attendance.check_in
attendance.check_out
attendance.break_start
attendance.break_end
attendance.absent
leave.requested
leave.approved
leave.rejected
employee.created
employee.updated

التحقق من التوقيع (Node.js)

import { createHmac, timingSafeEqual } from 'crypto';

app.post('/webhook', (req, res) => {
  const signature = req.headers['x-najmat-signature'];
  const body = JSON.stringify(req.body);
  const expected = createHmac('sha256', process.env.NAJMAT_WEBHOOK_SECRET)
    .update(body).digest('hex');

  const a = Buffer.from(signature);
  const b = Buffer.from(expected);
  if (a.length !== b.length || !timingSafeEqual(a, b)) {
    return res.status(401).send('Invalid signature');
  }

  // معالجة الحدث
  console.log('Event:', req.body.event, req.body.data);
  res.send('ok');
});

التحقق من التوقيع (PHP)

$signature = $_SERVER['HTTP_X_NAJMAT_SIGNATURE'];
$body = file_get_contents('php://input');
$expected = hash_hmac('sha256', $body, getenv('NAJMAT_WEBHOOK_SECRET'));
if (!hash_equals($expected, $signature)) {
  http_response_code(401); exit;
}
$payload = json_decode($body, true);

ممارسات موصى بها

  • ارجع HTTP 2xx خلال 10 ثوانٍ — أي شيء آخر يُعتبر فشلاً
  • عالج الحدث في queue خلفية بدل معالجة مباشرة
  • خزّن event.id لتفادي المعالجة المكررة (idempotency)
  • لا تعتمد على ترتيب الأحداث — استخدم timestamp
API Keys
سحب البيانات مباشرة — REST endpoints للقراءة فقط.

أنشئ مفتاحاً من لوحة الإدارة → إدارة API Keys (يظهر المفتاح مرة واحدة عند الإنشاء)، ثم أرسله في كل طلب:

Authorization: Bearer nr_YOUR_KEY
# أو
x-api-key: nr_YOUR_KEY

Base URL

https://najmat-alrwoad.lovable.app/api/public/v1

جميع الطلبات مُعزَلة تلقائياً لشركتك حسب المفتاح — لا تحتاج تمرير company_id.

GET /employees

قائمة الموظفين. Query: limit (اختياري، حتى 1000).

curl https://najmat-alrwoad.lovable.app/api/public/v1/employees \
  -H "Authorization: Bearer nr_YOUR_KEY"

GET /attendance

سجلات الحضور. Query: from, to (ISO)، user_id، limit (حتى 5000).

curl "https://najmat-alrwoad.lovable.app/api/public/v1/attendance?from=2026-07-01&to=2026-07-31" \
  -H "Authorization: Bearer nr_YOUR_KEY"

GET /leaves

الإجازات. Query: status (approved/pending/rejected)، from, to.

curl "https://najmat-alrwoad.lovable.app/api/public/v1/leaves?status=approved" \
  -H "Authorization: Bearer nr_YOUR_KEY"

GET /summary

ملخّص شهري جاهز للنشر في الحسابات: أيام الحضور، إجمالي دقائق التأخير، أيام الإجازات — لكل موظف. Query: year, month.

curl "https://najmat-alrwoad.lovable.app/api/public/v1/summary?year=2026&month=7" \
  -H "Authorization: Bearer nr_YOUR_KEY"

أكواد الاستجابة

  • 200 نجاح
  • 401 مفتاح ناقص/غير صالح/منتهي/مسحوب
  • 500 خطأ داخلي

توصيات أمنية

  • لا تضع المفتاح في كود العميل (frontend) — استخدمه من الخادم فقط
  • أنشئ مفتاحاً منفصلاً لكل نظام تكامل (ERP، Payroll، BI…)
  • اسحب أي مفتاح فور الشك في تسريبه من صفحة الإدارة
  • حدّد expires_at للمفاتيح المؤقتة