المصادقة
تقريبًا كل الطلبات إلى AstroWay API يتم توثيقها عبر الهيدر X-Api-Key. الاستثناءات: 14 نقطة نهاية /v1/reference/* (signs, planets, houses, aspects, …) تعمل بشكل عام بدون مفتاح مع حد 30 طلبًا في الساعة لكل IP. إذا كان الخادم الخاص بك هو الذي يرسل الطلبات، أرسل الهيدر X-AstroWay-Site-URL وسيصبح الحد 300 طلبًا في الساعة للموقع: التفاصيل.
لكل نقاط النهاية الحسابية /v1/* (chart, synastry, transits, /reports, /tarot وغيرها) - فقط X-Api-Key. لعمليات المستخدم /v1/me/* (GET /me, DELETE /me/account) - Bearer JWT صادرة عبر /v1/auth/login. OAuth/جلسات الكوكيز غير مستخدمة في الـ API العام. قواميس المرجع /v1/reference/* - بدون مفتاح، مجانية (جداول lookup قانونية).
تنسيق المفتاح
Section titled “تنسيق المفتاح”aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_test_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRaw_live_: الإنتاج، يخصم الرصيد من الرصيد المتاحaw_test_: sandbox، الطلبات تُرجع ردًا ثابتًا (أو حسابًا حقيقيًا بسيطًا)، لا تخصم رصيدًا، مُعلمة في لوحة التحكم بشكل منفصل- بعد البادئة: 32 حرفًا base62، عشوائية تشفيرياً
- يُظهر المفتاح بصورته الصافية مرة واحدة فقط عند الإنشاء. بعد ذلك في لوحة التحكم - فقط الأربعة أحرف الأولى والأخيرة.
رأس الطلب
Section titled “رأس الطلب”POST /v1/chart HTTP/1.1Host: api.astroway.infoX-Api-Key: aw_live_aB3xY7pQ9rN2mK4jH8vC5tL6wZ1fD0eRContent-Type: application/jsonمجموعة Postman
Section titled “مجموعة Postman”إذا كان Postman أسهل لك من curl/SDK - هناك مجموعة جاهزة تحتوي على جميع نقاط النهاية 771، موزعة على 55 مجلدًا حسب وسوم OpenAPI، مع أمثلة طلبات مدمجة. تم إعداد المصادقة على مستوى المجموعة: تضع المفتاح في المتغير apiKey مرة واحدة، وتلتقط جميع الطلبات.
- المستندات المنشورة: documenter.getpostman.com/view/54689779/2sBXqNmy3n
- مساحة العمل العامة: postman.com/astroway-info/astroway-api
- تحميل JSON: astroway-api.json (≈ 5 MB) - استورد مباشرةً إلى Postman أو Insomnia
المجموعة تم إنشاؤها تلقائيًا من OpenAPI spec - يتم تحديثها مع كل نشر.
إنشاء وإدارة المفاتيح
Section titled “إنشاء وإدارة المفاتيح”من خلال لوحة التحكم:
- api.astroway.info/dashboard/keys
- يمكنك امتلاك ما يصل إلى 10 مفاتيح نشطة لكل حساب في نفس الوقت
- كل مفتاح له اسم، الحقل
name(مثالproduction-backend,ci-tests,local-dev)
من خلال الـ API (للتكامل ذاتي الخدمة):
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"name": "ci-tests", "mode": "test"}'// Equivalent via @astroway/sdk: aw.client.POST('/keys', { body: { name, mode } })const r = await fetch('https://api.astroway.info/v1/keys', { method: 'POST', headers: { 'X-Api-Key': process.env.ASTROWAY_MASTER_KEY!, 'Content-Type': 'application/json', }, body: JSON.stringify({ name: 'ci-tests', mode: 'test' }),});
const { data: created } = await r.json();console.log(created.api_key); // shown once - store it now# Equivalent via `astroway` (PyPI): aw.post('/keys', body={'name': ..., 'mode': ...})import os, requests
r = requests.post( 'https://api.astroway.info/v1/keys', headers={'X-Api-Key': os.environ['ASTROWAY_MASTER_KEY']}, json={'name': 'ci-tests', 'mode': 'test'},)created = r.json()['data']print(created['api_key']) # shown once - store it now<?phpuse GuzzleHttp\Client;
$aw = new Client(['base_uri' => 'https://api.astroway.info/v1/']);$r = $aw->post('keys', [ 'headers' => ['X-Api-Key' => getenv('ASTROWAY_MASTER_KEY')], 'json' => ['name' => 'ci-tests', 'mode' => 'test'],]);
$created = json_decode($r->getBody(), true)['data'];echo $created['api_key']; // shown once - store it nowالمفاتيح للمتصفح
Section titled “المفاتيح للمتصفح”المفتاح النموذجي server-only: إذا كان الطلب يحمل الهيدر Origin أو Referer، يتم إرجاع 403 ORIGIN_FORBIDDEN. هذا مقصود، وهو ما يلتقط المفتاح إذا تُرك عن طريق الخطأ في الواجهة الأمامية.
عندما يحتاج الودجت أو الصفحة إلى الاتصال بالـ API من المتصفح، يتم إنشاء المفتاح مباشرةً مع سياسة الأصل. الحقل origin_restriction في POST /v1/keys:
type | ما المسموح به | متى يُستخدم |
|---|---|---|
server-only (افتراضيًا) | فقط الطلبات بدون Origin و Referer | الخلفية، cron، CI |
public | فقط المضيفين المذكورين، والطلب مطلوب أن يحمل الأصل | ودجت أو صفحة على نطاقك، المفتاح في الكود المصدر |
allowlist | نفس ما هو في public | صيغة قديمة: لا تزال مقبولة، لكن في openapi.json لم تعد موجودة |
curl -X POST https://api.astroway.info/v1/keys \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "name": "site-widget", "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] }, "credits_cap_cycle": 20000, "allowed_endpoints": ["chart", "public/*"] }'قواعد المطابقة، تم اختبارها في الإنتاج:
- حتى 20 مضيفًا لكل مفتاح. البروتوكول (
https://) والمنفذ يتم تجاهلهما، ولا يهم حالة الأحرف. - يتم إزالة
www.من المضيف الوارد، لذاexample.comيغطي أيضًاwww.example.com. لا تحتاج لإضافة صيغة منفصلة بـwww.، فهي لا تغير شيئًا. *.example.comيغطي النطاقات الفرعية (app.example.com)، لكن ليسexample.comنفسه. النجم يُدرج كسطر منفصل، كما في المثال أعلاه.- المضيف غير الموجود في القائمة يحصل على
403 ORIGIN_NOT_ALLOWEDمع المضيف نفسه في حقلincoming_originلتوضيح أي سطر مفقود. - يُعامل
Refererعلى قدم المساواة معOrigin: المتصفح يرسلها عندما لا يكون هناكOrigin.
تعديل القائمة في مفتاح موجود بالفعل
Section titled “تعديل القائمة في مفتاح موجود بالفعل”PATCH /v1/keys/{id} يكتب القائمة من جديد دون تعديل المفتاح نفسه. صلاحية الوصول هي نفسها كما في POST /v1/keys أعلاه؛ في لوحة التحكم هذا هو خيار “تعديل الأصل” في قائمة المفتاح.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{ "origin_restriction": { "type": "public", "allowed_origins": ["example.com", "*.example.com"] } }'القائمة الجديدة سارية بدءًا من الطلب التالي: يتم مسح ذاكرة التخزين المؤقت للمفتاح أثناء الكتابة، لا حاجة للانتظار دقيقة. لا يتغير نص المفتاح نفسه، لذا لا تحتاج لإعادة إصدار الصفحة أو الخلفية. بعد POST /v1/keys/{id}/rotate تُحفظ القائمة، وتتوقف القيمة القديمة للمفتاح عن العمل فورًا.
فئة المفتاح لا يمكن تعديلها لأنها مُدمجة في المفتاح نفسه:
| محاولة | استجابة |
|---|---|
pk_ تحويل إلى server-only | 400: الفئة جزء من المفتاح، يجب إلغاءه وإنشاء مفتاح جديد |
aw_ إعطاء قائمة النطاقات | 400: مفتاح المتصفح هو فئة مختلفة، يتم إنشاؤه كـ public |
pk_ مع قائمة فارغة | 400: مفتاح بدون قائمة سيرفض أي طلب |
pk_ بدون ميزانية أو منطقة (null) | 400: مفتاح المتصفح دائمًا مقيد بكليهما، يمكن تعديلهما لكن لا يمكن إزالتهما |
ميزانية الائتمانات للمفتاح الفردي
Section titled “ميزانية الائتمانات للمفتاح الفردي”الأرصدة مشتركة على جميع الحساب، لذا يمكن لمفتاح واحد إنفاقها كلها. هذا مقبول للمفتاح الخلفي، لكن ليس للمفتاح الموجود في كود الصفحة: قائمة النطاقات تخبر من أين يمكن الاتصال، لكنها لا تخبر بكمية التكلفة.
credits_cap_cycle في نفس PATCH /v1/keys/{id} يحد هذا المفتاح تحديدًا:
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"credits_cap_cycle": 5000}'null يزيل الحد (باستثناء المفتاح pk_، حيث يمكن تعديل الميزانية ولكن لا يمكن إزالتها). 0 يعني مفتاحًا لا يمكن إنفاق أي شيء به: طريقة لإيقاف المفتاح دون إلغائه. العداد هو نفسه كما في الائتمانات، ويُعاد ضبطه مع دورة التعرفة.
عندما يصطدم المفتاح بميزانيته، يُرجع 429 KEY_BUDGET_EXHAUSTED، حتى لو كان هناك رصيد متبقٍ في الحساب، وحتى في خطة مع overage: الميزانية التي يمكن تجاوزها مقابل المال ليست ميزانية. طالما تم تحديد ميزانية، كل استجابة تحمل X-Key-Budget-Limit و X-Key-Budget-Remaining.
نطاق نقاط النهاية
Section titled “نطاق نقاط النهاية”المفتاح بدون نطاق يستدعي كل ما هو ضمن الخطة. allowed_endpoints يحدده إلى قائمة من المسارات: محددة (chart) أو مساحة أسماء (embed/*). هذا قيد ثالث مستقل: قائمة النطاقات تخبر من أين، الميزانية تخبر بكمية، والنطاق يخبر ما هو.
curl -X PATCH https://api.astroway.info/v1/keys/433 \ -H "X-Api-Key: aw_live_master_key" \ -H "Content-Type: application/json" \ -d '{"allowed_endpoints": ["embed/*", "public/moon-phase"]}'null يزيل الحد (باستثناء المفتاح pk_، حيث النطاق إلزامي). القائمة الفارغة غير مقبولة: ستُفسر كـ “الكل” و”لا شيء” على حد سواء. تُكتب المسارات نسبةً إلى /v1، بدون شرطة مبدئية، ولا يهم حالة الأحرف.
الطلب خارج القائمة يحصل على 403 ENDPOINT_NOT_IN_SCOPE، وdetails يذكر القائمة نفسها لتجنب التخمين. النطاق ينطبق على كلا فئتي المفاتيح وعلى /v1/public/* و/v1/embed/* بنفس الطريقة كما على البقية. القراءات الخدمية من خلاله غير معفاة، على عكس الائتمانات: المفتاح المحدد إلى embed/* لن يقرأ إحصائياته الخاصة. هذا مقصود، لأن المفتاح الموجود في كود الصفحة لا يجب أن يكشف للزائر نفقات الحساب، لكن التحكم بالمفتاح لا يعيق ذلك: لوحة التحكم تستخدم الجلسة، وليس المفتاح.
أفضل الممارسات
Section titled “أفضل الممارسات”1. لا تضع مفتاح server-only في الواجهة الأمامية
Section titled “1. لا تضع مفتاح server-only في الواجهة الأمامية”المفتاح النموذجي هو سر من مستوى الخلفية. إذا وصل إلى JavaScript الذي يُنفذ في متصفح المستخدم، يصبح مرئيًا في DevTools وسيتسرب. لهذا السبب يرد هذا المفتاح بـ 403 ORIGIN_FORBIDDEN على أي طلب يحمل Origin أو Referer.
إذا كان من الضروري الاتصال من المتصفح، يتم ذلك بمفتاح منفصل تم إنشاؤه باستخدام origin_restriction.type: "public": المفاتيح للمتصفح. هذا المفتاح يحمل البادئة pk_، وهو أيضًا مرئي في DevTools، وهذا هو الهدف كله - قيمته محدودة بقائمة نطاقاتك، والطلب بدون أصل يُرفض.
صحيح: الخلفية الخاصة بك تحتفظ بالمفتاح، الواجهة الأمامية تتواصل مع الخلفية الخاصة بك، وخلفيتك تتواصل مع AstroWay API.
خطأ:
// DO NOT DO THISfetch('https://api.astroway.info/v1/chart', { headers: { 'X-Api-Key': 'aw_live_...' }, // visible in browser});2. متغيرات البيئة، لا تكتب القيم مباشرة
Section titled “2. متغيرات البيئة، لا تكتب القيم مباشرة”# .env (in .gitignore)ASTROWAY_API_KEY=aw_live_...// in codeconst key = process.env.ASTROWAY_API_KEY;if (!key) throw new Error('ASTROWAY_API_KEY is not set');3. مفاتيح منفصلة للبيئات المختلفة
Section titled “3. مفاتيح منفصلة للبيئات المختلفة”production-backend: الإنتاجstaging-backend: التجربةci-tests: خط أنابيب CI/CDlocal-dev-maksym: تطوير محلي لكل مطور
إذا تم اختراق مفتاح ما - قم بإلغاءه فقط، وستستمر المفاتيح الأخرى في العمل.
4. التدوير
Section titled “4. التدوير”التردد الموصى به - مرة كل 90 يومًا. أو فورًا إذا كان هناك اشتباه في تسرب.
التدوير بدون توقف الخدمة:
- أنشئ مفتاحًا جديدًا بنفس
name+-v2 - انشره في الإنتاج (بالتوازي مع القديم)
- تأكد من أن الاستخدام يتحول إلى المفتاح الجديد (لوحة التحكم)
- ألغِ القديم
5. مراقبة الاستخدام
Section titled “5. مراقبة الاستخدام”لوحة التحكم تُظهر الطلبات حسب كل مفتاح على حدة. إذا فجأة بدأ مفتاح ما يرسل طلبات أكثر بـ 10× من المعتاد - فهذا إشارة للتحقق.
يمكن ضبط تنبيه: Settings → Notifications → Alert when daily credits > X.
أخطاء المصادقة
Section titled “أخطاء المصادقة”| الرمز | القيمة |
|---|---|
401 Unauthorized | Header X-Api-Key مفقود أو المفتاح غير صالح |
403 Forbidden | المفتاح صالح، لكنه لا يملك النطاق لهذه العملية (مثلاً مفتاح عادي يحاول إدارة مفاتيح أخرى) |
403 PUBLISHABLE_KEY_UNBOUNDED | المفتاح pk_ بدون ميزانية credits_cap_cycle أو بدون نطاق allowed_endpoints: عيّن كليهما في إعدادات المفتاح |
402 Payment Required | انتهت الأرصدة (في الخطة المجانية) أو الاشتراك غير نشط |
429 Too Many Requests | تم تجاوز حد المعدل (10/60/300 طلب/دقيقة حسب الخطة) |
مثال 401:
{ "error": { "code": "invalid_api_key", "message": "The API key provided is invalid or has been revoked.", "request_id": "8aec43e9bc749b37e998a489bbad1757" }}وضع الصندوق الرملي
Section titled “وضع الصندوق الرملي”المفاتيح ذات البادئة aw_test_ تعمل في الصندوق الرملي:
- لا تخصم أرصدة
- تُرجع ردًا ثابتًا أو حسابًا حقيقيًا بسيطًا
- لا تؤثر على إحصائيات الإنتاج
- نقاط النهاية المتاحة: نفسها
مفيد لـ CI/CD، اختبارات e2e، والتطوير المحلي. يتم إنشاؤه عبر لوحة التحكم بنقرة واحدة.
التالي
Section titled “التالي”- الأرصدة والحدود: كيف يعمل الفوترة وتحديد المعدل
- الأخطاء: قائمة كاملة بأكواد الأخطاء