| <!DOCTYPE html> |
| <html lang="en"> |
| <head> |
| <meta charset="UTF-8" /> |
| <meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
| <meta name="theme-color" content="#FFD6E8" /> |
| |
| |
| |
| |
| |
| <style> |
| html{background:linear-gradient(180deg,#E8E0FF 0%,#FFD6E8 52%,#FFE5D9 100%) fixed;background-color:#FFD6E8;} |
| </style> |
| <title>Docs — DreamRouter</title> |
| <meta name="description" content="DreamRouter API reference: authenticate, list models, send chat completions, stream responses, and handle errors across one OpenAI-compatible endpoint." /> |
| <link rel="canonical" href="https://apiarium-labs.hf.space/docs.html" /> |
| <meta property="og:type" content="website" /> |
| <meta property="og:title" content="DreamRouter Docs" /> |
| <meta property="og:description" content="One OpenAI-compatible endpoint. Auth, models, chat, streaming, errors." /> |
|
|
| <link rel="preconnect" href="https://fonts.googleapis.com" /> |
| <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin /> |
| <link href="https://fonts.googleapis.com/css2?family=Comfortaa:wght@400;500;700&family=Nunito:wght@400;600;700;800&family=JetBrains+Mono:wght@400;600&display=swap" rel="stylesheet" /> |
| <script src="https://unpkg.com/lenis@1.1.13/dist/lenis.min.js" defer></script> |
|
|
| <link rel="stylesheet" href="css/tokens.css?v=20260620b" /> |
| <link rel="stylesheet" href="css/base.css?v=20260620b" /> |
| <link rel="stylesheet" href="css/scene.css?v=20260620b" /> |
| <link rel="stylesheet" href="css/nav.css?v=20260620b" /> |
| <link rel="stylesheet" href="css/sections.css?v=20260620b" /> |
| <link rel="stylesheet" href="css/docs.css?v=20260620b" /> |
| </head> |
|
|
| <body data-page="docs"> |
|
|
| |
| <div class="blur-overlay" aria-hidden="true"></div> |
| <div class="grain-overlay" aria-hidden="true"></div> |
|
|
| |
| <div class="scene" aria-hidden="true"> |
| <div class="layer layer-far-clouds" data-speed="0.06" data-mouse="6"> |
| <svg class="cloud-far c1" viewBox="0 0 200 100"><use href="#cloud"/></svg> |
| <svg class="cloud-far c3" viewBox="0 0 200 100"><use href="#cloud"/></svg> |
| </div> |
| <div class="layer layer-moon" data-speed="0.10" data-mouse="10"> |
| <div class="moon"><span class="moon-disc"></span></div> |
| </div> |
| </div> |
|
|
| |
| <div data-site-nav></div> |
|
|
| <main id="main"> |
|
|
| <header class="doc-hero"> |
| <div class="container"> |
| <h1 data-split>docs</h1> |
| <p data-reveal>One OpenAI-compatible endpoint. Authenticate, send a request, stream the reply.</p> |
| </div> |
| </header> |
|
|
| <div class="container"> |
| <div class="doc-layout"> |
|
|
| |
| <aside class="doc-toc" aria-label="On this page"> |
| <h2>On this page</h2> |
| <ul> |
| <li><a href="#quickstart">Quickstart</a></li> |
| <li><a href="#auth">Authentication</a></li> |
| <li><a href="#base-url">Base URL</a></li> |
| <li><a href="#models">List models</a></li> |
| <li><a href="#chat">Chat completions</a></li> |
| <li><a href="#streaming">Streaming</a></li> |
| <li><a href="#parameters">Parameters</a></li> |
| <li><a href="#errors">Errors</a></li> |
| <li><a href="#retries">Retries & limits</a></li> |
| </ul> |
| </aside> |
|
|
| |
| <div class="doc-content"> |
|
|
| <section id="quickstart"> |
| <h2>Quickstart</h2> |
| <p data-reveal>Send a standard OpenAI-style chat completion. Swap the base URL and the model name — that's the whole integration.</p> |
|
|
| <div class="bezel" data-code-tabs> |
| <div class="code-tabs" role="tablist"> |
| <button data-tab="curl" aria-selected="true">cURL</button> |
| <button data-tab="py" aria-selected="false">Python</button> |
| <button data-tab="js" aria-selected="false">JavaScript</button> |
| </div> |
| <div class="code-wrap"> |
| <pre class="code-panel" data-tab="curl" data-active="true"><span class="tok-com"># one endpoint, every model</span> |
| curl https://apiarium-labs.hf.space/v1/chat/completions \ |
| -H <span class="tok-str">"Authorization: Bearer $DREAMROUTER_KEY"</span> \ |
| -H <span class="tok-str">"Content-Type: application/json"</span> \ |
| -d <span class="tok-str">'{ |
| "model": "claude-opus-4.8", |
| "messages": [{"role":"user","content":"Hello, whale."}] |
| }'</span></pre> |
| <pre class="code-panel" data-tab="py"><span class="tok-key">from</span> openai <span class="tok-key">import</span> OpenAI |
|
|
| client = OpenAI( |
| base_url=<span class="tok-str">"https://apiarium-labs.hf.space/v1"</span>, |
| api_key=<span class="tok-str">"dr_u_..."</span>, <span class="tok-com"># your personal key from the dashboard</span> |
| ) |
|
|
| resp = client.chat.completions.create( |
| model=<span class="tok-str">"claude-opus-4.8"</span>, |
| messages=[{<span class="tok-str">"role"</span>: <span class="tok-str">"user"</span>, <span class="tok-str">"content"</span>: <span class="tok-str">"Hello, whale."</span>}], |
| ) |
| <span class="tok-key">print</span>(resp.choices[<span class="tok-num">0</span>].message.content)</pre> |
| <pre class="code-panel" data-tab="js"><span class="tok-key">import</span> OpenAI <span class="tok-key">from</span> <span class="tok-str">"openai"</span>; |
|
|
| <span class="tok-key">const</span> client = <span class="tok-key">new</span> OpenAI({ |
| baseURL: <span class="tok-str">"https://apiarium-labs.hf.space/v1"</span>, |
| apiKey: <span class="tok-str">"dr_u_..."</span>, <span class="tok-com">// your personal key from the dashboard</span> |
| }); |
|
|
| <span class="tok-key">const</span> resp = <span class="tok-key">await</span> client.chat.completions.create({ |
| model: <span class="tok-str">"claude-opus-4.8"</span>, |
| messages: [{ role: <span class="tok-str">"user"</span>, content: <span class="tok-str">"Hello, whale."</span> }], |
| }); |
| console.log(resp.choices[<span class="tok-num">0</span>].message.content);</pre> |
| </div> |
| </div> |
|
|
| <div class="callout note"> |
| <span class="ico">i</span> |
| <div>The router rewrites your model name to each target's upstream id automatically. You send one name; it resolves to a healthy pool behind the scenes. <a href="models.html">Browse the 374 available models →</a></div> |
| </div> |
| </section> |
|
|
| <section id="auth"> |
| <h2>Authentication</h2> |
| <p data-reveal>Proxy endpoints require a Bearer token in the <code>Authorization</code> header.</p> |
| <pre class="code-panel" style="background:var(--ink);padding:1rem 1.2rem;border-radius:14px;"><span class="tok-key">Authorization</span>: Bearer sk-your-DreamRouter-key</pre> |
| <div class="callout warn"> |
| <span class="ico">!</span> |
| <div>Public endpoints (<code>/</code>, <code>/health</code>, <code>/v1/models</code>) need no auth. Everything else returns <code>403</code> without a valid key. An optional IP allowlist can further lock access.</div> |
| </div> |
| </section> |
|
|
| <section id="base-url"> |
| <h2>Base URL</h2> |
| <p data-reveal>All requests are made against:</p> |
| <pre class="code-panel" style="background:var(--ink);padding:1rem 1.2rem;border-radius:14px;">https://apiarium-labs.hf.space/v1</pre> |
| <p>Point any OpenAI-compatible client at this base URL and you are done.</p> |
| </section> |
|
|
| <section id="models"> |
| <h2>List models</h2> |
| <p data-reveal><code>GET /v1/models</code> returns every model the router can resolve. Public, no auth required.</p> |
| <div class="bezel" data-code-tabs> |
| <div class="code-tabs" role="tablist"> |
| <button data-tab="curl" aria-selected="true">cURL</button> |
| <button data-tab="resp" aria-selected="false">Response</button> |
| </div> |
| <div class="code-wrap"> |
| <pre class="code-panel" data-tab="curl" data-active="true">curl https://apiarium-labs.hf.space/v1/models</pre> |
| <pre class="code-panel" data-tab="resp">{ |
| <span class="tok-key">"object"</span>: <span class="tok-str">"list"</span>, |
| <span class="tok-key">"data"</span>: [ |
| { <span class="tok-key">"id"</span>: <span class="tok-str">"claude-opus-4.8"</span>, <span class="tok-key">"object"</span>: <span class="tok-str">"model"</span>, <span class="tok-key">"owned_by"</span>: <span class="tok-str">"claude-subnet"</span> }, |
| { <span class="tok-key">"id"</span>: <span class="tok-str">"deepseek-v4-pro"</span>, <span class="tok-key">"object"</span>: <span class="tok-str">"model"</span>, <span class="tok-key">"owned_by"</span>: <span class="tok-str">"deepseek"</span> } |
| <span class="tok-com">// ...374 models</span> |
| ] |
| }</pre> |
| </div> |
| </div> |
| </section> |
|
|
| <section id="chat"> |
| <h2>Chat completions</h2> |
| <p data-reveal><code>POST /v1/chat/completions</code> accepts the standard OpenAI request body. The <code>model</code> field selects the pool; everything else passes through.</p> |
| <table class="doc-table"> |
| <thead><tr><th>Field</th><th>Type</th><th>Notes</th></tr></thead> |
| <tbody> |
| <tr><td><code>model</code></td><td>string</td><td>Required. Any name from <code>/v1/models</code>.</td></tr> |
| <tr><td><code>messages</code></td><td>array</td><td>OpenAI message format.</td></tr> |
| <tr><td><code>stream</code></td><td>boolean</td><td>SSE stream when <code>true</code>.</td></tr> |
| <tr><td><code>temperature</code></td><td>number</td><td>Forwarded upstream.</td></tr> |
| <tr><td><code>max_tokens</code></td><td>number</td><td>Forwarded. GPT-5.x maps to <code>max_completion_tokens</code> automatically.</td></tr> |
| <tr><td><code>tools</code></td><td>array</td><td>Tool/function calling supported where the upstream allows it.</td></tr> |
| </tbody> |
| </table> |
| </section> |
|
|
| <section id="streaming"> |
| <h2>Streaming</h2> |
| <p data-reveal>Set <code>"stream": true</code>. The router forwards the upstream SSE stream and filters non-<code>data:</code> lines so strict parsers stay happy. Each chunk is a standard <code>chat.completion.chunk</code>.</p> |
| <div class="bezel"> |
| <div class="code-wrap"> |
| <pre class="code-panel" data-active="true" style="display:block;">data: {<span class="tok-key">"choices"</span>:[{<span class="tok-key">"delta"</span>:{<span class="tok-key">"content"</span>:<span class="tok-str">"Hello"</span>}}]} |
|
|
| data: {<span class="tok-key">"choices"</span>:[{<span class="tok-key">"delta"</span>:{<span class="tok-key">"content"</span>:<span class="tok-str">", whale."</span>}}]} |
|
|
| data: [DONE]</pre> |
| </div> |
| </div> |
| </section> |
|
|
| <section id="parameters"> |
| <h2>Parameters</h2> |
| <p data-reveal>Unsupported parameters are silently dropped before forwarding. The router never invents upstream behavior — it only translates model names and injects keys.</p> |
| </section> |
|
|
| <section id="errors"> |
| <h2>Errors</h2> |
| <table class="doc-table"> |
| <thead><tr><th>Status</th><th>Meaning</th></tr></thead> |
| <tbody> |
| <tr><td><code>401</code></td><td>Missing or invalid bearer token.</td></tr> |
| <tr><td><code>403</code></td><td>Endpoint blocked, or IP not on the allowlist.</td></tr> |
| <tr><td><code>404</code></td><td>Model not found. Returned before any upstream call.</td></tr> |
| <tr><td><code>429</code></td><td>All targets rate-limited after retries.</td></tr> |
| <tr><td><code>502</code></td><td>Every target in the pool failed its attempts.</td></tr> |
| <tr><td><code>503</code></td><td>Pool exhausted — every target cooling down.</td></tr> |
| </tbody> |
| </table> |
| </section> |
|
|
| <section id="retries"> |
| <h2>Retries & limits</h2> |
| <p data-reveal>Each request gets up to <strong>five attempts</strong>. On <code>401</code>, <code>402</code>, <code>403</code>, <code>429</code>, or <code>5xx</code>, the failing target cools for <strong>sixty seconds</strong> and the router tries the next healthy one. Cooldowns are idempotent — re-failing a target never resets its timer, so flapping endpoints recover cleanly.</p> |
| <div class="callout note"> |
| <span class="ico">↻</span> |
| <div>Load is spread by a thread-safe round-robin cursor, so traffic distributes evenly across the whole pool — not hammering the first target.</div> |
| </div> |
| </section> |
|
|
| </div> |
| </div> |
| </div> |
|
|
| <div data-site-footer></div> |
| </main> |
|
|
| |
| <svg width="0" height="0" style="position:absolute" aria-hidden="true"> |
| <symbol id="cloud" viewBox="0 0 200 100"> |
| <path fill="currentColor" d="M44,82 C24,82 18,58 38,53 C32,32 62,26 74,42 C80,22 116,22 122,44 C142,32 168,48 158,68 C172,72 172,90 152,90 L54,90 C40,92 35,88 44,82 Z" /> |
| </symbol> |
| </svg> |
|
|
| <script src="js/layout.js?v=20260620b"></script> |
| <script src="js/motion.js?v=20260620b"></script> |
| <script src="js/parallax.js?v=20260620b"></script> |
| <script src="js/docs.js?v=20260620b"></script> |
| </body> |
| </html> |
|
|