المصادقة
إصدار API 2026-10-affable-towhee
يحمل كل استدعاء لواجهة Lingara البرمجية رمز وصول. ويحصل الخادم على رمز الوصول باستبدال معرّف عميل OAuth وسرّه عند نقطة نهاية الرموز: وهو منح بيانات اعتماد العميل (client credentials) في OAuth 2.0، لخادم يعمل باسمه هو. أنشئ العملاء من صفحة عمليات التكامل في تطبيق Lingara على الويب، على العنوان app.getlingara.com/admin.
جلسة أم عميل
تسجّل تطبيقات Lingara دخولك بجلسة، تحمل كل النطاقات وتستهلك من حصة خطتك. أما العميل فأضيق: تختار النطاقات المسموح بها له عند إنشائه، ولا يحمل كل رمز وصول يحصل عليه إلا النطاقات التي يطلبها.
ثلاث قيم
يبدأ معرّف العميل بـ lgr_cid_ ويسمّي العميل عند نقطة نهاية الرموز. وهو ليس سرًّا.
يبدأ سرّ العميل بـ lgr_cs_ ولا يُرسل إلا إلى نقطة نهاية الرموز. يُعرض مرة واحدة فقط، عند إنشائه: انسخه حينها، لأن Lingara لا تخزّن منه إلا قيمة مجزّأة (hash).
يبدأ رمز الوصول بـ lgr_at_ ويدوم ساعة واحدة. مكانه الترويسة Authorization: Bearer في الاستدعاءات الواقعة تحت /v1/، ولا مكان آخر. وهو القيمة الوحيدة التي تنتمي إلى تلك الترويسة: سرّ العميل المرسَل فيها يُرفض بالحالة 401.
احصل على رمز وصول
أرسل نموذجًا بالطريقة POST إلى نقطة نهاية الرموز مع grant_type=client_credentials. أرسل معرّف العميل وسرّه إما بمصادقة HTTP Basic وإما في حقلي النموذج client_id وclient_secret، لا بالطريقتين معًا. scope قائمة مفصولة بمسافات من النطاقات المسموح بها للعميل؛ احذفه لتحصل على كل النطاقات المسموح بها للعميل. يطلب الأمر أدناه usage:read وحده، وهو النطاق الذي يحتاجه مثال GET /v1/usage في الأسفل.
curl -X POST "https://api.getlingara.com/oauth/token" \
-u "$LINGARA_CLIENT_ID:$LINGARA_CLIENT_SECRET" \
-d "grant_type=client_credentials" \
--data-urlencode "scope=usage:read"يحمل الرد access_token وtoken_type (Bearer) وexpires_in (3600، بالثواني) وscope، أي النطاقات التي يحملها الرمز فعلًا. ويجيب الاستبدال الفاشل بصيغة أخطاء OAuth، {error, error_description}، لا بغلاف {code, error} الخاص بـ /v1/. السرّ الخاطئ أو الملغى، أو العميل المحذوف، يُرفض بالحالة 401 وinvalid_client. والنطاق الذي لا يجوز للعميل طلبه يرفض الاستبدال كله بالحالة 400 وinvalid_scope؛ ولا يُضيَّق بصمت أبدًا.
العمل نيابةً عن مستخدم آخر على Lingara
يستخدم التطبيق الذي يعمل نيابةً عن مستخدم آخر على Lingara منح رمز التفويض. وجّه متصفح المستخدم إلى عنوان URL الخاص بالتفويض مع response_type=code وclient_id وredirect_uri يطابق تمامًا عنوانًا سجّلته وscope وstate وcode_challenge بطريقة S256. يرى المستخدم صفحة الموافقة في Lingara ثم يعود إلى redirect_uri الخاص بك ومعه code وstate وiss. تحقّق من أن state هو نفسه الذي أرسلته وأن iss هو https://api.getlingara.com قبل أن تستخدم رمز التفويض.
PKCE إلزامي
يستخدم كل عميل PKCE، وبالطريقة S256 فقط. أنشئ code_verifier عشوائيًا، وأرسل تجزئة SHA-256 الخاصة به، مرمّزة بـ base64url، بوصفها code_challenge مع code_challenge_method=S256، واحتفظ بالمُحقِّق للاستبدال. ويُرفض الطلب الذي لا يحدّد طريقة، أو الذي يحدّد plain، بـ invalid_request.
استبدل رمز التفويض
في غضون 60 ثانية، أرسل بالطريقة POST إلى نقطة نهاية الرموز مع grant_type=authorization_code وcode وredirect_uri نفسه وcode_verifier، مع المصادقة بوصفك العميل؛ ويرسل العميل العام client_id وحده. ويضيف الرد refresh_token يبدأ بـ lgr_rt_. يبدأ رمز التفويض بـ lgr_ac_ ويعمل مرة واحدة: يُرفض الاستخدام الثاني بـ invalid_grant وينهي الرموز التي أصدرها الاستبدال الأول.
التجديد
عندما تنتهي صلاحية رمز الوصول، أرسل بالطريقة POST إلى نقطة نهاية الرموز مع grant_type=refresh_token وrefresh_token، مع المصادقة بوصفك العميل مجددًا. يعيد كل تجديد رمز تحديث جديدًا: احتفظ بالأحدث فقط. نفّذ عمليات التجديد واحدة تلو الأخرى: يُعامَل رمز التحديث القديم المستخدَم بعد أكثر من 60 ثانية من استبداله على أنه مسروق، وينهي رموز ذلك التثبيت بـ invalid_grant. تنتهي صلاحية رمز التحديث الذي لم يُستخدَم مدة 30 يومًا. تحدّ نقطة نهاية الرموز من عدد الطلبات لكل عنوان، لذا لا تجدّد إلا عندما تنفد صلاحية الرمز.
التطبيقات الأصلية عملاء عامّون
لا يستطيع تطبيق سطح المكتب أو الهاتف المحمول أو سطر الأوامر الحفاظ على سرّ، لذا فهو عميل عام: لا سرّ له، ويرسل client_id وحده إلى نقطة نهاية الرموز، ويسجّل إعادة توجيه استرجاعية مثل http://127.0.0.1/callback (بأي منفذ) أو مخططًا للاستخدام الخاص مثل com.example.app:/callback. يرى المستخدم صفحة الموافقة في كل مرة. ولا يمكن لصفحة ويب أن تكون عميلًا: فلا نقطة نهاية الرموز ولا /v1/ تجيب على أي طلب تمهيدي عابر للأصول (preflight).
عندما يزيل المستخدم تطبيقك
يستطيع المستخدم إزالة تطبيقك في أي وقت من صفحة التطبيقات المتصلة، أو بإلغاء تثبيته إن كان قد ثبّته، فيفشل استدعاؤه التالي بالحالة 401. وعندما يسجّل المستخدم خروجه من تطبيقك، ألغِ رمز التحديث الخاص به عند نقطة نهاية الإلغاء، مما ينهي رموز ذلك التثبيت.
عندما تنتهي صلاحية الرمز
بعد ساعة، تجيب /v1/ بالحالة 401 مع الرمز unauthorized وخطأ يبدأ بـ invalid_token. استبدل من جديد عندما يتلقى استدعاء 401، أو قبيل نفاد expires_in، وأعد الاستدعاء مرة واحدة. وإذا فشل الاستبدال نفسه بـ invalid_client أو invalid_scope، فقد حُذف العميل أو أُلغي سرّه أو ضُيّقت نطاقاته: توقّف وأصلح ذلك في صفحة عمليات التكامل، لأن إعادة المحاولة لا يمكن أن تنجح. احتفظ بالرمز بين الاستدعاءات: تحدّ نقطة نهاية الرموز من عدد الاستبدالات لكل عميل ولكل عنوان، والبرنامج الذي يستبدل عند كل استدعاء يُرفض بالحالة 429 وrate_limited خلال الساعة (انتظر Retry-After). لا يتضمن هذا المنح رمز تحديث: يُستبدل السرّ من جديد.
لا تصل رموز الوصول إلا إلى مسارات API
لا يعمل رمز الوصول إلا على المسارات الواقعة تحت /v1/. وإذا أُرسل إلى أي مسار آخر في Lingara يُرفض بالحالة 401، ويبدأ المتن بـ api_token_not_accepted، نصًا عاديًا أو داخل الحقل error، ولا يكون أبدًا في غلاف {code, error} الذي تستخدمه مسارات /v1/. أرسل رمز الوصول في الترويسة Authorization، كما يلي.
curl "https://api.getlingara.com/v1/usage" \
-H "Authorization: Bearer $LINGARA_TOKEN"النطاقات
تحتاج كل عملية إلى نطاق واحد بالضبط، مذكور في صفحتها. يُرفض رمز الوصول الذي يفتقر إلى ذلك النطاق بالحالة 403 والرمز insufficient_scope. لاستدعاء العملية، اطلب نطاقها عند الاستبدال، إن كان مسموحًا به للعميل. يسرد الجدول أدناه كل نطاق والعمليات التي يسمح بها.
vocab:generate | إنشاء قوائم المفردات. | إنشاء قائمة مفردات |
lesson_plans:read | قراءة خطط دروسك وإعادة الاتصال بتقدّمها. | الحصول على خطة درسإعادة الاتصال بخطة درس |
lesson_plans:write | إنشاء خطط الدروس. | إنشاء خطة درس |
tutor:converse | إجراء محادثات مع المعلّم. يتطلب خطة مدفوعة. | إرسال دور إلى المعلّم |
usage:read | معرفة حصتك المتبقية، أو استخدام عميل `metered` هذا الشهر. | الحصول على حصتك المتبقية |
events:read | قراءة الأحداث المتعلقة بحسابك، وتسجيل نقاط النهاية التي تستقبلها. | عرض الأحداثبث الأحداث |
events:write | إرسال الأحداث من لعبتك أو تكاملك إلى Lingara. | إرسال حدث |
من يدفع ثمن الاستدعاء
يُفوتَر العميل بإحدى طريقتين تُختار عند إنشائه. يستهلك عميل allowance حصة مالكه، وهي الحصة نفسها التي تستهلكها تطبيقاتك، وتستهلكها رموز الوصول الخاصة به أيضًا؛ ويعرض GET /v1/usage ما تبقّى منها. أما عميل metered فلا يستهلك أي حصة: بل يُفوتَر لكل رصيد عبر اشتراك فوترة بحسب الاستهلاك تُعدّه في صفحة عمليات التكامل. وتُرفض استدعاءاته بالرمز 402 وspend_cap_reached عندما يبلغ العميل أو حسابك حدّ الإنفاق الشهري، وبالرمز 402 وmetered_billing_inactive ما دامت الفوترة بحسب الاستهلاك غير مفعّلة. تُحتسب خطة الدرس بـ 10 أرصدة، وجولة المحادثة مع المعلّم برصيد واحد، وتوليد المفردات بـ 3 أرصدة، لذا تتحوّل units التي يعرضها GET /v1/usage إلى أرصدة بهذه الأوزان. والاستدعاء الذي يجريه تطبيق نيابةً عن مستخدم آخر، برمز وصول مأخوذ من رمز تفويض، يستهلك دائمًا حصة ذلك المستخدم، أيًّا كان وضع العميل.
احتفظ بالأسرار والرموز على خادم
مكان سرّ العميل خادم تتحكّم فيه، لا صفحة ويب ولا إضافة متصفح ولا حزمة تطبيق، حيث يستطيع أي أحد قراءته. والتطبيق الأصلي عميل عام لا يحمل أي سرّ. ولا تجيب /v1/ ولا نقطة نهاية الرموز على أي طلب تمهيدي عابر للأصول (preflight)، لذا لا يستطيع متصفح على موقع آخر استدعاءهما على أي حال.
إدارة العملاء
في صفحة عمليات التكامل، على العنوان app.getlingara.com/admin، أنشئ العملاء وأعد تسميتهم واحذفهم، وغيّر ما يستطيع كل منهم فعله والإصدار المثبَّت عليه، وأنشئ أسراره وألغِها. حذف العميل يوقف فورًا كل رمز وصول يحمله، وينهي كل تفويض منحه إياه أي مستخدم. وإلغاء السرّ يوقف فورًا كل رمز وصول استُبدل به ذلك السرّ. وتضييق نطاقات العميل يسري فورًا أيضًا؛ أما توسيعها، أو تغيير إصداره، فيسري من الاستبدال التالي.
تدوير سرّ
يمكن للعميل أن يحتفظ بسرّين في آن واحد. للتدوير، أنشئ سرًّا جديدًا، وانشره، ثم ألغِ القديم حين يتوقف تاريخ «آخر استخدام» الخاص به في صفحة عمليات التكامل عن التغيّر. والعملية التي حصلت على السرّ الجديد لكنها لا تزال تحمل رمزًا من القديم تتلقى 401 مرة واحدة ثم تستبدل من جديد. لا يمكن إلغاء السرّ الوحيد للعميل: أنشئ بديله أولًا، أو احذف العميل.
إذا اختلفت ترجمةٌ عن المرجع الإنجليزي، فالمرجع الإنجليزي هو الصحيح.