الأدلةأدلة

واجهة API لأسعار الصرف على Stack Overflow: حل مشكلات المطورين

أخطاء واجهة API لأسعار الصرف التي يواجهها المطورون على Stack Overflow، محلولة: مصادقة 401، وحدود الطلبات 429، وCORS من المتصفح، والأسعار الراكدة في عطلة الأسبوع، وتحويل مبلغ، وجلب بيانات تاريخية أو سلسلة زمنية.

6 أغسطس 2026 · قراءة 6 دقائق

حين يتعطل التكامل، يلصق المطورون الخطأ في Stack Overflow. بالنسبة لواجهة API لأسعار الصرف، تكاد الأسئلة تكون نفسها دائمًا: مفتاح مرفوض، جدار حد طلبات، خطأ CORS، أو سعر يبدو راكدًا في عطلة الأسبوع. إليك حلولًا مباشرة، باستخدام exchangerate.dev كمثال عملي. كل مقتطف استدعاء حقيقي ضد https://api.exchangerate.dev.

  • يعني 401 تقريبًا دائمًا غياب بادئة Bearer أو مفتاحًا فيه سطر جديد شارد من النسخ واللصق.
  • راقب X-RateLimit-Remaining قبل بلوغ الحد. وعند 429 اقرأ X-RateLimit-Scope وRetry-After.
  • استدعاءات المتصفح المجهولة مسموحة. لا تضع مفتاح الحساب في جافاسكربت الواجهة الأمامية.
  • يخبرك source وmarket_session في كل استجابة بالضبط لماذا لا يتحرك سعر ما.

الـ base URL هو https://api.exchangerate.dev. يعمل أول استدعاء دون تسجيل (بحد أقصى لكل IP)، فيمكنك تجربة الأسعار الحديثة قبل التسجيل.

401 Unauthorized, المفتاح مرفوض

يوضع المفتاح في ترويسة Authorization كرمز bearer، ويجب أن تكون كلمة Bearer متبوعة بمسافة موجودة. تبدأ المفاتيح بالبادئة exr_live_.

curl · authenticated
curl https://api.exchangerate.dev/v1/latest/USD \  -H "Authorization: Bearer exr_live_YOUR_KEY"

الأسباب المعتادة لخطأ 401: غياب بادئة Bearer ، أو التقط المفتاح سطرًا جديدًا أو علامة اقتباس شاردة من النسخ واللصق، أو أن متغير البيئة الحامل له غير مُحمَّل. المنصات التي لا يمكنها ضبط Authorization يمكنها إرسال المفتاح كترويسة X-API-Key بدلاً من ذلك.

429 Too Many Requests, التعامل مع حدود الطلبات

تحمل الاستجابات الناجحة المحتسبة X-RateLimit-Remaining. ويعيد 429 Retry-After، فانتظر المدة المحددة قبل المحاولة. يوضح X-RateLimit-Scope هل استنفدت حد الدقيقة، أو حد الساعة المجهول، أو الحصة الشهرية. حد الدقيقة: مجاني 10، Basic 60، Plus 120، Pro 300. افحص حصة الحساب وموعد إعادة تعيينها الشهري عبر GET /v1/account.

خطأ CORS, استدعاء الـ API من المتصفح

تسمح CORS بالقراءات المجهولة وبترويستي Authorization وX-API-Key. لكن ذلك لا يجعل طلب المتصفح المزود بمفتاح سريًا: يستطيع أي شخص يفتح أدوات المطورين نسخ exr_live_.... استخدم الاستدعاء المجهول للعرض العام؛ ولاستخدام حصة الحساب، مرر الطلب عبر خادمك الخلفي واحتفظ بالمفتاح على الخادم.

javascript · your backend route
// the key never reaches the browserconst r = await fetch("https://api.exchangerate.dev/v1/latest/USD", {  headers: { Authorization: `Bearer ${process.env.EXCHANGERATE_API_KEY}` },});const data = await r.json();

كيف أخزّن أسعار الصرف مؤقتًا بأمان؟

خزّن الرصد الناجح كاملًا: السعر وsource وmarket_session وdata_updated_at. ابدأ للأزواج النشطة بتخزين 60 ثانية على الخادم. يقلل ذلك الطلبات المكررة، لكنه لا يجعل السعر المرجعي اليومي أحدث.

  • اجمع العملات في طلب symbols واحد بدل استدعاء HTTP مستقل لكل زوج.
  • خزّن استجابات 2xx الناجحة فقط. لا تحفظ 401 أو 429 أو خطأ المصدر كسعر.
  • عند 429 استخدم Retry-After وX-RateLimit-Scope، ولا تفترض مدة انتظار ثابتة.
  • احتفظ بمفاتيح الحساب في إعدادات الخادم، لا في cache أو حزمة متصفح عامة.

السعر يبدو راكدًا أو لا يتغير في عطلة الأسبوع

هذا متوقع، والاستجابة تخبرك بالسبب. تُحدَّث العملات الـ144 كل نحو 60 ثانية في أيام التداول. يوفر ECB بديلًا يوميًا لنحو 30 عملة. في عطلة الأسبوع يكون السوق بين البنوك مغلقًا، فتتوقف التغذية المباشرة وتحمل الأسعار المرجعية آخر قيمة منشورة. حقلان يوضحان ذلك صراحة:

