Deployed b10fd2d3 with MkDocs version: 1.6.1

This commit is contained in:
2026-11-09 22:44:09 +00:00
parent ced0d14f36
commit 90ff59f608
5 changed files with 46 additions and 5 deletions
+31
View File
@@ -2670,6 +2670,33 @@ seconds:</p>
<code>GET /api/health</code> is never limited. See
<a href="../dashboard/#rate-limits">dashboard rate limits</a> for the config and the counters, and
<a href="../../../reference/configuration/services/">services configuration</a> for the keys themselves.</p>
<p>Every response to an API key that has a limit carries these headers, the <code>429</code> too. A
WebSocket or event stream response sends its headers before the handler returns, so it has none.
The CORS headers expose these headers and <code>Retry-After</code> to a browser client.</p>
<table>
<thead>
<tr>
<th>Header</th>
<th>Value</th>
</tr>
</thead>
<tbody>
<tr>
<td><code>X-RateLimit-Limit</code></td>
<td>Requests per hour that the API key may make.</td>
</tr>
<tr>
<td><code>X-RateLimit-Remaining</code></td>
<td>Requests left in the current window.</td>
</tr>
<tr>
<td><code>X-RateLimit-Reset</code></td>
<td>Seconds until the window resets.</td>
</tr>
</tbody>
</table>
<p>A <code>--remote</code> client that gets a <code>429</code> with <code>Retry-After</code> shows a countdown, waits that time
(one hour at most), and then sends the request again. It stops after 3 waits for one request.</p>
<div class="admonition warning">
<p class="admonition-title"><code>429</code> is not the <code>RATE_LIMITED</code> error body</p>
<p><code>RATE_LIMITED</code> in <a href="../errors/">Errors</a> is a <em>service</em> rate limit that a handler raises, and it
@@ -2808,6 +2835,10 @@ that reads <code>error_code</code> to classify a <code>429</code> must cope with
<td><code>{"status": 429, "message": "Rate limit exceeded."}</code>, plus a <code>Retry-After</code> header</td>
</tr>
<tr>
<td>Rate limit headers</td>
<td><code>X-RateLimit-Limit</code>, <code>X-RateLimit-Remaining</code>, <code>X-RateLimit-Reset</code> on each response to a limited API key</td>
</tr>
<tr>
<td>Rate limit config</td>
<td><code>serve.tiers.&lt;name&gt;.rate_limit</code>, overridden by <code>serve.users.&lt;key&gt;.rate_limit</code></td>
</tr>
+1 -1
View File
@@ -2893,7 +2893,7 @@ from a browser origin, not when you want only the local HTTP API.</p>
<tr>
<td><code>GET</code></td>
<td><code>/api/tunnel</code></td>
<td>WebSocket that relays the connections of a <code>tunnel:&lt;id&gt;</code> proxy to the client; <code>?id=</code> reconnects</td>
<td>WebSocket that relays the connections of a <code>tunnel:&lt;id&gt;</code> proxy to the client; <code>?id=</code> reconnects, close code 1000 frees the tunnel at once</td>
</tr>
<tr>
<td><code>GET</code></td>
+4 -2
View File
@@ -3075,8 +3075,10 @@ tunnel: the client downloads them as before.</p>
logs in with its own account. If the tunnel drops, the client connects again, and a new request
from the server waits up to 10 seconds for it. A request that was in progress when the tunnel
dropped fails. The server closes a tunnel when its client has not connected for 60 seconds, and
the client then stops with <code>The tunnel to the server closed</code>. An API key can have 4 tunnels
open at once.</p>
the client then stops with <code>The tunnel to the server closed</code>. A client that exits closes its
tunnel at once. An API key can have 4 tunnels open at once (4 for each person on a key with
<code>shared: true</code>, see <a href="../../reference/configuration/services/">services configuration</a>). A fifth run waits for a free
tunnel and tries again every 15 seconds, for one hour at most.</p>
<h2 id="basic-static-proxies">Basic (static proxies)<a class="headerlink" href="#basic-static-proxies" title="Permanent link">&para;</a></h2>
<p>The <code>Basic</code> proxy provider is pure static configuration, with no accounts and no network
calls. You record proxy URLs under each country code, and unshackle serves them back
+9 -1
View File
@@ -2414,10 +2414,16 @@ hold goes back to the client's device. When the service runs the remote session
own device (a service option, such as a server-identity flag), the client's own vaults, and the
server vault with this grant, are the only source, and a missing content key stops the download.</p>
<p><code>admin</code> is a boolean that lets the API key run the maintenance endpoints (clear-cache, clear-temp, refresh-services). It is <code>false</code> unless the entry sets it. Keys that have no <code>users</code> entry, such as <code>api_secret</code>, keep that access.</p>
<p><code>shared</code> is a boolean for an API key that a gateway in front of the server gives to many people.
The gateway puts its own ID for each person in the <code>X-Client-Id</code> header, and the server then
counts the <code>--local-proxy</code> tunnels of that API key for each person. Without <code>shared: true</code> the
server ignores the header, because a client that connects to the server directly can set any
value. Set it only when the gateway always replaces the header that the client sends.</p>
<p>A <code>tier</code> names an entry under <code>serve.tiers</code>, which holds the settings that several API keys
share. Today a tier carries <code>rate_limit</code>, the requests per hour that API key may make; an API
key can also set its own <code>rate_limit</code>, which wins over its tier's. An API key with neither has
no limit. Going over the limit answers <code>429</code> with a <code>Retry-After</code> header. The server keeps a
no limit. Going over the limit answers <code>429</code> with a <code>Retry-After</code> header, and a <code>--remote</code>
client waits that time before it tries again. The server keeps a
fixed window rather than a sliding one: it opens on the first request and resets an hour
later. A <code>tier</code> that names no entry under <code>serve.tiers</code>, or a <code>rate_limit</code> that is not a
positive whole number, stops the server at startup, because the alternative is an API key that
@@ -2504,6 +2510,8 @@ own config.</p>
</span><span id="__span-4-23"><a id="__codelineno-4-23" name="__codelineno-4-23" href="#__codelineno-4-23"></a><span class="w"> </span><span class="nt">f3a4b5c6</span><span class="p">:</span>
</span><span id="__span-4-24"><a id="__codelineno-4-24" name="__codelineno-4-24" href="#__codelineno-4-24"></a><span class="w"> </span><span class="nt">services</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">EXAMPLE1</span><span class="p p-Indicator">]</span>
</span><span id="__span-4-25"><a id="__codelineno-4-25" name="__codelineno-4-25" href="#__codelineno-4-25"></a><span class="w"> </span><span class="nt">server_vault</span><span class="p">:</span><span class="w"> </span><span class="p p-Indicator">[</span><span class="nv">EXAMPLE1</span><span class="p p-Indicator">]</span><span class="w"> </span><span class="c1"># the client's device licenses; the server vault still serves keys</span>
</span><span id="__span-4-26"><a id="__codelineno-4-26" name="__codelineno-4-26" href="#__codelineno-4-26"></a><span class="w"> </span><span class="nt">d7e8f9a0</span><span class="p">:</span>
</span><span id="__span-4-27"><a id="__codelineno-4-27" name="__codelineno-4-27" href="#__codelineno-4-27"></a><span class="w"> </span><span class="nt">shared</span><span class="p">:</span><span class="w"> </span><span class="l l-Scalar l-Scalar-Plain">true</span><span class="w"> </span><span class="c1"># a gateway gives this key to many people; tunnels count per X-Client-Id</span>
</span></code></pre></div>
<div class="admonition note">
<p class="admonition-title"><code>dl</code> keys inside <code>serve</code></p>
File diff suppressed because one or more lines are too long