The same JSON that powers the frontend. Hermes (or any agent) can subscribe to /ws for live push, query /api/agent/ask in natural language, register webhooks, and manage alerts. All /api/* endpoints require a bearer token (or pass ?token=...); local callers from 127.0.0.1 skip auth.
Authorization: Bearer demo-token-please-change # or ?token=demo-token-please-change
Set the token via env: XISOB_TOKEN=... python3 app.py
The terminal reads annual, quarterly, audit, and IFRS records from https://new-api.openinfo.uz/api/v2/reports/... without credentials. Direct media files and generated PDF links are cached per company for 15 minutes.
?q=, ?ticker=URTS, ?sentiment=positive, ?source=OpenInfo, ?category=corporate, ?type=disclosure, ?limit=100.price_above, price_below, change_pct, news_keyword.curl -X POST http://localhost:8000/api/alerts \
-H "Authorization: Bearer demo-token-please-change" \
-H "Content-Type: application/json" \
-d '{"type":"price_above","ticker":"URTS","threshold":9000}'
curl -X POST http://localhost:8000/api/webhooks \
-H "Authorization: Bearer demo-token-please-change" \
-H "Content-Type: application/json" \
-d '{"url":"https://your-server/uzx-hook"}'
{"event":"alert","alert":{...}}ws://localhost:8000/ws?token=demo-token-please-change&channels=screener,news,alerts,fx,indices # or all channels: ws://localhost:8000/ws?token=demo-token-please-change
You'll receive JSON frames like: {"channel":"screener","data":{"count":69},"ts":...} on every server-side refresh (every 12 s for the tape, 5 min for news, 30 min for FX). Initial hello + snapshot frame on connect.
curl -X POST http://localhost:8000/api/agent/ask \
-H "Authorization: Bearer demo-token-please-change" \
-H "Content-Type: application/json" \
-d '{"q":"what is the biggest mover today?"}'
| Pattern | Returns |
|---|---|
biggest mover, mover, largest change | top absolute % change |
gainers, losers | top 10 of each |
top volume, top value | top 5 by volume / value |
USD, EUR, RUB, CNY, GBP | CBU rate |
index, UZSE | composite index + history |
news | latest 10 headlines |
any 3–6 letter uppercase token (e.g. URTS) | quote for that ticker |
Subscribe to live tape updates and react to large moves:
import asyncio, json, websockets, requests
TOKEN = "demo-token-please-change"
BASE = "http://localhost:8000"
WS = "ws://localhost:8000/ws"
# 1) Get current snapshot
snap = requests.get(f"{BASE}/api/snapshot",
headers={"Authorization": f"Bearer {TOKEN}"}).json()
print(f"Traded: {snap['market']['traded_issues']}, "
f"gainers: {snap['market']['gainers']}, "
f"losers: {snap['market']['losers']}")
# 2) Ask a question
ans = requests.post(f"{BASE}/api/agent/ask",
headers={"Authorization": f"Bearer {TOKEN}"},
json={"q": "biggest mover"}).json()
print(ans["answer"], "->", ans["data"]["ticker"])
# 3) Set an alert
alert = requests.post(f"{BASE}/api/alerts",
headers={"Authorization": f"Bearer {TOKEN}"},
json={"type": "change_pct", "ticker": "URTS", "threshold": 5}).json()
print("alert:", alert["alert"]["id"])
# 4) Register a webhook
hook = requests.post(f"{BASE}/api/webhooks",
headers={"Authorization": f"Bearer {TOKEN}"},
json={"url": "https://hermes.example/uzx"}).json()
print("webhook:", hook["webhook"]["id"])
# 5) Stream live updates
async def stream():
url = f"{WS}?token={TOKEN}"
async with websockets.connect(url) as ws:
async for msg in ws:
m = json.loads(msg)
if m["channel"] == "screener":
# re-pull snapshot
...
asyncio.run(stream())
| Source | Endpoint | What |
|---|---|---|
| UZSE / OpenInfo | /api/v2/iuzse/stock-screener/?mkt_id=STK&page_size=100 | Live OHLC, per-trade timestamp, change |
| UZSE / OpenInfo | /api/v2/iuzse/stock-screener/?mkt_id=BND&page_size=100 | Bond tape |
| UZSE / OpenInfo | /api/v2/iuzse/price-indices/ | UZSE composite index |
| UZSE / OpenInfo | /api/v2/iuzse/trade-analytics/?start_date=...&end_date=... | Top issuers by trades |
| UZSE / OpenInfo | /api/v2/iuzse/conclusions/?isu_cd=...&start_date=...&end_date=... | Per-issuer daily OHLC history |
| OpenInfo public v2 API | https://new-api.openinfo.uz/api/v2/reports/... | Annual, quarterly, audit, and IFRS documents + PDFs (no auth) |
| UZSE official schedule | https://www.uzse.uz/exchange/schedule?locale=en | 09:30 orders, 10:00–15:30 continuous trading, closing execution up to 16:02 |
| CBU (Central Bank) | https://cbu.uz/ru/arkhiv-kursov-valyut/json/ | Official UZS FX rates |
| RSS | uzdaily.uz, gazeta.uz, uza.uz | News headlines |
| Telegram | t.me/s/<channel> | Public channel preview (HTML) |
XISOB Terminal · local Bloomberg for Uzbek markets · v3 · hisob-kitob (accounting/calculation)