العناوين
| العنوان | ما يُرجعه |
|---|---|
GET /api/v1/jobs | الوظائف المفتوحة، الأحدث أولاً (والأنسب أولاً عند البحث)، صفحة في كل مرة. |
GET /api/v1/jobs/{id} | وظيفة مفتوحة واحدة بوصفها ومتطلباتها كاملة. |
GET /api/v1/meta | كل المدن والمجالات والخيارات: الرموز التي تقبلها خيارات التصفية، بأسمائها بالعربية والإنجليزية. |
GET /api/v1/openapi.json | وصف الواجهة بصيغة OpenAPI 3، لأدوات مثل Postman ومولّدات الكود ومساعدي الذكاء الاصطناعي. |
خيارات التصفية في /jobs
يتضمن كل إعلان apply: { on, url }: تكون قيمة on هي jobsly مع رابط ينتهي بـ ?apply=1، أو external مع رابط التقديم لدى المؤسسة. لا تُرسل طلبات التوظيف عبر الواجهة. المسارات غير المعروفة تعيد 404 بصيغة JSON.
كلها اختيارية وتعمل معاً. تُقبل الرموز وأسماؤها العربية والإنجليزية من /api/v1/meta دون تمييز حالة الأحرف. تُرفض قيم التصفية غير الصالحة بالرمز 400 invalid_parameter مع اسم الخيار ورموزه المسموحة. وقيمة company التي لا تصلح عنواناً لصفحة، أو قيمة client التي لا تصلح مفتاحاً لعميل، تُرفض (400)، حتى لا يؤدي خطأ في الكتابة إلى إرجاع جميع الوظائف.
| الاسم | مثال | المعنى |
|---|---|---|
q | محاسب في طرابلس فوق 2000 | كلمات البحث بالعربية أو الإنجليزية. ويستخرج البحث من العبارة أيضاً المدينة ونمط العمل والحد الأدنى للراتب. |
city | benghazi | رمز المدينة. |
category | it_software | رمز المجال. |
jobType | full_time | رمز نوع الدوام. |
workMode | remote | في المقر أو عن بُعد أو هجين. |
experienceLevel | junior | رمز مستوى الخبرة. |
minSalary | 2000 | أقل راتب شهري بالدينار الليبي (رقم صحيح)؛ تُستثنى الوظائف التي لا تذكر راتباً والرواتب بعملات أو فترات أخرى. وما فوق 100,000 يُقرأ 100,000. |
company | al-marjan | وظائف هذه المؤسسة فقط (عنوان صفحتها في jobs.ly): التي تنشرها، والتي تنشرها لها وكالة توظيف باسمها. حروف إنجليزية صغيرة وأرقام وشرطات. |
client | the-client-key | الوظائف التي تنشرها وكالة توظيف لعميل واحد باسمه فقط، بمفتاح العميل (32 رمزاً من 0-9 وa-f) كما يرد في كود نافذة وظائفه. والمفتاح الذي يكون عميله مخفياً أو في الأرشيف أو انتقلت صفحته إلى مؤسسته لا يُرجع أي وظيفة، وتكون قيمة meta.client فيه null. |
partner | lbc | قائمة شريك: وظائف المؤسسات التي لها عضوية سارية لديه (اليوم lbc فقط، مجلس أصحاب الأعمال الليبيين؛ أعضاؤه فقط، لا المؤسسات المسجّلة لديه دون عضوية). ويكون في كل وظيفة عندها الحقل partnerMember. ولا تُدرج الوظائف دون اسم المؤسسة أبداً. وأي قيمة أخرى ردها 400 invalid_parameter. |
member | 3f2c… (UUID) | مع partner: وظائف عضو واحد فقط، بمعرّف الشريك نفسه لتلك المؤسسة. والقيمة التي ليست UUID، أو member دون partner، ردها 400 invalid_parameter. |
apply | jobsly | jobsly: الوظائف التي يُقدَّم عليها في jobs.ly فقط (قيمة apply.on فيها "jobsly")، ولا تُدرج الوظائف التي ترسل المتقدمين إلى موقع آخر أو بريد آخر. ويُجمع مع كل خيارات التصفية الأخرى (partner وmember وcompany وclient…). وأي قيمة أخرى ردها 400 invalid_parameter. |
page | 2 | رقم الصفحة، بدءاً من 1. |
perPage | 20 | عدد الوظائف في الصفحة، من 1 إلى 50 (والافتراضي 20). |
الوظيفة
{
"data": [
{
"id": "8ce12ab3-5f0e-4c1d-9b7a-2d4e6f8a1b3c",
"url": { "ar": "https://jobs.ly/jobs/8ce12ab3-…-accountant", "en": "https://jobs.ly/en/jobs/8ce12ab3-…-accountant" },
"title": { "ar": "محاسب", "en": "Accountant" },
"company": {
"name": { "ar": "شركة المرجان", "en": "Al Marjan" },
"url": { "ar": "https://jobs.ly/companies/al-marjan", "en": "https://jobs.ly/en/companies/al-marjan" },
"verified": true,
"logo": "https://jobs.ly/api/files/…",
"confidential": false
},
"hiringFor": null,
"city": { "code": "tripoli", "ar": "طرابلس", "en": "Tripoli" },
"countryCode": "LY",
"locations": [{ "countryCode": "LY", "cityCode": "tripoli", "locality": null, "localityAr": null }],
"category": { "code": "accounting_finance", "ar": "المحاسبة والمالية", "en": "Accounting & Finance" },
"occupation": { "isco08": "2411", "ar": "المحاسبون", "en": "Accountants" },
"jobType": { "code": "full_time", "ar": "دوام كامل", "en": "Full-time" },
"workMode": { "code": "onsite", "ar": "في المقر", "en": "On-site" },
"experienceLevel": { "code": "mid", "ar": "خبرة متوسطة", "en": "Mid-level" },
"salary": {
"min": 2500, "max": 3200, "currency": "LYD", "period": "month",
"formatted": { "ar": "2,500 – 3,200 د.ل", "en": "2,500 – 3,200 LYD" }
},
"postedAt": "2026-09-23T09:22:44.000Z",
"expiresAt": "2026-11-07T09:22:44.000Z"
}
],
"meta": { "total": 14, "page": 1, "pageCount": 3, "perPage": 5 }
}| الحقل | المعنى |
|---|---|
id | معرّف الوظيفة (UUID). |
url.ar وurl.en | صفحة الوظيفة. اربط كل وظيفة بها ليتبع الزائر طريقة التقديم الموضّحة، سواء على jobs.ly أو بطريقة خارجية. |
title | المسمى الوظيفي بالعربية والإنجليزية. |
company | name وurl (صفحتها) وverified (موثّقة من jobs.ly) وlogo (أو null) وconfidential. الوظيفة دون اسم المؤسسة (مؤسسة موثّقة فضّلت إخفاء اسمها) فيها confidential: true والاسم «مؤسسة غير مُعْلَنَة»، وurl وlogo قيمتهما null. تظهر في الخلاصات العامة دون اسم المؤسسة، ولا تظهر عند استخدام خيار التصفية company ولا في خلاصات مؤسسة بعينها أو أداة وظائفها. |
hiringFor | عندما تنشر وكالة توظيف لعميل: { "name": …, "nameEn": … } (nameEn الاسم بالإنجليزية، أو الاسم نفسه إن لم يوجد)، أو { "confidential": true }. وإلا null. |
city وcategory وjobType وworkMode وexperienceLevel | كلٌّ منها بالشكل { code, ar, en }. تكون jobType قيمتها null إذا لم يذكر الإعلان الأصلي نوع الدوام لوظيفة منقولة من موقع آخر. |
occupation | مهنة الوظيفة حسب التصنيف الدولي للمهن: { isco08, ar, en } (مجموعة ISCO-08 من 4 أرقام واسمها، مثل 2411 المحاسبون). تكون null إذا لم يكن مسمى الوظيفة من المسميات القياسية لدينا. |
salary | { min, max, currency, period, formatted: { ar, en } }. المبالغ قد تكون عشرية أو null، والعملة رمز ISO 4217. الفترة: hour أو day أو week أو month أو year أو project. الحقل كله null إذا لم يُذكر الراتب. |
countryCode وlocations | دولة موقع العمل الرئيسي برمز ISO 3166-1 alpha-2، والمواقع الفعلية بالشكل { countryCode, cityCode, locality, localityAr }. للعمل عن بُعد تكون countryCode قيمتها null وlocations قائمة فارغة؛ ولا تحدد هذه الحقول الجنسية أو أهلية العمل عن بُعد. |
postedAt وexpiresAt | تواريخ ISO 8601 بتوقيت UTC. postedAt هو تاريخ نشر الوظيفة أول مرة: للوظيفة المنقولة من موقع آخر، تاريخ الإعلان الأصلي، أو null إذا كان غير معروف. |
partnerMember | مع خيار التصفية partner فقط: معرّف الشريك نفسه (UUID) للمؤسسة التي نشرت الوظيفة. |
تُستثنى الوظائف المستوردة التي لا تسمح حقوقها بإعادة التوزيع من API والخلاصات والأداة المضمّنة، حتى لو كانت منشورة على jobs.ly.
ويمكن للمؤسسة أيضاً أن تختار عدم مشاركة وظائفها مع مواقع الوظائف الأخرى (من إعداداتها في jobs.ly). عندها تُستثنى وظائفها من الخلاصتين ومن هذه الواجهة، ومنها /jobs/{id}، إلا أن GET /api/v1/jobs يُرجعها عند طلب وظائف تلك المؤسسة وحدها (company أو client أو member لدى شريك)، وبهذا تعرضها أداة الوظائف على موقعها. لا تستخدم خيارَي التصفية هذين، ولا صفحات الموقع، لجمع وظائف اختارت المؤسسة عدم مشاركتها. ولا يغيّر هذا الاختيار صفحات jobs.ly وبحثه، ولا خرائط الموقع، ولا بيانات الوظيفة التي تقرؤها محركات البحث في صفحة كل وظيفة.
وظيفة واحدة
curl "https://jobs.ly/api/v1/jobs/8ce12ab3-5f0e-4c1d-9b7a-2d4e6f8a1b3c"
{
"data": {
"id": "8ce12ab3-…",
"…": "the same fields as in the list, plus:",
"description": { "ar": "…", "en": "…" },
"requirements": { "ar": ["…"], "en": ["…"] }
}
}الخيارات
curl "https://jobs.ly/api/v1/meta"
{
"cities": [{ "code": "tripoli", "ar": "طرابلس", "en": "Tripoli" }, …],
"categories": [{ "code": "it_software", "ar": "…", "en": "…" }, …],
"jobTypes": […], "workModes": […], "experienceLevels": […],
"currency": "LYD"
}الصفحات
meta.total عدد الوظائف الموجودة، وmeta.pageCount عدد الصفحات. اطلب page=2 ثم page=3… حتى تصل page إلى pageCount. وإذا طلبت صفحة بعد آخر صفحة (أو بعد الصفحة 500)، تكون قائمة data فارغة، وتبقى قيمة meta.page رقم الصفحة التي طلبتها.
مع client يعطي meta.client اسم العميل name وصفحته url، كلٌّ منهما بالشكل { ar, en }، أو null إذا لم يدل المفتاح على عميل له وظائف ظاهرة للعموم.
الأخطاء والحدود
400 { "error": "invalid_parameter", "message": "company must be an organization's page address (slug): …" }
400 { "error": "invalid_parameter", "message": "client must be a client's widget key: …" }
404 { "error": "not_found", "message": "This job doesn't exist or is closed." }
429 { "error": "too_many_requests", "message": "Up to 120 requests per minute." }
Retry-After: 60- تتبع جميع الأخطاء التنسيق نفسه:
errorرمز ثابت تستخدمه البرامج، وmessageشرح بالإنجليزية للمستخدم. - حتى 120 طلباً في الدقيقة من العنوان نفسه، وبعدها يكون الرد 429، ويبيّن
Retry-Afterعدد الثواني قبل المحاولة. - قد تُخزَّن الردود مؤقتاً لمدة دقيقة (
Cache-Control: max-age=60)، لذا لا يؤدي تكرار الطلب خلال هذه المدة إلى إرجاع وظائف أحدث. - يمكن لأي موقع طلب الواجهة من المتصفح (
Access-Control-Allow-Origin: *).
أمثلة أخرى
const res = await fetch("https://jobs.ly/api/v1/jobs?city=tripoli&perPage=10");
const { data, meta } = await res.json();
for (const job of data) {
console.log(job.title.en, "·", job.company.name.en, "·", job.url.en);
}
console.log(`${meta.total} open jobs`);import requests
r = requests.get("https://jobs.ly/api/v1/jobs", params={"category": "it_software", "perPage": 20})
r.raise_for_status()
for job in r.json()["data"]:
print(job["title"]["ar"], job["url"]["ar"])