Bắt đầu nhanh
Tạo khóa trong ứng dụng tại Wire → Khóa API rồi gọi API từ bất kỳ đâu. Phản hồi là JSON, thời gian theo ISO-8601 UTC.
curl -H "Authorization: Bearer rr_live_…" \
https://realityradar-7h6.pages.dev/api/v1/public/alerts?limit=5const res = await fetch('https://realityradar-7h6.pages.dev/api/v1/public/entities', {
method: 'POST',
headers: { Authorization: `Bearer ${process.env.RADAR_KEY}`, 'Content-Type': 'application/json' },
body: JSON.stringify({ entityType: 'software_version', displayName: 'Node.js', modelOrVersion: '18.20.0',
identifiers: { eolProduct: 'nodejs' }, relationship: 'used' }),
});
console.log(res.status, await res.json());import os, requests
r = requests.get("https://realityradar-7h6.pages.dev/api/v1/public/events", params={"type": "product_recall", "limit": 20},
headers={"Authorization": f"Bearer {os.environ['RADAR_KEY']}"}, timeout=10)
r.raise_for_status()
for e in r.json()["items"]:
print(e["firstSeenAt"], e["title"], e["sourceUrl"])Xác thực
Gửi khóa dưới dạng token Bearer. Khóa chỉ hiện một lần, chỉ lưu dạng băm, có thể hết hạn sau 30, 90 hoặc 365 ngày và được thay thế với 24 giờ chồng lấn.
Authorization: Bearer rr_live_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXPhạm vi
Mỗi khóa chỉ mang các phạm vi bạn chọn. Yêu cầu ngoài phạm vi trả về 403 insufficient_scope, nên khóa chỉ đọc không thể thêm mục hay quản lý webhook.
| Phạm vi | Endpoint |
|---|---|
read:signals | GET /public/eventsGET /public/events/{id} |
read:entities | GET /public/entities |
write:entities | POST /public/entities |
read:alerts | GET /public/alerts |
manage:webhooks | GET /public/webhooksPOST /public/webhooksDELETE /public/webhooks/{id}GET /public/webhooks/{id}/deliveriesPOST /public/webhooks/{id}/deliveries/{deliveryId}/replay |
Giới hạn tần suất
Khóa tiêu chuẩn cho phép 60 yêu cầu mỗi phút, khóa hạn mức cao 300. Phản hồi 429 nghĩa là chờ rồi thử lại; mức dùng theo khóa và endpoint có trong Wire.
Phân trang
Endpoint danh sách trả về items và nextCursor. Gửi lại cursor cho đến khi nó là null; cursor là chuỗi mờ và ổn định khi phân trang.
cursor = None
while True:
page = requests.get(f"https://realityradar-7h6.pages.dev/api/v1/public/events", headers=H, params={"limit": 100, "cursor": cursor}).json()
handle(page["items"])
cursor = page["nextCursor"]
if not cursor:
breakLỗi
Lỗi dùng một định dạng chung với mã cố định. Thử lại 5xx và 429 với độ trễ tăng dần; 4xx nghĩa là yêu cầu có vấn đề.
{ "error": { "code": "insufficient_scope", "message": "This key lacks the \"write:entities\" scope" } }invalid_api_key | 401 | Thiếu khóa, sai định dạng hoặc đã thu hồi |
api_key_expired | 401 | Khóa đã quá hạn hoặc quá thời gian thay thế |
insufficient_scope | 403 | Khóa thiếu phạm vi mà endpoint này yêu cầu |
not_found | 404 | Không tìm thấy hoặc không hiển thị cho không gian này |
plan_limit | 409 | Đã đạt giới hạn mục của gói miễn phí |
ssrf_blocked | 422 | URL trỏ tới địa chỉ riêng tư hoặc nội bộ |
rate_limited | 429 | Quá nhiều yêu cầu — thử lại sau khoảng chờ |
Webhook
Webhook gửi POST một sự kiện JSON khi có cảnh báo từ mức bạn chọn trở lên. Nhật ký gửi lưu 30 ngày kèm trạng thái, độ trễ và gửi lại một chạm.
POST /your/endpoint
Content-Type: application/json
User-Agent: RealityRadar-Webhook/1.0
X-Radar-Signature: t=1761112800,v1=5f2b…a91c,v1=03de…77b0
{"type":"alert.created","alert":{"impactLevel":"critical","matchType":"exact",…},"event":{…}}Xác minh chữ ký
Tính HMAC-SHA256 của t, dấu chấm và nội dung thô bằng bí mật của bạn, so sánh thời gian hằng với bất kỳ v1 nào và từ chối dấu thời gian cũ hơn năm phút. Sau khi đổi bí mật, hai v1 được gửi trong 24 giờ.
import { createHmac, timingSafeEqual } from 'node:crypto';
// rawBody: the exact bytes you received (do not re-serialize JSON)
export function verifyRadar(header, rawBody, secret) {
const parts = header.split(',').map((p) => p.split('='));
const t = Number(parts.find(([k]) => k === 't')?.[1]);
const sigs = parts.filter(([k]) => k === 'v1').map(([, v]) => v);
if (!Number.isFinite(t) || Math.abs(Date.now() / 1000 - t) > 300) return false;
const mac = createHmac('sha256', secret).update(`${t}.${rawBody}`).digest('hex');
return sigs.some((v) => v.length === mac.length && timingSafeEqual(Buffer.from(v), Buffer.from(mac)));
}import hmac, hashlib, time
def verify_radar(header: str, raw_body: bytes, secret: str) -> bool:
parts = [p.split("=", 1) for p in header.split(",")]
t = next((int(v) for k, v in parts if k == "t"), None)
sigs = [v for k, v in parts if k == "v1"]
if t is None or abs(time.time() - t) > 300:
return False
mac = hmac.new(secret.encode(), f"{t}.".encode() + raw_body, hashlib.sha256).hexdigest()
return any(hmac.compare_digest(mac, s) for s in sigs)func VerifyRadar(header string, rawBody []byte, secret string) bool {
var t int64 = -1
var sigs []string
for _, p := range strings.Split(header, ",") {
k, v, ok := strings.Cut(p, "=")
if !ok { continue }
if k == "t" { t, _ = strconv.ParseInt(v, 10, 64) }
if k == "v1" { sigs = append(sigs, v) }
}
if t < 0 || math.Abs(float64(time.Now().Unix()-t)) > 300 { return false }
m := hmac.New(sha256.New, []byte(secret))
fmt.Fprintf(m, "%d.", t)
m.Write(rawBody)
want := hex.EncodeToString(m.Sum(nil))
for _, s := range sigs {
if hmac.Equal([]byte(want), []byte(s)) { return true }
}
return false
}# Replay a delivery (fresh timestamp + signature)
curl -X POST -H "Authorization: Bearer rr_live_…" \
https://realityradar-7h6.pages.dev/api/v1/public/webhooks/WEBHOOK_ID/deliveries/DELIVERY_ID/replayPhụ thuộc và OSV
Theo dõi gói bằng purl như pkg:npm/lodash và phiên bản chính xác. Reality Radar kiểm tra OSV.dev và đánh dấu khớp chính xác khi phiên bản của bạn nằm trong danh sách bị ảnh hưởng. Tải lockfile hoặc SBOM lên trong ứng dụng tại mục Nhập.
curl -X POST -H "Authorization: Bearer rr_live_…" -H "Content-Type: application/json" \
-d '{"entityType":"software_version","displayName":"lodash","modelOrVersion":"4.17.20","identifiers":{"purl":"pkg:npm/lodash"},"relationship":"used"}' \
https://realityradar-7h6.pages.dev/api/v1/public/entitiesThuật ngữ
Các thuật ngữ bạn sẽ gặp trong phản hồi.
- Signal (tín hiệu)
- Một thay đổi phát hiện từ nguồn chính thức, kèm bằng chứng và dấu thời gian.
- Beacon
- Một nguồn dữ liệu. Hạng A là cơ quan quản lý hoặc nhà sản xuất chính thức, hạng B là cơ sở dữ liệu đã kiểm chứng.
- Kiểu khớp
- exact, strong, probable hoặc weak — mức chắc chắn rằng sự kiện liên quan đến mục của bạn. Chỉ exact và strong được nêu là chắc chắn.
- Liên quan, tin cậy, mức nghiêm trọng
- Ba điểm 0–100 tính riêng: có liên quan đến bạn không, bằng chứng đáng tin đến đâu, thay đổi nghiêm trọng thế nào.
- purl
- Package URL, ví dụ pkg:npm/lodash, là định danh chuẩn dùng để khớp với OSV.
- Sổ cái bằng chứng
- Chuỗi băm chống giả mạo của mọi bằng chứng đã lưu, ai cũng có thể xác minh.