Docs.
Everything the site draws is served by four read-only endpoints. They are open, need no key, send access-control-allow-origin: *, and are the same endpoints the pages themselves call.
01GET /api/summary
Every index with its latest price, 24h change, source quality and a 15-minute sparkline.
curl https://werid.77.42.65.214.sslip.io/api/summary
# one category, no sparkline (much smaller)
curl 'https://werid.77.42.65.214.sslip.io/api/summary?category=Metals&spark=0'
{
"id": 0,
"t": "GLD", // symbol
"name": "Gold",
"category": "Metals",
"unit": "oz",
"last": 4398.0,
"ts": 1789747200, // unix seconds, from the source
"age": 644, // seconds since that observation
"quality": "live", // live | daily | static | reference
"stale": false,
"chg24": -0.41, // percent
"spark": [4391.2, 4393.8, ...]
}
]
| PARAM | DEFAULT | MEANING |
|---|---|---|
| category | all | Exact category name, as listed by /api/commodities. |
| spark | 1 | Set to 0 to drop the sparkline arrays. |
02GET /api/history
OHLC candles for one index. The market can be given as a numeric id or as a symbol.
{ "market": 0, "symbol": "GLD", "unit": "oz", "tf": 900,
"candles": [ { "t": 1789747200, "o": 4391.2, "h": 4398.0, "l": 4390.1, "c": 4398.0, "n": 3 } ] }
| PARAM | DEFAULT | MEANING |
|---|---|---|
| market | — | Required. Numeric id or symbol, case insensitive. |
| tf | 900 | Bucket size in seconds: 60, 300, 900, 3600 or 86400. |
| limit | 96 | 1 to 1000 candles, oldest first. |
| since | 0 | Unix seconds; only candles at or after this bucket. |
03GET /api/commodities
The catalogue: what exists, in what unit, from which source. Static enough to cache.
"categories": [ { "name": "Metals", "count": 6 }, ... ],
"markets": [ { "id": 0, "symbol": "GLD", "name": "Gold", "category": "Metals",
"unit": "oz", "quality": "live",
"source": "Front-month futures quote (Yahoo Finance), converted to USD per catalogue unit" } ] }
04GET /api/health
Whether the feed is doing its job. status is ok only while every adapter has succeeded within three of its own poll intervals, so a dead source shows up here before anyone notices a stale price.
"sources": [ { "kind": "yahoo", "label": "Yahoo Finance futures", "everyMs": 300000,
"lastSuccess": 1789747200000, "lastCount": 29, "expected": 29,
"consecutiveFailures": 0, "healthy": true, "error": null } ],
"store": { "candles": 1869, "priced": 220 } }
05Running it yourself
One Node process, no external database, no runtime dependencies.
npm start # http://localhost:4800
# environment
PORT 4800
HOST 0.0.0.0
State lives in data/werid.db (SQLite via node:sqlite) and resolved TCGplayer ids are cached in data/cache/. Deleting either is safe: the catalogue re-seeds from data/universe.txt and the ids resolve again on the next poll.
06Links
- Methodology: where every price comes from
- Commodities: all 220, live
- @WeridARC on X