قيمة الحقلماذا تعنيمتى تتحرك
source: liveسعر فوري إرشاديخلال اليوم (~60 ثانية)، أسبوع التداول
source: ecb_dailyتثبيت مرجعي رسميمرة واحدة في يوم العمل
source: market_dailyإغلاق محفوظ بلا تثبيت ECBتغذية السوق اليومية
market_session: weekendالسوق بين البنوك مغلقالتغذية المباشرة متوقفة؛ يحمل السعر المرجعي قيمة الجمعة

كيف أحوّل مبلغًا، لا أن أقرأ سعرًا فقط؟

استخدم /v1/convert/{from}/{to}/{amount}. تعيد السعر والمبلغ المحوَّل معًا، فلا تحتاج للضرب يدويًا:

curl · convert 100 USD to EUR
curl https://api.exchangerate.dev/v1/convert/USD/EUR/100 \  -H "Authorization: Bearer exr_live_YOUR_KEY"

كيف أحصل على بيانات تاريخية أو سلسلة زمنية؟

ليوم واحد: GET /v1/{YYYY-MM-DD}/{base}؛ منذ 1999 بمفتاح Plus/Pro. لسلسلة كاملة عبر مدى زمني في استدعاء واحد، استخدم GET /v1/range مع start_date وend_date؛ يستخدم ترقيمًا بالمؤشر (keyset)، فاتبع المؤشر بدل طلب مدى ضخم دفعة واحدة.

أُرحّل من واجهة API أخرى لأسعار الصرف وأواجه أخطاء؟

تتبع معاملات الطلب الاصطلاحات الشائعة بين واجهات API لأسعار الصرف (عملة أساس مع مرشّح symbols)، فمعظم عمليات الترحيل مجرد تبديل الـ base URL دون إعادة كتابة الكود. حيث تختلف الاستجابات، تضيف هذه الـ API حقولًا (source وmarket_session وnotice) بدل حذفها, راجع الكود الذي يقرأ الاستجابة تحسبًا لافتراضه مجموعة ثابتة من المفاتيح.

أقصر استدعاء يعمل

دون مفتاح، دون تبعيات:

curl · no key
curl https://api.exchangerate.dev/v1/latest/USD

تحصل على الأسعار إضافة إلى source وmarket_session فتعرف مدى حداثة كل منها. مفتاح مجاني يرفع الحد إلى 5,000 استدعاء شهريًا ويستغرق دقيقة.

إرشادي، وليس للتسوية

تُنشر الأسعار للمرجعية والتحليل والعرض. ليست عرض سعر تنفيذي ولا يجب استخدامها لتسوية صفقة. تسمح المجانية بالعرض التجاري مع رابط إسناد ظاهر؛ المدفوعة لا تتطلب إسناداً.

أسئلة

لماذا أحصل على 401 من واجهة API لأسعار الصرف؟

يعني 401 تقريبًا دائمًا أن ترويسة Authorization مشوّهة الصياغة. أرسل المفتاح بصيغة "Bearer exr_live_..." مع بادئة Bearer ومسافة، وتأكد من عدم وجود سطر جديد أو علامة اقتباس شاردة من النسخ. المنصات التي لا يمكنها ضبط Authorization يمكنها استخدام ترويسة X-API-Key بدلاً من ذلك.

كيف أتعامل مع أخطاء حد الطلبات 429؟

انتظر المدة التي تحددها Retry-After قبل إعادة المحاولة، واستخدم X-RateLimit-Scope لمعرفة الحد الذي استنفدته. يساعدك X-RateLimit-Remaining على التخفيف قبل الصفر. افحص حصة الحساب عبر GET /v1/account، وخزّن الاستجابات الناجحة فقط.

كيف أخزّن أسعار الصرف مؤقتًا دون عرض بيانات قديمة بشكل مضلل؟

خزّن الرصد الناجح كاملًا، مع source وmarket_session وdata_updated_at إلى جانب السعر. تخزين الخادم لمدة 60 ثانية نقطة بداية لتقليل الطلبات المكررة للأزواج الحية، لكنه لا يجعل السعر المرجعي اليومي أحدث. لا تخزّن 401 أو 429 أو خطأ المصدر كسعر صالح.

لماذا لا يتحدث سعر الصرف في عطلة الأسبوع؟

يكون السوق بين البنوك مغلقًا في عطلة الأسبوع، فتتوقف التغذية المباشرة ويحمل التثبيت المرجعي اليومي قيمة يوم الجمعة. تخبرك الاستجابة بذلك مباشرة: يكون market_session قيمته "weekend" ويكون source فئة مرجعية يومية بدل "live".

كيف أحصل على أسعار صرف تاريخية؟

ليوم واحد: /v1/{YYYY-MM-DD}/{base}؛ منذ 1999 بمفتاح Plus/Pro. لمدى تاريخي في استدعاء واحد، استخدم /v1/range مع start_date وend_date، متبعًا مؤشر الترقيم الخاص به.

تابع القراءة

ابدأ بمفتاح API مجاني

5,000 طلب شهريًا ضمن الخطة المجانية. لا حاجة إلى بطاقة ائتمان.

احصل على مفتاح مجاني