========================================= EURODATAHUB - PUBLIC STATIC DEPLOYMENT ========================================= This deployment serves the public, unauthenticated website only. No cookies are stored. The OS keeps desktop preferences and open windows in browser local storage, on your own device only — that storage is never used for tracking and is never transmitted to us. Eurodatahub is a project operating under the organization ThuleAI — https://thuleai.com/ Public pages: / The OS desktop — the OS is the landing page and boots directly /os The OS desktop (dataset browser, search, Crypto Klines app) /os?app=klines Crypto Klines — candlestick chart app inside the OS desktop (SQLite time-series, top 10 coins, 1m stored raw — the single stored grid, synced every minute; 5m–3d derived from the stored 1m candles) /os?app=chat Search — perplexity-like web answer engine inside the OS desktop (open/free search backends + LLM synthesis; searches kept only in the browser; NO rate limit) /os?app=api API — Eurodatahub API documentation app (endpoints, params, caching, live probe) /contact Contact information (no forms) /donate Donation page (links to OpenCollective, no forms) /pricing Pricing plans /about About Eurodatahub (a ThuleAI umbrella project) /about/datasets About the datasets /privacy Privacy policy (no cookies; local storage for preferences) /terms Terms of service /cookies Cookie policy (no cookies are stored) /invite Dataset access information Public API: /api/docs This document /api/market-history Market History — the SAME SQLite dataset as /api/klines (top-10 pairs, 1m stored raw over the full 1-year window (default 1 year; the EDH_KLINES_HISTORY_YEAR_OVERRIDE env var sets the retained years) — the single stored grid, synced every minute; 5m–3d derived from the stored 1m candles; permanent cache) documented as its own public REST endpoint: rows { openTime, open, high, low, close, volume, closeTime }, params symbol/interval/limit/startTime/endTime/timeZone; 404 unknown symbol; 400 bad params (full reference: GET /llms.txt — the machine-readable API index; mirrored in the API desktop app /os?app=api) /api/search Search — POST { message } to start ONE streamed cited answer (web fan-out + LLM synthesis), then poll /api/search/stream?job=; unlimited — no hourly cap /api/llms.txt The /llms.txt machine-readable API documentation (same file at /llms.txt) /api/klines Crypto Klines — cache-only reads from a SQLite time-series (eurodatahub_klines.sqlite3). ONLY the top 10 USDT pairs are supported (symbol list from the collector config); symbol= must be one of them. Supported intervals: 1m is STORED directly (raw, closed minute candles over the full 1-year window (default 1 year; the EDH_KLINES_HISTORY_YEAR_OVERRIDE env var sets the retained years) — the time-series' single stored grid) and every other interval is DERIVED on the fly from those stored 1m candles — 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d (a derived candle is emitted only when ALL of its constituent minute candles are present in the store and the bucket has fully closed, so derived values stay authentic and aligned to their interval grid; 1w and 1M are not offered because their week/month boundaries cannot be expressed as multiples of the minute grid). Parameters: symbol (top 10 only), interval (see above), limit (max 1000, newest N candles), startTime/endTime (open-time window, optional). An HTTP layer NEVER fetches upstream: a background collector is the only component that reaches the market-data upstream — AT MOST EVERY 1 MINUTE per symbol (database time stamps in klines_meta: the newest stored kline + the last-sync stamp are checked FIRST, and the upstream is hit ONLY when the latest stored kline is more than 1 minute old, in which case exactly the gap after it is fetched; symbols are refreshed SEQUENTIALLY — max 1 concurrent curl process over SOCKS5) — so there is no double-fetching, no double-storing and never more than one curl in flight. Responses (always cached=true, via curl over SOCKS5 with up to 10 retries per fetch — rotating-proxy failures are treated as IP blocks and respawned with a fresh node) are therefore at most ~1 minute behind live, and at most ~1 minute + one interval step for derived intervals (delayMs / maxDelayMs in the payload); before the first fill completes the endpoint answers 503. /api/chat POST — starts ONE streamed Chat reply (the LLM endpoint is hardcoded to the Grunden API: https://api.grunden.ai/v1/chat/completions, model glm-5.3-flash, API key from the GRUNDENAI_APIKEY env var). Body { message, history?, conversationId? } — CHAT HISTORY LIVES ONLY IN THE BROWSER: the server keeps NO conversation storage; the client sends its recent prior turns as history[] with every POST to give the model context, the sanitized copy is used for THIS one LLM call only and dropped the moment the reply finishes (never persisted or stored server-side), and the finished reply is appended to the browser's own thread. Response { conversationId, jobId, pollMs, rateLimit: { unlimited: true } }. STREAMING (websocket emulation, no socket layer): the client polls /api/chat/stream?job= every pollMs (500ms default); each poll returns { jobId, conversationId, done, content } — the incremental reply text (while nothing has streamed yet the Chat UI shows a "Thinking…" loader with a spinner; the first streamed text replaces it) — and done:true finalizes with { reply, replyHtml } (or error: when the background pass failed — the thread is the browser's own copy, so the client simply keeps it). /api/chat/stream?job= GET — the 500ms streamed-reply poller described above (one job per started reply; unknown or expired jobs answer 404). NO COUNT: how many chats or searches have been run is neither tracked nor exposed — there is no stats endpoint and no answers ledger. There are no sign-in, contact, or access-request forms on this site, no user accounts, no sessions, and no database layer. Authentication endpoints are not registered.