المصادقة
احصل على مفتاح APIيحمل كل استدعاء رمز Bearer في الترويسة Authorization. تقرأ Sofia الصلاحيات الكامنة وراءه في كل استدعاء: شخص أُزيل من مساحة عمل، أو تفويض أُلغي، يتوقف رمزه عند الطلب التالي.
| الطريقة | الاستخدام | الرمز |
|---|---|---|
| مفتاح شخصي | أتمتة حسابك الخاص، والسكربتات، والوكلاء | sofia_pk_live_…، صالح حتى تاريخ انتهائه |
| OAuth، رمز التفويض + PKCE | منتج يتصرف نيابةً عن مستخدميه، على مساحة العمل التي يختارها كل منهم | sofia_live_at_…، ساعة واحدة، قابل للتجديد |
| OAuth، بيانات اعتماد العميل | خادمك الذي يؤتمت مساحة عمل تملكها | sofia_live_at_…، ساعة واحدة |
المفاتيح الشخصية
أنشئ مفتاحًا في الإعدادات › API › الوصول الشخصي. يتصرف نيابةً عنك في كل مساحات عملك: المنشأة التي تسمّيها تحدد مساحة العمل، ودورك هناك يحدد ما يستطيع المفتاح فعله.
curl https://api.sofia-post.com/api/v1/establishments \
-H "Authorization: Bearer sofia_pk_live_…"OAuth: رمز التفويض مع PKCE
سجّل عميلًا في الإعدادات › API › عملاء التطبيقات: اسمه وشعاره وسياسة الخصوصية والصلاحيات التي يجوز له طلبها وعناوين إعادة التوجيه عبر https. للعميل السري (confidential) سرّ خاص، أما العميل العام (public) (تطبيق جوال، إضافة متصفح) فلا سرّ له ويعتمد على PKCE وحده.
وجّه الشخص إلى نقطة نهاية التفويض مع تحدّي PKCE (إلزامي بصيغة S256) وstate تحتفظ به في جلسته:
import { createHash, randomBytes } from 'node:crypto';
const verifier = randomBytes(32).toString('base64url');
const challenge = createHash('sha256').update(verifier).digest('base64url');
const state = randomBytes(16).toString('base64url');
const url = new URL('https://api.sofia-post.com/api/v1/oauth/authorize');
url.search = new URLSearchParams({
response_type: 'code',
client_id: process.env.SOFIA_CLIENT_ID,
redirect_uri: 'https://app.example.com/oauth/callback',
scope: 'establishments:read posts:read posts:write offline_access',
state,
code_challenge: challenge,
code_challenge_method: 'S256',
}).toString();يسجّل الشخص الدخول إلى Sofia، ويرى اسمك وشعارك وصلاحياتك، ويختار مساحة عمل ويوافق. ثم تعيده Sofia إلى عنوان إعادة التوجيه الخاص بك مع code وstate والمُصدِر iss. تحقق من الاثنين، ثم بدّل الرمز:
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=authorization_code \
-d code=$CODE \
-d redirect_uri=https://app.example.com/oauth/callback \
-d code_verifier=$VERIFIER{
"access_token": "sofia_live_at_…",
"token_type": "Bearer",
"expires_in": 3600,
"scope": "establishments:read posts:read posts:write offline_access",
"refresh_token": "sofia_live_rt_…"
}- الرمز صالح 5 دقائق ولمرة واحدة. إذا أُعيد استخدامه رُفض وتوقفت الرموز التي منحها.
- يدوم رمز الوصول ساعة واحدة ويتصرف على مساحة العمل التي اختارها الشخص فقط.
- لا يُعاد
refresh_tokenإلا إذا طلبتoffline_access. وهو للاستخدام مرة واحدة: احتفظ بالجديد في كل مرة. إعادة استخدام رمز تحديث مستخدَم تُلغي التفويض كله.
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=refresh_token \
-d refresh_token=$REFRESH_TOKENOAuth: بيانات اعتماد العميل
يستطيع العميل السري أيضًا أن يتصرف على مساحة عمل يملكها صاحبه، دون شخص في الحلقة. عندما يملك العميل عدة مساحات عمل، سمِّ إحداها بـ workspace_id.
curl -X POST https://api.sofia-post.com/api/v1/oauth/token \
-u "$SOFIA_CLIENT_ID:$SOFIA_CLIENT_SECRET" \
-d grant_type=client_credentials \
-d workspace_id=$WORKSPACE_IDالصلاحيات (scopes)
| النطاق | يتيح |
|---|---|
establishments:read | عرض المنشآت |
accounts:read, accounts:write | قراءة الشبكات المتصلة؛ إنشاء روابط الربط |
media:read, media:write | قراءة مكتبة الوسائط؛ رفع الوسائط واستيرادها |
posts:read, posts:write | عرض المنشورات ومتابعتها؛ نشرها وتعديلها وحذفها |
insights:read | قراءة الإحصاءات |
webhooks:read, webhooks:write | عرض webhooks؛ تسجيلها واختبارها وحذفها |
offline_access | OAuth فقط: استلام رمز تحديث |
الاستدعاء الذي يفتقر إلى النطاق المطلوب يُجاب بـ 403 insufficient_scope. تسرد بيانات الخادم الوصفية (RFC 8414) كل نقطة نهاية وكل نطاق:
https://api.sofia-post.com/.well-known/oauth-authorization-server/api/v1/oauth