Oref Alert Proxy
March 24, 2026 · View on GitHub
Local relay proxy for Israel Homefront Command (Pikud HaOref) real-time alert data.
Why This Exists
Israel's Homefront Command publishes real-time rocket, UAV, and threat alerts through an unofficial JSON endpoint. There is no official public API — the data comes from the same internal feed that powers the Oref website and the official HFC app.
If you're building anything that consumes this data — a dashboard, a Telegram bot, a home automation trigger, a desktop notification app — you need to poll the endpoint every few seconds. The problem is that if you run multiple services, each one polls independently, which means:
- Redundant traffic to the same endpoint
- Inconsistent state — each service may see a slightly different snapshot depending on timing
- Harder to manage — polling logic, error handling, and BOM-stripping duplicated everywhere
This proxy solves that by polling once and serving the data locally via a simple HTTP API. All your downstream services read from the proxy instead.
┌────────────────────┐ ┌──────────────────┐
│ Oref (Pikud │ ──3s─▶ │ This Proxy │
│ HaOref endpoint) │ │ (port 8764) │
│ Geo-restricted │ │ Runs in Israel │
└────────────────────┘ └────────┬─────────┘
│
┌─────────────┼─────────────┐
▼ ▼ ▼
┌──────────┐ ┌──────────┐ ┌──────────┐
│Dashboard │ │Telegram │ │Home │
│ │ │Bot │ │Automation│
└──────────┘ └──────────┘ └──────────┘
Design Philosophy
This is a dumb relay. It passes through whatever Oref returns, verbatim:
- No category remapping — if Oref says category 10, you get category 10
- No alert persistence — when alerts disappear from Oref's response, they disappear here too
- No interpretation — shelter instructions, early warnings, and drills are passed through as-is
- No authentication — it's a local service, bind it to localhost or your LAN
Interpretation is the consumer's job. A dashboard might want to color-code by category and track alert duration. A bot might only care about threshold crossings. The proxy doesn't make those decisions.
API Endpoints
| Endpoint | Description |
|---|---|
GET /api/alerts | Current active alerts (polled every POLL_INTERVAL) |
GET /api/alerts/raw | Raw Oref response text for consumers that want to parse it themselves |
GET /api/history | Today's full alert history (polled every HISTORY_INTERVAL) |
GET /api/health | Health check |
GET /api/status | Poller stats — poll count, error count, timing, current alert count |
Response Formats
GET /api/alerts
{
"alerts": [
{
"data": "תל אביב - מרכז העיר",
"cat": 1,
"title": "ירי רקטות וטילים",
"desc": "",
"alertDate": "2026-03-10 14:22:05"
}
],
"timestamp": 1710115325.4
}
When there are no active alerts, the array is empty:
{
"alerts": [],
"timestamp": 1710115328.1
}
GET /api/status
{
"uptime_seconds": 3600.0,
"alerts": {
"poll_count": 1200,
"error_count": 0,
"last_poll_ago": 1.2,
"last_nonempty_ago": null,
"current_count": 0,
"poll_interval": 3
},
"history": {
"poll_count": 60,
"error_count": 0,
"last_poll_ago": 12.4,
"current_count": 379,
"poll_interval": 60
}
}
Oref Alert Format Reference
The alert objects come directly from Oref. Key fields:
| Field | Type | Description |
|---|---|---|
data | string | Area name in Hebrew (e.g., "ירושלים - דרום") |
cat | int | Alert category number |
title | string | Alert type description in Hebrew |
desc | string | Additional description (often empty) |
alertDate | string | Timestamp in YYYY-MM-DD HH:MM:SS format |
Alert Categories
| Category | Meaning | Severity |
|---|---|---|
| 1–4 | Rockets & Missiles | Active threat |
| 6 | Unauthorized Aircraft | Active threat |
| 7 | Hostile Aircraft Intrusion | Active threat |
| 8 | Infiltration | Active threat |
| 9 | Tsunami | Active threat |
| 10 | Earthquake | Active threat |
| 11 | Radiological | Active threat |
| 12 | Hazardous Materials | Active threat |
| 13 | All Clear | Event ended |
| 14 | Pre-Warning | Alert expected shortly |
| 15–28 | Drills | Not real alerts |
Note: Oref sometimes sends single-object responses (instead of an array) for special messages like shelter instructions or early warnings. The proxy normalizes these into a single-element array, but does not remap the category. Consumers should handle categories 13 (all-clear) and 15–28 (drills) appropriately.
Setup
Docker (recommended)
git clone https://github.com/danielrosehill/Oref-Alert-Proxy.git
cd Oref-Alert-Proxy
docker compose up -d
Direct
pip install httpx fastapi uvicorn
python server.py
Environment Variables
| Variable | Default | Description |
|---|---|---|
POLL_INTERVAL | 3 | Active alert poll interval in seconds |
HISTORY_INTERVAL | 60 | History poll interval in seconds |
HOST | 0.0.0.0 | Bind address |
PORT | 8764 | Listen port |
Geo-Restriction
The Oref API is geo-restricted to Israeli IP addresses. This proxy must run from within Israel — either on a machine with an Israeli IP, or behind a VPN/proxy with an Israeli exit node. Non-Israeli IPs will get empty or error responses.
Resource Usage
Polling every 3 seconds sounds aggressive, but it's extremely lightweight:
| Resource | Estimate | Context |
|---|---|---|
| Requests/day | ~28,800 | One GET every 3s |
| Response size (quiet) | 0 bytes | Empty string when no alerts |
| Response size (alerts) | 1–50 KB | Small JSON array |
| Bandwidth/day (quiet) | ~30–100 MB | Mostly TLS overhead |
| Bandwidth/day (mass attack) | Up to ~500 MB | Sustained large payloads |
| CPU/day | ~30 seconds cumulative | JSON parse + cache update |
| RAM | ~30–50 MB | Python + FastAPI + httpx connection pool |
For comparison, a single browser tab on a news website generates more daily traffic than this proxy. The official Oref website itself polls at the same 3-second interval — this is the intended consumption pattern.
Consuming the Proxy
Python
import httpx
resp = httpx.get("http://localhost:8764/api/alerts")
alerts = resp.json()["alerts"]
for alert in alerts:
area = alert["data"]
category = alert["cat"]
print(f"{area}: category {category}")
JavaScript
const resp = await fetch("http://localhost:8764/api/alerts");
const { alerts } = await resp.json();
alerts.forEach(alert => {
console.log(`${alert.data}: category ${alert.cat}`);
});
curl
# Current alerts
curl -s http://localhost:8764/api/alerts | jq .
# Poller status
curl -s http://localhost:8764/api/status | jq .
Related Projects
- Red-Alert-Telegram-Bot — Telegram bot for situational awareness, consumes from this proxy
- Awesome-Red-Alerts — Curated list of Oref API wrappers and alert projects
License
MIT