واجهة أسعار الصرف عبر WebSocket

اشترك في الأزواج المدعومة وتلقَّ تحديثات الأسعار عبر اتصال مستمر. احتفظ بمفتاح API على الخادم.

أنشئ مفتاحًا مجانيًااقرأ مرجع API

بدء الاتصال

اتصل بـ wss://api.exchangerate.dev/v1/stream وأرسل auth خلال 10 ثوانٍ، ثم أرسل subscribe بعد authenticated.

مثال اتصال

يُوثّق هذا التسلسل على الخادم مفتاحًا ويشترك في USD/EUR وUSD/JPY.

Node.js 22+ · عميل WebSocket على الخادم
// Node.js 22+ · run on your server · set EXCHANGERATE_API_KEY in the environment
const key = process.env.EXCHANGERATE_API_KEY;
if (!key) throw new Error("EXCHANGERATE_API_KEY is required");

let retries = 0;
let stopped = false;
function connect() {
  const ws = new WebSocket("wss://api.exchangerate.dev/v1/stream");
  ws.addEventListener("open", () => {
    ws.send(JSON.stringify({ action: "auth", api_key: key }));
  });
  ws.addEventListener("message", ({ data }) => {
    const frame = JSON.parse(String(data));
    if (frame.type === "authenticated") {
      retries = 0;
      ws.send(JSON.stringify({ action: "subscribe", base: "USD", symbols: ["EUR", "JPY"] }));
    } else if (frame.type === "snapshot" || frame.type === "update") {
      if (frame.stale) return; // Keep the observation time; don't treat it as a fresh tick.
      console.log(frame.base, frame.symbol, frame.rate, frame.effective_at);
    } else if (frame.type === "state") {
      console.log(frame.base, frame.symbol, frame.state); // stale or unavailable
    } else if (frame.type === "error") {
      console.error(frame.code, frame.message);
      if (["invalid_api_key", "quota_exceeded", "connection_limit_exceeded", "subscription_limit_exceeded"].includes(frame.code)) {
        stopped = true;
        ws.close();
      }
    }
  });
  ws.addEventListener("close", () => {
    if (stopped) return;
    const delay = Math.min(30_000, 1_000 * 2 ** Math.min(retries++, 5));
    setTimeout(connect, delay + Math.random() * 250);
  });
}
connect();

تتطلب اتصالات WebSocket المصادقة.

قراءة كل رسالة

تتضمن الرسالة الزوج والسعر ووقت المشاهدة وحالة الحداثة. تعامل مع unavailable وstale كحالتين صريحتين.

JSON · رسالة نموذجية؛ القيم والوقت للتوضيح فقط
{
  "type": "update",
  "base": "USD",
  "symbol": "JPY",
  "rate": "154.792",
  "effective_at": "2026-09-15T02:59:44Z",
  "source": "live",
  "source_type": "market",
  "market_session": "open",
  "derived": false,
  "stale": false
}

التغطية

يمكن الاشتراك فقط في الأزواج الموجودة في جدول التغطية الحالي. تتطلب التقاطعات مشاهدات حديثة لكلتا الساقين.

AUD, CAD, CHF, EUR, GBP, JPY, MXN, NOK, NZD, PLN, SEK, SGD, USD, ZAR · 182 الأزواج المدعومة

التحديثات مشاهدات إرشادية. تحقق من الحالة ووقت المشاهدة في كل رسالة.

تحقق من التغطية الحالية

حدود الخطة

يعتمد عدد الاتصالات والأزواج لكل اتصال على الخطة. يستهلك كل اتصال مقبول وحدة من الحصة الشهرية.

الخطةالاتصالاتالأزواج لكل اتصالالاستخدام التجاري
Free15لا
Basic325نعم
Pro10100نعم

يستهلك كل اتصال مقبول وحدة من الحصة الشهرية.

عرض الأسعار

الاستخدام التجاري

راجع الخطة الحالية وشروط الاستخدام التجاري قبل توزيع منتج يعتمد على البث.

إعادة الاتصال بأمان

بعد الانقطاع، انتظر قبل إعادة الاتصال، ثم وثّق من جديد وانتظر authenticated وأعد الاشتراك. لا تضع المفتاح في URL أو JavaScript عام.

تبقى التحديثات المفقودة مفقودة؛ لا ينشئ البث قيمًا.

هل يمكن الاتصال دون هوية؟

لا. تتطلب اتصالات WebSocket مفتاح API. يتوفر الاختبار المجهول عبر نقاط REST المدعومة.

هل يُبث كل زوج عملات؟

لا. تغطية WebSocket خاصة بكل زوج. راجع جدول التغطية وتعامل صراحة مع الاشتراكات غير المدعومة.