بهجای اینکه هر چند ثانیه /rates را صدا بزنید، یک اتصال باز کنید و هر تغییر نرخ را همان لحظه بگیرید. قالب Server-Sent Events است: متن ساده روی HTTP، بدون کتابخانهٔ خاص.
GET
/api/fx/v1/stream
فقط طرح پرو
| پارامتر | توضیح |
|---|---|
codes | کدهای موردنظر با کاما، حداکثر ۲۰. پیشفرض USD. |
رویدادها
retry: 3000
event: rate
data: {"code":"USD","name":"دلار آمریکا","unit":1,"buy":101900,"sell":102900,"mid":102400,"change_24h_percent":0.39,"as_of":"2026-09-05T10:20:00+03:30","usd_irt":102400}
event: ping
data: {"t":"2026-09-05T10:20:15+03:30"}
event: rate
data: {"code":"USD","buy":102000,"sell":103000,"mid":102500,"…":"…"}
event: reconnect
data: {"in_ms":3000}
rate— بلافاصله پس از اتصال برای هر کد یک بار (وضعیت فعلی)، سپس هر بار که خرید/فروش/میانگین آن کد عوض شود.ping— هر ۱۵ ثانیه تا پروکسیها اتصال را نبندند.reconnect— پایان عمر اتصال (حدود ۵۵ ثانیه). دوباره وصل شوید؛ کلاینتهای SSE استاندارد این کار را خودکار میکنند (retry: 3000).
نمونهکد
// EventSource هدر سفارشی نمیپذیرد؛ برای مرورگر از fetch + ReadableStream استفاده کنید:
const res = await fetch("https://netarz.ir/api/fx/v1/stream?codes=USD,EUR", {
headers: { Authorization: "Bearer fx-ntz-v1-...", Accept: "text/event-stream" },
});
const reader = res.body.pipeThrough(new TextDecoderStream()).getReader();
let buffer = "";
while (true) {
const { value, done } = await reader.read();
if (done) break; // هر ~۵۵ ثانیه؛ دوباره وصل شوید
buffer += value;
const events = buffer.split("\n\n"); buffer = events.pop();
for (const raw of events) {
const type = raw.match(/^event: (.+)$/m)?.[1];
const data = raw.match(/^data: (.+)$/m)?.[1];
if (type === "rate") {
const r = JSON.parse(data);
document.querySelector(`[data-code=${r.code}]`).textContent = r.mid.toLocaleString("fa-IR");
}
}
}
// Node 18+ — با اتصال مجدد خودکار
async function stream() {
while (true) {
try {
const res = await fetch("https://netarz.ir/api/fx/v1/stream?codes=USD", {
headers: { Authorization: `Bearer ${process.env.NETARZ_FX_KEY}` },
});
for await (const chunk of res.body) {
for (const line of chunk.toString().split("\n")) {
if (line.startsWith("data: ")) console.log(JSON.parse(line.slice(6)));
}
}
} catch (e) { console.error("stream dropped", e.message); }
await new Promise(r => setTimeout(r, 3000));
}
}
stream();
import requests, json, time
while True:
with requests.get("https://netarz.ir/api/fx/v1/stream", params={"codes": "USD,EUR"},
headers={"Authorization": "Bearer fx-ntz-v1-..."}, stream=True, timeout=90) as r:
for line in r.iter_lines():
if line.startswith(b"data: "):
print(json.loads(line[6:]))
time.sleep(3)
محدودیتها
- حداکثر ۲ استریم همزمان برای هر اپ (
429 too_many_streams). - هر اتصال یک درخواست از سهمیهٔ روزانه حساب میشود — نه هر رویداد.
- در مرورگر،
EventSourceنمیتواند هدر Authorization بفرستد؛ نمونهٔ بالا باfetchاست. اگر ترجیح میدهید کلید در فرانت نباشد، استریم را از بکاند خود پروکسی کنید.