[{"data":1,"prerenderedAt":4761},["ShallowReactive",2],{"docs-all":3,"\u002Fdocs\u002Fconcepts":4568},[4,948,1503,1755,1959,2419,2941,3209,3730,3902,4221],{"id":5,"title":6,"body":7,"description":939,"extension":940,"meta":941,"navigation":942,"path":944,"seo":945,"stem":946,"__hash__":947},"docs\u002Fdocs\u002Fapi-reference.md","API reference — Proxy management and inference",{"type":8,"value":9,"toc":925},"minimark",[10,15,19,36,39,66,69,72,79,86,93,96,194,242,248,251,328,334,340,343,385,391,394,455,460,466,532,538,541,571,575,609,761,763,767,787,793,821,823,827,914,921],[11,12,14],"h1",{"id":13},"api-reference","API reference",[16,17,18],"p",{},"Base URLs:",[20,21,22,30],"ul",{},[23,24,25,26],"li",{},"Site: ",[27,28,29],"code",{},"https:\u002F\u002Fklunqlabs.com",[23,31,32,33],{},"Proxy: ",[27,34,35],{},"https:\u002F\u002Fproxy.klunqlabs.com",[16,37,38],{},"Auth model:",[20,40,41,58],{},[23,42,43,47,48,51,52,57],{},[44,45,46],"strong",{},"Management key"," (",[27,49,50],{},"sk-…"," from dashboard) — can manage your ",[53,54,56],"abbr",{"title":55},"virtual keys","v-keys"," and read your usage.",[23,59,60,47,63,65],{},[44,61,62],{},"v-key",[27,64,50],{}," minted via management key) — inference only, cannot call management.",[16,67,68],{},"The proxy is LiteLLM-based with custom hooks and guardrails, so the management key exposes only the documented subset below — not the full upstream LiteLLM surface. Production does not expose Swagger.",[70,71],"hr",{},[73,74,76,77],"h2",{"id":75},"management-v-keys","Management — ",[53,78,56],{"title":55},[16,80,81,82,85],{},"All following require ",[27,83,84],{},"Authorization: Bearer $TEAM_MGMT_KEY"," (the team management key from the dashboard).",[87,88,90],"h3",{"id":89},"post-keygenerate",[27,91,92],{},"POST \u002Fkey\u002Fgenerate",[16,94,95],{},"Create a disposable v-key.",[97,98,103],"pre",{"className":99,"code":100,"language":101,"meta":102,"style":102},"language-bash shiki shiki-themes material-theme-lighter github-light github-dark","curl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"vkey-landing\",\"models\":[\"gemma4\"],\"max_budget\":2,\"budget_duration\":\"30d\",\"rpm_limit\":100,\"tpm_limit\":10000}'\n# 200 { \"key\":\"sk-…\", \"token_id\":\"…\", \"max_budget\":2, ... }\n","bash","",[27,104,105,140,158,172,187],{"__ignoreMap":102},[106,107,110,114,118,122,126,130,133,136],"span",{"class":108,"line":109},"line",1,[106,111,113],{"class":112},"sbgvK","curl",[106,115,117],{"class":116},"stzsN"," -X",[106,119,121],{"class":120},"s_sjI"," POST",[106,123,125],{"class":124},"sjJ54"," \"",[106,127,129],{"class":128},"su5hD","$PROXY_URL",[106,131,132],{"class":120},"\u002Fkey\u002Fgenerate",[106,134,135],{"class":124},"\"",[106,137,139],{"class":138},"s_hVV"," \\\n",[106,141,143,146,148,151,154,156],{"class":108,"line":142},2,[106,144,145],{"class":116},"  -H",[106,147,125],{"class":124},[106,149,150],{"class":120},"Authorization: Bearer ",[106,152,153],{"class":128},"$TEAM_MGMT_KEY",[106,155,135],{"class":124},[106,157,139],{"class":138},[106,159,161,163,165,168,170],{"class":108,"line":160},3,[106,162,145],{"class":116},[106,164,125],{"class":124},[106,166,167],{"class":120},"Content-Type: application\u002Fjson",[106,169,135],{"class":124},[106,171,139],{"class":138},[106,173,175,178,181,184],{"class":108,"line":174},4,[106,176,177],{"class":116},"  -d",[106,179,180],{"class":124}," '",[106,182,183],{"class":120},"{\"key_alias\":\"vkey-landing\",\"models\":[\"gemma4\"],\"max_budget\":2,\"budget_duration\":\"30d\",\"rpm_limit\":100,\"tpm_limit\":10000}",[106,185,186],{"class":124},"'\n",[106,188,190],{"class":108,"line":189},5,[106,191,193],{"class":192},"sutJx","# 200 { \"key\":\"sk-…\", \"token_id\":\"…\", \"max_budget\":2, ... }\n",[16,195,196,197,200,201,204,205,208,209,204,212,47,215,218,219,218,222,225,226,204,229,204,232,204,235,218,238,241],{},"Fields: ",[27,198,199],{},"key_alias"," ",[44,202,203],{},"required",", ",[27,206,207],{},"models"," (array, empty = all curated models), ",[27,210,211],{},"max_budget",[27,213,214],{},"budget_duration",[27,216,217],{},"30d","\u002F",[27,220,221],{},"1d",[27,223,224],{},"1h","), ",[27,227,228],{},"rpm_limit",[27,230,231],{},"tpm_limit",[27,233,234],{},"max_parallel_requests",[27,236,237],{},"expires",[27,239,240],{},"duration",".",[87,243,245],{"id":244},"get-keylist",[27,246,247],{},"GET \u002Fkey\u002Flist",[16,249,250],{},"List keys for your team.",[97,252,254],{"className":99,"code":253,"language":101,"meta":102,"style":102},"curl -G \"$PROXY_URL\u002Fkey\u002Flist\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\"\n# → { \"keys\": [...], \"total_count\": 42, \"total_pages\": 5, \"current_page\": 1 }\n# Filter exact alias:\ncurl -G \"$PROXY_URL\u002Fkey\u002Flist\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" --data-urlencode \"key_alias=vkey-landing\"\n",[27,255,256,284,289,294],{"__ignoreMap":102},[106,257,258,260,263,265,267,270,272,275,277,279,281],{"class":108,"line":109},[106,259,113],{"class":112},[106,261,262],{"class":116}," -G",[106,264,125],{"class":124},[106,266,129],{"class":128},[106,268,269],{"class":120},"\u002Fkey\u002Flist",[106,271,135],{"class":124},[106,273,274],{"class":116}," -H",[106,276,125],{"class":124},[106,278,150],{"class":120},[106,280,153],{"class":128},[106,282,283],{"class":124},"\"\n",[106,285,286],{"class":108,"line":142},[106,287,288],{"class":192},"# → { \"keys\": [...], \"total_count\": 42, \"total_pages\": 5, \"current_page\": 1 }\n",[106,290,291],{"class":108,"line":160},[106,292,293],{"class":192},"# Filter exact alias:\n",[106,295,296,298,300,302,304,306,308,310,312,314,316,318,321,323,326],{"class":108,"line":174},[106,297,113],{"class":112},[106,299,262],{"class":116},[106,301,125],{"class":124},[106,303,129],{"class":128},[106,305,269],{"class":120},[106,307,135],{"class":124},[106,309,274],{"class":116},[106,311,125],{"class":124},[106,313,150],{"class":120},[106,315,153],{"class":128},[106,317,135],{"class":124},[106,319,320],{"class":116}," --data-urlencode",[106,322,125],{"class":124},[106,324,325],{"class":120},"key_alias=vkey-landing",[106,327,283],{"class":124},[16,329,330,331,333],{},"Exact ",[27,332,199],{}," search is case-sensitive (dashboard search).",[87,335,337],{"id":336},"get-keyinfokeysk",[27,338,339],{},"GET \u002Fkey\u002Finfo?key={sk-…}",[16,341,342],{},"Inspect a key.",[97,344,346],{"className":99,"code":345,"language":101,"meta":102,"style":102},"curl -G \"$PROXY_URL\u002Fkey\u002Finfo\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" --data-urlencode \"key=$VKEY\"\n",[27,347,348],{"__ignoreMap":102},[106,349,350,352,354,356,358,361,363,365,367,369,371,373,375,377,380,383],{"class":108,"line":109},[106,351,113],{"class":112},[106,353,262],{"class":116},[106,355,125],{"class":124},[106,357,129],{"class":128},[106,359,360],{"class":120},"\u002Fkey\u002Finfo",[106,362,135],{"class":124},[106,364,274],{"class":116},[106,366,125],{"class":124},[106,368,150],{"class":120},[106,370,153],{"class":128},[106,372,135],{"class":124},[106,374,320],{"class":116},[106,376,125],{"class":124},[106,378,379],{"class":120},"key=",[106,381,382],{"class":128},"$VKEY",[106,384,283],{"class":124},[87,386,388],{"id":387},"post-keyupdate",[27,389,390],{},"POST \u002Fkey\u002Fupdate",[16,392,393],{},"Update alias, budget or limits.",[97,395,397],{"className":99,"code":396,"language":101,"meta":102,"style":102},"curl -X POST \"$PROXY_URL\u002Fkey\u002Fupdate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key\":\"sk-…\",\"key_alias\":\"vkey-renamed\",\"max_budget\":5}'\n",[27,398,399,418,432,444],{"__ignoreMap":102},[106,400,401,403,405,407,409,411,414,416],{"class":108,"line":109},[106,402,113],{"class":112},[106,404,117],{"class":116},[106,406,121],{"class":120},[106,408,125],{"class":124},[106,410,129],{"class":128},[106,412,413],{"class":120},"\u002Fkey\u002Fupdate",[106,415,135],{"class":124},[106,417,139],{"class":138},[106,419,420,422,424,426,428,430],{"class":108,"line":142},[106,421,145],{"class":116},[106,423,125],{"class":124},[106,425,150],{"class":120},[106,427,153],{"class":128},[106,429,135],{"class":124},[106,431,139],{"class":138},[106,433,434,436,438,440,442],{"class":108,"line":160},[106,435,145],{"class":116},[106,437,125],{"class":124},[106,439,167],{"class":120},[106,441,135],{"class":124},[106,443,139],{"class":138},[106,445,446,448,450,453],{"class":108,"line":174},[106,447,177],{"class":116},[106,449,180],{"class":124},[106,451,452],{"class":120},"{\"key\":\"sk-…\",\"key_alias\":\"vkey-renamed\",\"max_budget\":5}",[106,454,186],{"class":124},[16,456,457,459],{},[27,458,199],{}," cannot be cleared to empty.",[87,461,463],{"id":462},"post-keydelete",[27,464,465],{},"POST \u002Fkey\u002Fdelete",[97,467,469],{"className":99,"code":468,"language":101,"meta":102,"style":102},"curl -X POST \"$PROXY_URL\u002Fkey\u002Fdelete\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"keys\":[\"sk-…\"]}'\n# subsequent GET \u002Fkey\u002Finfo?key=sk-… → 404\n",[27,470,471,490,504,516,527],{"__ignoreMap":102},[106,472,473,475,477,479,481,483,486,488],{"class":108,"line":109},[106,474,113],{"class":112},[106,476,117],{"class":116},[106,478,121],{"class":120},[106,480,125],{"class":124},[106,482,129],{"class":128},[106,484,485],{"class":120},"\u002Fkey\u002Fdelete",[106,487,135],{"class":124},[106,489,139],{"class":138},[106,491,492,494,496,498,500,502],{"class":108,"line":142},[106,493,145],{"class":116},[106,495,125],{"class":124},[106,497,150],{"class":120},[106,499,153],{"class":128},[106,501,135],{"class":124},[106,503,139],{"class":138},[106,505,506,508,510,512,514],{"class":108,"line":160},[106,507,145],{"class":116},[106,509,125],{"class":124},[106,511,167],{"class":120},[106,513,135],{"class":124},[106,515,139],{"class":138},[106,517,518,520,522,525],{"class":108,"line":174},[106,519,177],{"class":116},[106,521,180],{"class":124},[106,523,524],{"class":120},"{\"keys\":[\"sk-…\"]}",[106,526,186],{"class":124},[106,528,529],{"class":108,"line":189},[106,530,531],{"class":192},"# subsequent GET \u002Fkey\u002Finfo?key=sk-… → 404\n",[87,533,535],{"id":534},"get-teaminfo",[27,536,537],{},"GET \u002Fteam\u002Finfo",[16,539,540],{},"Read your team.",[97,542,544],{"className":99,"code":543,"language":101,"meta":102,"style":102},"curl -G \"$PROXY_URL\u002Fteam\u002Finfo\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\"\n",[27,545,546],{"__ignoreMap":102},[106,547,548,550,552,554,556,559,561,563,565,567,569],{"class":108,"line":109},[106,549,113],{"class":112},[106,551,262],{"class":116},[106,553,125],{"class":124},[106,555,129],{"class":128},[106,557,558],{"class":120},"\u002Fteam\u002Finfo",[106,560,135],{"class":124},[106,562,274],{"class":116},[106,564,125],{"class":124},[106,566,150],{"class":120},[106,568,153],{"class":128},[106,570,283],{"class":124},[87,572,574],{"id":573},"spend-team-scoped","Spend — team-scoped",[20,576,577,583,593,599],{},[23,578,579,582],{},[27,580,581],{},"GET \u002Fteam\u002Fdaily\u002Factivity?start_date=YYYY-MM-DD&end_date=YYYY-MM-DD"," — aggregated per day\u002Fmodel\u002Fkey. Without params auto-scoped to your team.",[23,584,585,588,589,592],{},[27,586,587],{},"GET \u002Fspend\u002Flogs\u002Fv2?start_date&end_date&page&page_size"," — per-request logs ",[27,590,591],{},"[{request_id, model, spend, total_tokens, startTime}]",", auto-scoped to your team.",[23,594,595,598],{},[27,596,597],{},"GET \u002Fspend\u002Flogs?start_date&end_date"," — deprecated aggregated variant.",[23,600,601,604,605,608],{},[27,602,603],{},"POST \u002Fspend\u002Fcalculate {\"model\":\"gemma4\",\"messages\":[...],\"max_tokens\":10}"," → ",[27,606,607],{},"{\"cost\":0.0}"," estimator.",[97,610,612],{"className":99,"code":611,"language":101,"meta":102,"style":102},"curl -G \"$PROXY_URL\u002Fteam\u002Fdaily\u002Factivity\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  --data-urlencode \"start_date=2025-01-01\" --data-urlencode \"end_date=2026-12-31\"\ncurl -G \"$PROXY_URL\u002Fspend\u002Flogs\u002Fv2\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  --data-urlencode \"start_date=2025-01-01\" --data-urlencode \"end_date=2026-12-31\"\ncurl -X POST \"$PROXY_URL\u002Fspend\u002Fcalculate\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":10}'\n",[27,613,614,641,662,689,707,736,749],{"__ignoreMap":102},[106,615,616,618,620,622,624,627,629,631,633,635,637,639],{"class":108,"line":109},[106,617,113],{"class":112},[106,619,262],{"class":116},[106,621,125],{"class":124},[106,623,129],{"class":128},[106,625,626],{"class":120},"\u002Fteam\u002Fdaily\u002Factivity",[106,628,135],{"class":124},[106,630,274],{"class":116},[106,632,125],{"class":124},[106,634,150],{"class":120},[106,636,153],{"class":128},[106,638,135],{"class":124},[106,640,139],{"class":138},[106,642,643,646,648,651,653,655,657,660],{"class":108,"line":142},[106,644,645],{"class":116},"  --data-urlencode",[106,647,125],{"class":124},[106,649,650],{"class":120},"start_date=2025-01-01",[106,652,135],{"class":124},[106,654,320],{"class":116},[106,656,125],{"class":124},[106,658,659],{"class":120},"end_date=2026-12-31",[106,661,283],{"class":124},[106,663,664,666,668,670,672,675,677,679,681,683,685,687],{"class":108,"line":160},[106,665,113],{"class":112},[106,667,262],{"class":116},[106,669,125],{"class":124},[106,671,129],{"class":128},[106,673,674],{"class":120},"\u002Fspend\u002Flogs\u002Fv2",[106,676,135],{"class":124},[106,678,274],{"class":116},[106,680,125],{"class":124},[106,682,150],{"class":120},[106,684,153],{"class":128},[106,686,135],{"class":124},[106,688,139],{"class":138},[106,690,691,693,695,697,699,701,703,705],{"class":108,"line":174},[106,692,645],{"class":116},[106,694,125],{"class":124},[106,696,650],{"class":120},[106,698,135],{"class":124},[106,700,320],{"class":116},[106,702,125],{"class":124},[106,704,659],{"class":120},[106,706,283],{"class":124},[106,708,709,711,713,715,717,719,722,724,726,728,730,732,734],{"class":108,"line":189},[106,710,113],{"class":112},[106,712,117],{"class":116},[106,714,121],{"class":120},[106,716,125],{"class":124},[106,718,129],{"class":128},[106,720,721],{"class":120},"\u002Fspend\u002Fcalculate",[106,723,135],{"class":124},[106,725,274],{"class":116},[106,727,125],{"class":124},[106,729,150],{"class":120},[106,731,153],{"class":128},[106,733,135],{"class":124},[106,735,139],{"class":138},[106,737,739,741,743,745,747],{"class":108,"line":738},6,[106,740,145],{"class":116},[106,742,125],{"class":124},[106,744,167],{"class":120},[106,746,135],{"class":124},[106,748,139],{"class":138},[106,750,752,754,756,759],{"class":108,"line":751},7,[106,753,177],{"class":116},[106,755,180],{"class":124},[106,757,758],{"class":120},"{\"model\":\"gemma4\",\"messages\":[{\"role\":\"user\",\"content\":\"hi\"}],\"max_tokens\":10}",[106,760,186],{"class":124},[70,762],{},[73,764,766],{"id":765},"inference-with-a-v-key-widget-only","Inference — with a v-key (widget-only)",[16,768,769,770,772,773,776,777,780,781,786],{},"The proxy is OpenAI-compatible, but today it only accepts the Klunq Widget’s watermarked prompts. A ",[27,771,62],{}," alone is not enough — every ",[27,774,775],{},"POST \u002Fv1\u002Fchat\u002Fcompletions"," must carry the widget’s page-locked system prompt, otherwise the proxy returns ",[27,778,779],{},"400 Guardrail Violation"," (see ",[782,783,785],"a",{"href":784},"\u002Fdocs\u002Fwatermarking","Watermarking","). Custom watermarks for other clients are planned; until then use the Klunq Widget integration.",[16,788,789,790,792],{},"List models (allowed with a ",[27,791,62],{},"):",[97,794,796],{"className":99,"code":795,"language":101,"meta":102,"style":102},"curl -H \"Authorization: Bearer $VKEY\" \"$PROXY_URL\u002Fv1\u002Fmodels\"\n",[27,797,798],{"__ignoreMap":102},[106,799,800,802,804,806,808,810,812,814,816,819],{"class":108,"line":109},[106,801,113],{"class":112},[106,803,274],{"class":116},[106,805,125],{"class":124},[106,807,150],{"class":120},[106,809,382],{"class":128},[106,811,135],{"class":124},[106,813,125],{"class":124},[106,815,129],{"class":128},[106,817,818],{"class":120},"\u002Fv1\u002Fmodels",[106,820,283],{"class":124},[70,822],{},[73,824,826],{"id":825},"errors-status-codes","Errors & status codes",[828,829,830,843],"table",{},[831,832,833],"thead",{},[834,835,836,840],"tr",{},[837,838,839],"th",{},"Code",[837,841,842],{},"Meaning",[844,845,846,861,874,884,894,904],"tbody",{},[834,847,848,854],{},[849,850,851],"td",{},[27,852,853],{},"200",[849,855,856,857,860],{},"Success (",[27,858,859],{},"finish_reason:\"stop\""," on page-lock pass)",[834,862,863,868],{},[849,864,865],{},[27,866,867],{},"400",[849,869,870,873],{},[27,871,872],{},"Guardrail Violation"," — page-lock failed (system prompt missing, not first, or watermark absent)",[834,875,876,881],{},[849,877,878],{},[27,879,880],{},"401",[849,882,883],{},"Missing\u002Finvalid key",[834,885,886,891],{},[849,887,888],{},[27,889,890],{},"403",[849,892,893],{},"Not allowed to call this route",[834,895,896,901],{},[849,897,898],{},[27,899,900],{},"404",[849,902,903],{},"Team\u002Fkey not found",[834,905,906,911],{},[849,907,908],{},[27,909,910],{},"500",[849,912,913],{},"Invalid route or server error",[16,915,916,917],{},"Next: ",[782,918,920],{"href":919},"\u002Fdocs\u002Fsecurity","Security",[922,923,924],"style",{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":102,"searchDepth":160,"depth":160,"links":926},[927,937,938],{"id":75,"depth":142,"text":928,"children":929},"Management — v-keys",[930,931,932,933,934,935,936],{"id":89,"depth":160,"text":92},{"id":244,"depth":160,"text":247},{"id":336,"depth":160,"text":339},{"id":387,"depth":160,"text":390},{"id":462,"depth":160,"text":465},{"id":534,"depth":160,"text":537},{"id":573,"depth":160,"text":574},{"id":765,"depth":142,"text":766},{"id":825,"depth":142,"text":826},"All public endpoints you need: management key to manage v-keys, and v-keys for inference and spend.","md",{},{"title":14,"icon":943},"i-lucide-code-2","\u002Fdocs\u002Fapi-reference",{"title":6,"description":939},"docs\u002Fapi-reference","uEfIUdk3uWmK9OICbaMNc5-LvjZt_3QjRNwb9qD1IkE",{"id":949,"title":950,"body":951,"description":1494,"extension":940,"meta":1495,"navigation":1496,"path":1499,"seo":1500,"stem":1501,"__hash__":1502},"docs\u002Fdocs\u002Fbudgets.md","Budgets — Macro-budget and micro-budget",{"type":8,"value":952,"toc":1488},[953,957,960,964,980,988,998,1002,1008,1064,1087,1090,1247,1251,1254,1273,1277,1299,1375,1394,1443,1446,1475,1485],[11,954,956],{"id":955},"macro-budget-micro-budget","Macro-budget & micro-budget",[16,958,959],{},"Two budgets apply to every request. Both must have headroom, otherwise the request is rejected.",[73,961,963],{"id":962},"macro-budget-the-workspace-pool","Macro-budget — the workspace pool",[16,965,966,967,970,971,974,975,979],{},"Set once for your workspace (for example ",[44,968,969],{},"50 $","). Every ",[53,972,62],{"title":973},"virtual key"," spend is also debited from this shared pool at real model pricing (see ",[782,976,978],{"href":977},"\u002Fdocs\u002Fmodels","Models","). You choose the amount when the workspace is provisioned.",[97,981,986],{"className":982,"code":984,"language":985},[983],"language-text","Workspace pool: 50 $  |->   v-key A (1 $\u002F30d) ─┐\n                      |->  v-key B (5 $\u002F30d)  ─┤ draws at provider price\n                      |->  v-key C (no cap)   ─┘\n","text",[27,987,984],{"__ignoreMap":102},[16,989,990,994,995,997],{},[991,992,993],"em",{},"The pool is global."," Even a “no cap” ",[53,996,62],{"title":973}," still counts against it.",[73,999,1001],{"id":1000},"micro-budget-per-v-key","Micro-budget — per v-key",[16,1003,1004,1005,1007],{},"Each ",[27,1006,92],{}," can carry:",[828,1009,1010,1022],{},[831,1011,1012],{},[834,1013,1014,1017,1020],{},[837,1015,1016],{},"Field",[837,1018,1019],{},"Example",[837,1021,842],{},[844,1023,1024,1044],{},[834,1025,1026,1030,1041],{},[849,1027,1028],{},[27,1029,211],{},[849,1031,1032,204,1035,204,1038],{},[27,1033,1034],{},"5",[27,1036,1037],{},"1",[27,1039,1040],{},"0.5",[849,1042,1043],{},"Hard cap in USD for that key",[834,1045,1046,1050,1058],{},[849,1047,1048],{},[27,1049,214],{},[849,1051,1052,204,1054,204,1056],{},[27,1053,217],{},[27,1055,221],{},[27,1057,224],{},[849,1059,1060,1061],{},"Window after which spend resets to ",[27,1062,1063],{},"0",[20,1065,1066,1072],{},[23,1067,1068,1069,1071],{},"If ",[27,1070,211],{}," is omitted\u002Fnull → unlimited for that key (still bounded by the workspace pool).",[23,1073,1074,1076,1077,1080,1081,1083,1084,1086],{},[27,1075,214],{}," is the ",[44,1078,1079],{},"reset cadence",". After ",[27,1082,217],{}," the key’s spend resets and it can spend another ",[27,1085,211],{}," block.",[16,1088,1089],{},"Popular presets you can issue via management key:",[97,1091,1093],{"className":99,"code":1092,"language":101,"meta":102,"style":102},"# Per-user monthly — 2 $ that resets every month\n{ \"key_alias\": \"user-42\", \"max_budget\": 2, \"budget_duration\": \"30d\" }\n\n# Anonymous global pot — 1 $ that resets daily\n{ \"key_alias\": \"default\", \"max_budget\": 1, \"budget_duration\": \"1d\" }\n\n# Checkout-only burst — 0.5 $ one-shot (no reset)\n{ \"key_alias\": \"checkout-widget\", \"max_budget\": 0.5 }\n",[27,1094,1095,1100,1151,1157,1162,1206,1210,1215],{"__ignoreMap":102},[106,1096,1097],{"class":108,"line":109},[106,1098,1099],{"class":192},"# Per-user monthly — 2 $ that resets every month\n",[106,1101,1102,1106,1109,1113,1115,1118,1120,1123,1125,1127,1129,1131,1134,1136,1138,1140,1142,1144,1146,1148],{"class":108,"line":142},[106,1103,1105],{"class":1104},"sP7_E","{",[106,1107,1108],{"class":112}," \"key_alias\"",[106,1110,1112],{"class":1111},"sptTA",":",[106,1114,125],{"class":124},[106,1116,1117],{"class":120},"user-42",[106,1119,135],{"class":124},[106,1121,1122],{"class":120},",",[106,1124,125],{"class":124},[106,1126,211],{"class":120},[106,1128,135],{"class":124},[106,1130,1112],{"class":120},[106,1132,1133],{"class":120}," 2,",[106,1135,125],{"class":124},[106,1137,214],{"class":120},[106,1139,135],{"class":124},[106,1141,1112],{"class":120},[106,1143,125],{"class":124},[106,1145,217],{"class":120},[106,1147,135],{"class":124},[106,1149,1150],{"class":120}," }\n",[106,1152,1153],{"class":108,"line":160},[106,1154,1156],{"emptyLinePlaceholder":1155},true,"\n",[106,1158,1159],{"class":108,"line":174},[106,1160,1161],{"class":192},"# Anonymous global pot — 1 $ that resets daily\n",[106,1163,1164,1166,1168,1170,1172,1175,1177,1179,1181,1183,1185,1187,1190,1192,1194,1196,1198,1200,1202,1204],{"class":108,"line":189},[106,1165,1105],{"class":1104},[106,1167,1108],{"class":112},[106,1169,1112],{"class":1111},[106,1171,125],{"class":124},[106,1173,1174],{"class":120},"default",[106,1176,135],{"class":124},[106,1178,1122],{"class":120},[106,1180,125],{"class":124},[106,1182,211],{"class":120},[106,1184,135],{"class":124},[106,1186,1112],{"class":120},[106,1188,1189],{"class":120}," 1,",[106,1191,125],{"class":124},[106,1193,214],{"class":120},[106,1195,135],{"class":124},[106,1197,1112],{"class":120},[106,1199,125],{"class":124},[106,1201,221],{"class":120},[106,1203,135],{"class":124},[106,1205,1150],{"class":120},[106,1207,1208],{"class":108,"line":738},[106,1209,1156],{"emptyLinePlaceholder":1155},[106,1211,1212],{"class":108,"line":751},[106,1213,1214],{"class":192},"# Checkout-only burst — 0.5 $ one-shot (no reset)\n",[106,1216,1218,1220,1222,1224,1226,1229,1231,1233,1235,1237,1239,1241,1245],{"class":108,"line":1217},8,[106,1219,1105],{"class":1104},[106,1221,1108],{"class":112},[106,1223,1112],{"class":1111},[106,1225,125],{"class":124},[106,1227,1228],{"class":120},"checkout-widget",[106,1230,135],{"class":124},[106,1232,1122],{"class":120},[106,1234,125],{"class":124},[106,1236,211],{"class":120},[106,1238,135],{"class":124},[106,1240,1112],{"class":120},[106,1242,1244],{"class":1243},"srdBf"," 0.5",[106,1246,1150],{"class":120},[73,1248,1250],{"id":1249},"how-enforcement-works","How enforcement works",[16,1252,1253],{},"The proxy checks balances at inference time. When either cap would be exceeded, the chat completion is rejected before reaching the model.",[1255,1256,1259],"callout",{"color":1257,"icon":1258},"success","i-lucide-circle-check",[16,1260,1261,1264,1265,1268,1269,1272],{},[44,1262,1263],{},"Safe even when leaked."," A v-key for a single user with ",[27,1266,1267],{},"max_budget: 0.2"," and ",[27,1270,1271],{},"budget_duration: 1d"," cannot spend more than 20c that day, even if posted publicly. The workspace pool adds a second ceiling.",[73,1274,1276],{"id":1275},"choosing-durations","Choosing durations",[16,1278,1279,1281,1282,1285,1286,1289,1290,47,1296,792],{},[27,1280,214],{}," accepts a single duration string ",[27,1283,1284],{},"\u003Cnumber>\u003Cunit>",". If omitted or ",[27,1287,1288],{},"null",", the budget never resets. Per ",[782,1291,1295],{"href":1292,"rel":1293},"https:\u002F\u002Fdocs.litellm.ai\u002Fdocs\u002Fproxy\u002Fbudget_reset_and_tz#how-budget-resets-work",[1294],"nofollow","official LiteLLM docs",[27,1297,1298],{},"budget_reset_and_tz",[828,1300,1301,1313],{},[831,1302,1303],{},[834,1304,1305,1308,1310],{},[837,1306,1307],{},"Unit",[837,1309,842],{},[837,1311,1312],{},"Examples",[844,1314,1315,1336,1356],{},[834,1316,1317,1322,1325],{},[849,1318,1319],{},[27,1320,1321],{},"m",[849,1323,1324],{},"minutes",[849,1326,1327,204,1330,204,1333],{},[27,1328,1329],{},"5m",[27,1331,1332],{},"30m",[27,1334,1335],{},"60m",[834,1337,1338,1343,1346],{},[849,1339,1340],{},[27,1341,1342],{},"h",[849,1344,1345],{},"hours",[849,1347,1348,204,1350,204,1353],{},[27,1349,224],{},[27,1351,1352],{},"12h",[27,1354,1355],{},"24h",[834,1357,1358,1363,1366],{},[849,1359,1360],{},[27,1361,1362],{},"d",[849,1364,1365],{},"days",[849,1367,1368,204,1370,204,1373],{},[27,1369,221],{},[27,1371,1372],{},"7d",[27,1374,217],{},[16,1376,1377,1378,200,1381,218,1384,1387,1388,1390,1391,1393],{},"Weekly and monthly are ",[44,1379,1380],{},"not",[27,1382,1383],{},"1w",[27,1385,1386],{},"1mo"," — use ",[27,1389,1372],{}," for weekly and ",[27,1392,217],{}," for monthly:",[20,1395,1396,1408,1419,1430],{},[23,1397,1398,1407],{},[44,1399,1400,1401,1403,1404,1406],{},"Daily (",[27,1402,221],{}," \u002F ",[27,1405,1355],{},")"," — resets at midnight every day",[23,1409,1410,1415,1416],{},[44,1411,1412,1413,1406],{},"Weekly (",[27,1414,1372],{}," — resets on ",[44,1417,1418],{},"Monday at midnight",[23,1420,1421,1426,1427],{},[44,1422,1423,1424,1406],{},"Monthly (",[27,1425,217],{}," — resets on the ",[44,1428,1429],{},"1st of each month at midnight",[23,1431,1432,47,1435,204,1437,204,1439,1442],{},[44,1433,1434],{},"Sub-day",[27,1436,224],{},[27,1438,1332],{},[27,1440,1441],{},"10s",") — rolls forward by interval from current time",[16,1444,1445],{},"Common choices:",[20,1447,1448,1453,1458,1470],{},[23,1449,1450,1452],{},[27,1451,217],{}," ≈ monthly billing period (resets 1st at midnight)",[23,1454,1455,1457],{},[27,1456,1372],{}," ≈ weekly billing period (resets on Monday at midnight)",[23,1459,1460,1462,1463,604,1467,1469],{},[27,1461,221],{}," ≈ daily anonymous pot (see ",[782,1464,1466],{"href":1465},"\u002Fdocs\u002Fstrategies","Strategies",[27,1468,1174],{}," key)",[23,1471,1472,1474],{},[27,1473,224],{}," for aggressive demos or load tests",[16,1476,916,1477,1480,1481],{},[782,1478,1479],{"href":784},"Watermarking — page lock"," · ",[782,1482,1484],{"href":1483},"\u002Fdocs\u002Fmanaging-keys","Managing keys",[922,1486,1487],{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sptTA, html code.shiki .sptTA{--shiki-light:#6182B8;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .srdBf, html code.shiki .srdBf{--shiki-light:#F76D47;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":102,"searchDepth":160,"depth":160,"links":1489},[1490,1491,1492,1493],{"id":962,"depth":142,"text":963},{"id":1000,"depth":142,"text":1001},{"id":1249,"depth":142,"text":1250},{"id":1275,"depth":142,"text":1276},"A global pool plus per-key caps. Every request draws from both — spend stays bounded even when keys leak.",{},{"title":1497,"icon":1498},"Budgets","i-lucide-wallet","\u002Fdocs\u002Fbudgets",{"title":950,"description":1494},"docs\u002Fbudgets","-3wNEuusmhuqG868exqFcVOSV3Pmyzfj_Tk0ZIXVtSM",{"id":1504,"title":1505,"body":1506,"description":1746,"extension":940,"meta":1747,"navigation":1748,"path":1751,"seo":1752,"stem":1753,"__hash__":1754},"docs\u002Fdocs\u002Fconcepts.md","Concepts — v-key and disposal",{"type":8,"value":1507,"toc":1741},[1508,1512,1525,1529,1566,1569,1580,1584,1587,1630,1633,1637,1707,1716,1738],[11,1509,1510],{"id":62},[53,1511,62],{"title":973},[16,1513,1514,1515,1517,1518,1521,1522,1524],{},"A ",[53,1516,62],{"title":973}," is a disposable, budget-capped key (",[27,1519,1520],{},"sk-...",") you put in the browser. Your management key stays on the server and creates them. A group of ",[53,1523,56],{"title":55}," created by the same management key is called a team. Team and user account are the same thing — one management key and a pool of v-keys.",[73,1526,1528],{"id":1527},"the-two-key-types","The two key types",[828,1530,1531,1541],{},[831,1532,1533],{},[834,1534,1535,1538],{},[837,1536,1537],{},"Key",[837,1539,1540],{},"What it can do",[844,1542,1543,1552],{},[834,1544,1545,1549],{},[849,1546,1547],{},[44,1548,46],{},[849,1550,1551],{},"Create, list, inspect, update and delete your v-keys; read your usage and spend",[834,1553,1554,1558],{},[849,1555,1556],{},[44,1557,62],{},[849,1559,1560,204,1562,1565],{},[27,1561,775],{},[27,1563,1564],{},"GET \u002Fv1\u002Fmodels"," — inference only",[16,1567,1568],{},"The management key is securely available to see from the dashboard for authenticated users. v-keys are not stored like the management key — after creating one, store it securely, you will not be able to retrieve it again.",[1255,1570,1573],{"color":1571,"icon":1572},"warning","i-lucide-lock",[16,1574,1575,1576,1579],{},"Keep the management key secret on your server. Never put it in ",[27,1577,1578],{},"data-api-key",". Only v-keys go to the browser.",[73,1581,1583],{"id":1582},"disposable-by-design","Disposable by design",[16,1585,1586],{},"A v-key is created using your management key. It can then be updated and deleted, and each key can be used for inference — it is capped and page-locked.",[20,1588,1589,1607,1622],{},[23,1590,1591,1594,1595,204,1597,204,1599,204,1601,1603,1604,1606],{},[44,1592,1593],{},"Create"," with caps (",[27,1596,211],{},[27,1598,214],{},[27,1600,207],{},[27,1602,228],{},") and a ",[27,1605,199],{}," for individual tracking — make the alias correspond to the user, page, default anonymous user, or other abstraction that defines a budget strategy",[23,1608,1609,1612,1613,1616,1617,604,1620],{},[44,1610,1611],{},"Revoke"," via ",[27,1614,1615],{},"POST \u002Fkey\u002Fdelete {\"keys\":[\"sk-…\"]}"," — next ",[27,1618,1619],{},"GET \u002Fkey\u002Finfo?key=sk-…",[27,1621,900],{},[23,1623,1624,1627,1628],{},[44,1625,1626],{},"Rotate"," by deleting + generating a fresh ",[27,1629,199],{},[16,1631,1632],{},"You can issue hundreds of v-keys in your team.",[73,1634,1636],{"id":1635},"lifecycle-example","Lifecycle example",[97,1638,1640],{"className":99,"code":1639,"language":101,"meta":102,"style":102},"# Use your management key to mint a disposable v-key\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"vkey-landing\",\"max_budget\":5,\"budget_duration\":\"30d\",\"models\":[\"gemma4\"]}'\n# → { \"key\": \"sk-…\", \"max_budget\": 5.0 }\n",[27,1641,1642,1647,1665,1679,1691,1702],{"__ignoreMap":102},[106,1643,1644],{"class":108,"line":109},[106,1645,1646],{"class":192},"# Use your management key to mint a disposable v-key\n",[106,1648,1649,1651,1653,1655,1657,1659,1661,1663],{"class":108,"line":142},[106,1650,113],{"class":112},[106,1652,117],{"class":116},[106,1654,121],{"class":120},[106,1656,125],{"class":124},[106,1658,129],{"class":128},[106,1660,132],{"class":120},[106,1662,135],{"class":124},[106,1664,139],{"class":138},[106,1666,1667,1669,1671,1673,1675,1677],{"class":108,"line":160},[106,1668,145],{"class":116},[106,1670,125],{"class":124},[106,1672,150],{"class":120},[106,1674,153],{"class":128},[106,1676,135],{"class":124},[106,1678,139],{"class":138},[106,1680,1681,1683,1685,1687,1689],{"class":108,"line":174},[106,1682,145],{"class":116},[106,1684,125],{"class":124},[106,1686,167],{"class":120},[106,1688,135],{"class":124},[106,1690,139],{"class":138},[106,1692,1693,1695,1697,1700],{"class":108,"line":189},[106,1694,177],{"class":116},[106,1696,180],{"class":124},[106,1698,1699],{"class":120},"{\"key_alias\":\"vkey-landing\",\"max_budget\":5,\"budget_duration\":\"30d\",\"models\":[\"gemma4\"]}",[106,1701,186],{"class":124},[106,1703,1704],{"class":108,"line":738},[106,1705,1706],{"class":192},"# → { \"key\": \"sk-…\", \"max_budget\": 5.0 }\n",[16,1708,1709,1710,1712,1713,1715],{},"The v-key draws from both budgets (see ",[782,1711,1497],{"href":1499},") and is locked to the page (see ",[782,1714,785],{"href":784},").",[1255,1717,1720],{"color":1718,"icon":1719},"info","i-lucide-lightbulb",[16,1721,1722,1725,1726,47,1728,204,1731,204,1734,1737],{},[44,1723,1724],{},"Tip:"," Give each surface its own ",[27,1727,199],{},[27,1729,1730],{},"landing",[27,1732,1733],{},"docs",[27,1735,1736],{},"checkout","). Revoking one does not affect others.",[922,1739,1740],{},"html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":102,"searchDepth":160,"depth":160,"links":1742},[1743,1744,1745],{"id":1527,"depth":142,"text":1528},{"id":1582,"depth":142,"text":1583},{"id":1635,"depth":142,"text":1636},"Management keys, v-keys and why every key is disposable by design.",{},{"title":1749,"icon":1750},"Concepts","i-lucide-key-round","\u002Fdocs\u002Fconcepts",{"title":1505,"description":1746},"docs\u002Fconcepts","ha04O7zF-Tg40joI18wuRfDHpaKltS6Gt2wlaaBUdyI",{"id":1756,"title":1757,"body":1758,"description":1950,"extension":940,"meta":1951,"navigation":1952,"path":1955,"seo":1956,"stem":1957,"__hash__":1958},"docs\u002Fdocs\u002Findex.md","Introduction — What is Klunq Proxy",{"type":8,"value":1759,"toc":1944},[1760,1764,1790,1797,1811,1832,1836,1846,1849,1881,1885,1892,1895,1899,1905,1919,1923,1935],[11,1761,1763],{"id":1762},"what-is-klunq-proxy","What is Klunq Proxy",[16,1765,1766,1769,1770,47,1772,1774,1775,1780,1781,1785,1786,1789],{},[44,1767,1768],{},"Klunq Proxy"," is a managed gateway that lets you hand out disposable ",[53,1771,56],{"title":55},[27,1773,1520],{},") instead of your real provider key. It is built to pair with the ",[782,1776,1779],{"href":1777,"rel":1778},"https:\u002F\u002Fgithub.com\u002Fklunqlabs\u002Fklunq-widget",[1294],"Klunq widget"," — the embeddable page-agent at ",[782,1782,1784],{"href":29,"rel":1783},[1294],"klunqlabs.com"," that turns any website into an AI website with one ",[27,1787,1788],{},"\u003Cscript>"," tag.",[16,1791,1792,1793,1796],{},"The widget makes the page itself agentic: it reads content, clicks buttons, fills forms and answers questions in natural language. The proxy makes that agentic web ",[44,1794,1795],{},"safe to distribute",": every key is capped, reset on a schedule you choose, and locked to your page.",[1255,1798,1800],{"color":1571,"icon":1799},"i-lucide-flask-conical",[16,1801,1802,1805,1806,1810],{},[44,1803,1804],{},"Public beta — free models only, no payments."," The proxy currently serves a small set of free models. There is no payment gate, no charges and no billing: budgets cap usage, not money. Paid top-ups arrive later under updated terms (see ",[782,1807,1809],{"href":1808},"\u002Fterms","Terms of Service","). Availability is best-effort — do not wire life-critical flows to the beta.",[1255,1812,1815],{"color":1813,"icon":1814},"primary","i-lucide-info",[16,1816,1817,1818,1820,1821,1824,1825,1828,1829,1831],{},"The proxy speaks the OpenAI API, but today it only works with the Klunq Widget. Every request must carry the widget’s watermark — without it the proxy rejects the call (see ",[782,1819,785],{"href":784},"). In the future we plan to support custom watermarks for other clients. Today: point ",[27,1822,1823],{},"data-base-url"," at ",[27,1826,1827],{},"https:\u002F\u002Fproxy.klunqlabs.com\u002Fv1"," and use a ",[53,1830,62],{"title":973}," from the proxy — the widget handles the rest.",[73,1833,1835],{"id":1834},"why-a-proxy-at-all","Why a proxy at all",[16,1837,1838,1839,1841,1842,1845],{},"Shipping a provider key in ",[27,1840,1578],{}," makes it visible in the browser inspector. The conventional fix is to build your own backend that forwards requests to the LLM and enforces limits. Klunq inverts this: keep the page agentic with zero backend, and solve ",[44,1843,1844],{},"key distribution"," centrally.",[16,1847,1848],{},"Klunq Proxy gives you:",[20,1850,1851,1857,1863,1869,1875],{},[23,1852,1853,1856],{},[44,1854,1855],{},"Controllable spend"," — a global workspace budget plus per-key caps, both enforced",[23,1858,1859,1862],{},[44,1860,1861],{},"Disposable keys"," — revoke or rotate v-keys in seconds; safe to deploy because budgets and page-lock bound the blast radius",[23,1864,1865,1868],{},[44,1866,1867],{},"Page-lock"," — a leaked v-key cannot be repurposed for coding, math or generic chat",[23,1870,1871,1874],{},[44,1872,1873],{},"Curated cheap models"," — small open models that are enough for a page-agent at a fraction of the price",[23,1876,1877,1880],{},[44,1878,1879],{},"OpenAI-compatible, widget-locked"," — speaks the OpenAI API today, but only the widget’s watermarked prompts pass",[73,1882,1884],{"id":1883},"who-is-it-for","Who is it for",[16,1886,1887,1888,1891],{},"The proxy is designed ",[44,1889,1890],{},"first for small and medium businesses"," that want AI on their site without operating infrastructure. You fund a single workspace budget; every visitor draws from that shared pool through their own micro-budget. Spend is limited and predictable, even if a v-key leaks.",[16,1893,1894],{},"Larger workspaces can use it the same way — your management key manages only your own v-keys.",[73,1896,1898],{"id":1897},"how-it-fits-together","How it fits together",[97,1900,1903],{"className":1901,"code":1902,"language":985},[983],"Browser ─ v-key ──> Klunq Proxy ──> LLM (curated list)\n                 page-lock check\n                 workspace + per-key budget check\n",[27,1904,1902],{"__ignoreMap":102},[16,1906,1907,1908,1912,1913,1915,1916,1918],{},"See ",[782,1909,1911],{"href":1910},"\u002Fdocs\u002Fintegration","Integration"," for the one-line widget change, ",[782,1914,785],{"href":784}," for the page-lock, and ",[782,1917,14],{"href":944}," for programmatic key management.",[73,1920,1922],{"id":1921},"status","Status",[16,1924,1925,1926,218,1928,1930,1931,1934],{},"The proxy is live for early teams. It enforces v-keys with per-key ",[27,1927,211],{},[27,1929,214],{},", a global workspace pool, page-locked watermarking (widget-only today, custom watermarks planned), and a small curated model list (",[27,1932,1933],{},"gemma4"," today). Spend tracking via the proxy API is operational.",[16,1936,916,1937,1480,1941],{},[782,1938,1940],{"href":1939},"\u002Fdocs\u002Fquickstart","Quickstart — Mint your first disposable key",[782,1942,1943],{"href":1751},"Concepts — v-keys & teams",{"title":102,"searchDepth":160,"depth":160,"links":1945},[1946,1947,1948,1949],{"id":1834,"depth":142,"text":1835},{"id":1883,"depth":142,"text":1884},{"id":1897,"depth":142,"text":1898},{"id":1921,"depth":142,"text":1922},"Klunq Proxy gives you disposable v-keys with hard budgets and page-locked access, so you can safely distribute AI on the open web.",{},{"title":1953,"icon":1954},"Introduction","i-lucide-shield-check","\u002Fdocs",{"title":1757,"description":1950},"docs\u002Findex","slOWG56ytE2wAjzbjDZT_zBZ6APdFsX-mZwbYIWGWgs",{"id":1960,"title":1961,"body":1962,"description":2412,"extension":940,"meta":2413,"navigation":2414,"path":1910,"seo":2416,"stem":2417,"__hash__":2418},"docs\u002Fdocs\u002Fintegration.md","Integration — Widget + proxy in one script tag",{"type":8,"value":1963,"toc":2407},[1964,1968,1974,1978,1981,2075,2114,2117,2135,2139,2145,2160,2203,2209,2376,2379,2383,2398,2404],[11,1965,1967],{"id":1966},"widget-proxy-integration","Widget → Proxy integration",[16,1969,1970,1971,1973],{},"The Klunq Widget is framework-agnostic. If your page can render HTML, it can use the proxy — just add a ",[27,1972,1788],{}," tag and point it at your proxy deployment.",[73,1975,1977],{"id":1976},"setup","Setup",[16,1979,1980],{},"Add the widget script once and set two attributes:",[97,1982,1986],{"className":1983,"code":1984,"language":1985,"meta":102,"style":102},"language-html shiki shiki-themes material-theme-lighter github-light github-dark","\u003Cscript src=\"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@klunqlabs\u002Fklunq-widget@latest\u002Fdist\u002Fklunq-widget.js\"\n  data-model=\"gemma4\"\n  data-api-key=\"sk-vkey-…\"\n  data-base-url=\"https:\u002F\u002Fproxy.klunqlabs.com\u002Fv1\"\n  data-scope=\"broad\"\n>\u003C\u002Fscript>\n","html",[27,1987,1988,2011,2024,2038,2051,2065],{"__ignoreMap":102},[106,1989,1990,1993,1997,2001,2004,2006,2009],{"class":108,"line":109},[106,1991,1992],{"class":1104},"\u003C",[106,1994,1996],{"class":1995},"sQzsp","script",[106,1998,2000],{"class":1999},"s9AJx"," src",[106,2002,2003],{"class":1104},"=",[106,2005,135],{"class":124},[106,2007,2008],{"class":120},"https:\u002F\u002Fcdn.jsdelivr.net\u002Fnpm\u002F@klunqlabs\u002Fklunq-widget@latest\u002Fdist\u002Fklunq-widget.js",[106,2010,283],{"class":124},[106,2012,2013,2016,2018,2020,2022],{"class":108,"line":142},[106,2014,2015],{"class":1999},"  data-model",[106,2017,2003],{"class":1104},[106,2019,135],{"class":124},[106,2021,1933],{"class":120},[106,2023,283],{"class":124},[106,2025,2026,2029,2031,2033,2036],{"class":108,"line":160},[106,2027,2028],{"class":1999},"  data-api-key",[106,2030,2003],{"class":1104},[106,2032,135],{"class":124},[106,2034,2035],{"class":120},"sk-vkey-…",[106,2037,283],{"class":124},[106,2039,2040,2043,2045,2047,2049],{"class":108,"line":174},[106,2041,2042],{"class":1999},"  data-base-url",[106,2044,2003],{"class":1104},[106,2046,135],{"class":124},[106,2048,1827],{"class":120},[106,2050,283],{"class":124},[106,2052,2053,2056,2058,2060,2063],{"class":108,"line":189},[106,2054,2055],{"class":1999},"  data-scope",[106,2057,2003],{"class":1104},[106,2059,135],{"class":124},[106,2061,2062],{"class":120},"broad",[106,2064,283],{"class":124},[106,2066,2067,2070,2072],{"class":108,"line":738},[106,2068,2069],{"class":1104},">\u003C\u002F",[106,2071,1996],{"class":1995},[106,2073,2074],{"class":1104},">\n",[20,2076,2077,2088,2103],{},[23,2078,2079,2081,2082,2084,2085,1715],{},[27,2080,1823],{}," → your proxy’s OpenAI-compatible base. For the hosted proxy use ",[27,2083,1827],{},". If you self-host, use your own proxy URL (e.g. ",[27,2086,2087],{},"https:\u002F\u002Fproxy.yourdomain.com\u002Fv1",[23,2089,2090,2092,2093,47,2095,2097,2098,1268,2101,241],{},[27,2091,1578],{}," → a ",[53,2094,62],{"title":973},[27,2096,50],{},") you created with your management key. See ",[782,2099,2100],{"href":1939},"Quickstart",[782,2102,1484],{"href":1483},[23,2104,2105,2108,2109,2111,2112,241],{},[27,2106,2107],{},"data-model"," → one of the curated models (",[27,2110,1933],{}," today). See ",[782,2113,978],{"href":977},[16,2115,2116],{},"The widget then handles the page-locked prompt and page tools (read, click, fill, navigate). No backend code or build step is required to render the tag.",[1255,2118,2120],{"color":1718,"icon":2119},"i-lucide-book-open",[16,2121,2122,2123,2127,2128,1268,2131,2134],{},"The widget itself is documented in its ",[782,2124,2126],{"href":1777,"rel":2125},[1294],"GitHub README",". This doc focuses only on the proxy. See ",[782,2129,29],{"href":29,"rel":2130},[1294],[27,2132,2133],{},"\u002Fproxy"," marketing for product context.",[73,2136,2138],{"id":2137},"static-or-dynamic-your-choice","Static or dynamic — your choice",[16,2140,2141,2142,2144],{},"The ",[27,2143,1788],{}," tag is plain HTML, so it works in any framework — Next.js, Nuxt, SvelteKit, Rails, WordPress, or static HTML. You can embed the key statically or inject it dynamically; both are valid.",[16,2146,2147,2150,2151,2153,2154,2156,2157,1715],{},[44,2148,2149],{},"Static (simplest):"," hard-code a low-budget ",[53,2152,62],{"title":973}," directly in HTML. Good for public demos or the anonymous ",[27,2155,1174],{}," pot (e.g. ",[27,2158,2159],{},"1 $\u002Fday",[97,2161,2163],{"className":1983,"code":2162,"language":1985,"meta":102,"style":102},"\u003Cscript data-api-key=\"sk-vkey-static-…\" data-base-url=\"https:\u002F\u002Fproxy.klunqlabs.com\u002Fv1\" ...>\u003C\u002Fscript>\n",[27,2164,2165],{"__ignoreMap":102},[106,2166,2167,2169,2171,2174,2176,2178,2181,2183,2186,2188,2190,2192,2194,2197,2199,2201],{"class":108,"line":109},[106,2168,1992],{"class":1104},[106,2170,1996],{"class":1995},[106,2172,2173],{"class":1999}," data-api-key",[106,2175,2003],{"class":1104},[106,2177,135],{"class":124},[106,2179,2180],{"class":120},"sk-vkey-static-…",[106,2182,135],{"class":124},[106,2184,2185],{"class":1999}," data-base-url",[106,2187,2003],{"class":1104},[106,2189,135],{"class":124},[106,2191,1827],{"class":120},[106,2193,135],{"class":124},[106,2195,2196],{"class":1999}," ...",[106,2198,2069],{"class":1104},[106,2200,1996],{"class":1995},[106,2202,2074],{"class":1104},[16,2204,2205,2208],{},[44,2206,2207],{},"Dynamic (per-user):"," fetch a user-specific v-key from your backend after sign-in and set the attribute with JavaScript. Any framework that can manipulate the DOM can do this:",[97,2210,2214],{"className":2211,"code":2212,"language":2213,"meta":102,"style":102},"language-js shiki shiki-themes material-theme-lighter github-light github-dark","\u002F\u002F fetch a v-key minted on your server with the management key\nconst { key } = await fetch('\u002Fapi\u002Fmint-vkey', { headers: { Authorization: `Bearer ${userJwt}` } }).then(r => r.json())\n\n\u002F\u002F any tag will do — update the attribute live\ndocument.querySelector('script[data-api-key]')?.setAttribute('data-api-key', key)\n\u002F\u002F or create the script tag dynamically if you prefer\n","js",[27,2215,2216,2221,2322,2326,2331,2371],{"__ignoreMap":102},[106,2217,2218],{"class":108,"line":109},[106,2219,2220],{"class":192},"\u002F\u002F fetch a v-key minted on your server with the management key\n",[106,2222,2223,2227,2230,2233,2236,2240,2244,2248,2251,2254,2257,2259,2261,2263,2267,2269,2271,2274,2276,2279,2282,2285,2288,2291,2293,2295,2297,2299,2302,2304,2308,2311,2314,2316,2319],{"class":108,"line":142},[106,2224,2226],{"class":2225},"sbsja","const",[106,2228,2229],{"class":1104}," {",[106,2231,2232],{"class":138}," key",[106,2234,2235],{"class":1104}," }",[106,2237,2239],{"class":2238},"smGrS"," =",[106,2241,2243],{"class":2242},"sVHd0"," await",[106,2245,2247],{"class":2246},"sGLFI"," fetch",[106,2249,2250],{"class":128},"(",[106,2252,2253],{"class":124},"'",[106,2255,2256],{"class":120},"\u002Fapi\u002Fmint-vkey",[106,2258,2253],{"class":124},[106,2260,1122],{"class":1104},[106,2262,2229],{"class":1104},[106,2264,2266],{"class":2265},"skxfh"," headers",[106,2268,1112],{"class":1104},[106,2270,2229],{"class":1104},[106,2272,2273],{"class":2265}," Authorization",[106,2275,1112],{"class":1104},[106,2277,2278],{"class":124}," `",[106,2280,2281],{"class":120},"Bearer ",[106,2283,2284],{"class":124},"${",[106,2286,2287],{"class":128},"userJwt",[106,2289,2290],{"class":124},"}`",[106,2292,2235],{"class":1104},[106,2294,2235],{"class":1104},[106,2296,1406],{"class":128},[106,2298,241],{"class":1104},[106,2300,2301],{"class":2246},"then",[106,2303,2250],{"class":128},[106,2305,2307],{"class":2306},"s99_P","r",[106,2309,2310],{"class":2225}," =>",[106,2312,2313],{"class":128}," r",[106,2315,241],{"class":1104},[106,2317,2318],{"class":2246},"json",[106,2320,2321],{"class":128},"())\n",[106,2323,2324],{"class":108,"line":160},[106,2325,1156],{"emptyLinePlaceholder":1155},[106,2327,2328],{"class":108,"line":174},[106,2329,2330],{"class":192},"\u002F\u002F any tag will do — update the attribute live\n",[106,2332,2333,2336,2338,2341,2343,2345,2348,2350,2352,2355,2358,2360,2362,2364,2366,2368],{"class":108,"line":189},[106,2334,2335],{"class":128},"document",[106,2337,241],{"class":1104},[106,2339,2340],{"class":2246},"querySelector",[106,2342,2250],{"class":128},[106,2344,2253],{"class":124},[106,2346,2347],{"class":120},"script[data-api-key]",[106,2349,2253],{"class":124},[106,2351,1406],{"class":128},[106,2353,2354],{"class":1104},"?.",[106,2356,2357],{"class":2246},"setAttribute",[106,2359,2250],{"class":128},[106,2361,2253],{"class":124},[106,2363,1578],{"class":120},[106,2365,2253],{"class":124},[106,2367,1122],{"class":1104},[106,2369,2370],{"class":128}," key)\n",[106,2372,2373],{"class":108,"line":738},[106,2374,2375],{"class":192},"\u002F\u002F or create the script tag dynamically if you prefer\n",[16,2377,2378],{},"Both approaches are framework-agnostic: if you can add a tag to the rendered page and change an attribute, you can integrate.",[73,2380,2382],{"id":2381},"verify-the-proxy","Verify the proxy",[97,2384,2386],{"className":99,"code":2385,"language":101,"meta":102,"style":102},"curl https:\u002F\u002Fproxy.klunqlabs.com\u002Fhealth\u002Freadiness # → {\"status\":\"healthy\",\"db\":\"connected\"}\n",[27,2387,2388],{"__ignoreMap":102},[106,2389,2390,2392,2395],{"class":108,"line":109},[106,2391,113],{"class":112},[106,2393,2394],{"class":120}," https:\u002F\u002Fproxy.klunqlabs.com\u002Fhealth\u002Freadiness",[106,2396,2397],{"class":192}," # → {\"status\":\"healthy\",\"db\":\"connected\"}\n",[16,2399,916,2400,1480,2402],{},[782,2401,1484],{"href":1483},[782,2403,2100],{"href":1939},[922,2405,2406],{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sQzsp, html code.shiki .sQzsp{--shiki-light:#E53935;--shiki-default:#22863A;--shiki-dark:#85E89D}html pre.shiki code .s9AJx, html code.shiki .s9AJx{--shiki-light:#9C3EDA;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sbsja, html code.shiki .sbsja{--shiki-light:#9C3EDA;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s99_P, html code.shiki .s99_P{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#E36209;--shiki-default-font-style:inherit;--shiki-dark:#FFAB70;--shiki-dark-font-style:inherit}",{"title":102,"searchDepth":160,"depth":160,"links":2408},[2409,2410,2411],{"id":1976,"depth":142,"text":1977},{"id":2137,"depth":142,"text":2138},{"id":2381,"depth":142,"text":2382},"Point the Klunq widget at the proxy: set data-base-url to your proxy and data-api-key to a v-key.",{},{"title":1911,"icon":2415},"i-lucide-plug-zap",{"title":1961,"description":2412},"docs\u002Fintegration","nORkQ9xsJKZN0uEnYYh2dd-En3QuqXH_XUiJDWcRM9U",{"id":2420,"title":2421,"body":2422,"description":2934,"extension":940,"meta":2935,"navigation":2936,"path":1483,"seo":2938,"stem":2939,"__hash__":2940},"docs\u002Fdocs\u002Fmanaging-keys.md","Managing keys — UI and programmatic",{"type":8,"value":2423,"toc":2926},[2424,2427,2430,2434,2517,2521,2524,2537,2875,2879,2902,2912,2918,2923],[11,2425,1484],{"id":2426},"managing-keys",[16,2428,2429],{},"Two surfaces, same underlying API (the management key speaks to the proxy directly).",[73,2431,2433],{"id":2432},"option-1-dashboard-ui","Option 1: Dashboard UI",[20,2435,2436,2465,2474,2482,2490,2506],{},[23,2437,2438,2441,2442,2444,2445,204,2447,47,2449,218,2451,218,2453,225,2455,204,2457,204,2459,2461,2462,2464],{},[44,2439,2440],{},"Create modal"," — ",[27,2443,199],{}," required; optional ",[27,2446,211],{},[27,2448,214],{},[27,2450,217],{},[27,2452,221],{},[27,2454,224],{},[27,2456,228],{},[27,2458,231],{},[27,2460,207],{}," (comma list, empty = all). Shows ",[27,2463,113],{}," preview.",[23,2466,2467,2470,2471,2473],{},[44,2468,2469],{},"Copy once"," — the raw ",[27,2472,50],{}," is shown a single time.",[23,2475,2476,2479,2480,241],{},[44,2477,2478],{},"Inline edit"," — alias, budget, duration, RPM\u002FTPM via ",[27,2481,390],{},[23,2483,2484,2487,2488,241],{},[44,2485,2486],{},"Delete"," — confirmation via ",[27,2489,465],{},[23,2491,2492,2495,2496,2499,2500,218,2503,241],{},[44,2493,2494],{},"Search"," — exact, case-sensitive alias search via ",[27,2497,2498],{},"GET \u002Fkey\u002Flist?key_alias=…",". Pagination via ",[27,2501,2502],{},"total_count",[27,2504,2505],{},"total_pages",[23,2507,2508,2441,2510,218,2513,2516],{},[44,2509,1922],{},[27,2511,2512],{},"active",[27,2514,2515],{},"blocked"," derived from the key state.",[73,2518,2520],{"id":2519},"option-2-programmatic-management-key","Option 2: Programmatic — management key",[16,2522,2523],{},"Get your management key from the dashboard (Team API key). Keep it on the server — never ship it to the browser.",[16,2525,2526,2527,2530,2531,2533,2534,2536],{},"Base ",[27,2528,2529],{},"PROXY_URL"," is ",[27,2532,35],{},". The proxy is LiteLLM-based with custom hooks and guardrails, so the management key exposes only a documented subset (the key\u002Fspend routes listed in ",[782,2535,14],{"href":944},") — not the full upstream LiteLLM surface.",[97,2538,2540],{"className":99,"code":2539,"language":101,"meta":102,"style":102},"TEAM_MGMT_KEY=\"sk-...\" # from dashboard\n\n# Create\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"vkey-landing\",\"models\":[\"gemma4\"],\"max_budget\":2,\"budget_duration\":\"30d\"}'\n# → { \"key\": \"sk-…\", \"token_id\": \"…\", \"max_budget\": 2 }\n\n# List (all keys for your team)\ncurl -G \"$PROXY_URL\u002Fkey\u002Flist\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\"\n# → { \"keys\": [...], \"total_count\": 42 }\n\n# Filter by exact alias\ncurl -G \"$PROXY_URL\u002Fkey\u002Flist\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" --data-urlencode \"key_alias=vkey-landing\"\n\n# Info — use the sk-… value\ncurl -G \"$PROXY_URL\u002Fkey\u002Finfo\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" --data-urlencode \"key=$VKEY\"\n\n# Update\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fupdate\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" -H \"Content-Type: application\u002Fjson\" -d '{\"key\":\"sk-…\",\"key_alias\":\"vkey-updated\"}'\n\n# Delete\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fdelete\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" -H \"Content-Type: application\u002Fjson\" -d '{\"keys\":[\"sk-…\"]}'\n# → subsequent GET \u002Fkey\u002Finfo?key=sk-… → 404 No key\n",[27,2541,2542,2558,2562,2567,2585,2599,2611,2622,2627,2632,2638,2663,2669,2674,2680,2713,2718,2724,2759,2764,2770,2815,2820,2826,2869],{"__ignoreMap":102},[106,2543,2544,2547,2549,2551,2553,2555],{"class":108,"line":109},[106,2545,2546],{"class":128},"TEAM_MGMT_KEY",[106,2548,2003],{"class":2238},[106,2550,135],{"class":124},[106,2552,1520],{"class":120},[106,2554,135],{"class":124},[106,2556,2557],{"class":192}," # from dashboard\n",[106,2559,2560],{"class":108,"line":142},[106,2561,1156],{"emptyLinePlaceholder":1155},[106,2563,2564],{"class":108,"line":160},[106,2565,2566],{"class":192},"# Create\n",[106,2568,2569,2571,2573,2575,2577,2579,2581,2583],{"class":108,"line":174},[106,2570,113],{"class":112},[106,2572,117],{"class":116},[106,2574,121],{"class":120},[106,2576,125],{"class":124},[106,2578,129],{"class":128},[106,2580,132],{"class":120},[106,2582,135],{"class":124},[106,2584,139],{"class":138},[106,2586,2587,2589,2591,2593,2595,2597],{"class":108,"line":189},[106,2588,145],{"class":116},[106,2590,125],{"class":124},[106,2592,150],{"class":120},[106,2594,153],{"class":128},[106,2596,135],{"class":124},[106,2598,139],{"class":138},[106,2600,2601,2603,2605,2607,2609],{"class":108,"line":738},[106,2602,145],{"class":116},[106,2604,125],{"class":124},[106,2606,167],{"class":120},[106,2608,135],{"class":124},[106,2610,139],{"class":138},[106,2612,2613,2615,2617,2620],{"class":108,"line":751},[106,2614,177],{"class":116},[106,2616,180],{"class":124},[106,2618,2619],{"class":120},"{\"key_alias\":\"vkey-landing\",\"models\":[\"gemma4\"],\"max_budget\":2,\"budget_duration\":\"30d\"}",[106,2621,186],{"class":124},[106,2623,2624],{"class":108,"line":1217},[106,2625,2626],{"class":192},"# → { \"key\": \"sk-…\", \"token_id\": \"…\", \"max_budget\": 2 }\n",[106,2628,2630],{"class":108,"line":2629},9,[106,2631,1156],{"emptyLinePlaceholder":1155},[106,2633,2635],{"class":108,"line":2634},10,[106,2636,2637],{"class":192},"# List (all keys for your team)\n",[106,2639,2641,2643,2645,2647,2649,2651,2653,2655,2657,2659,2661],{"class":108,"line":2640},11,[106,2642,113],{"class":112},[106,2644,262],{"class":116},[106,2646,125],{"class":124},[106,2648,129],{"class":128},[106,2650,269],{"class":120},[106,2652,135],{"class":124},[106,2654,274],{"class":116},[106,2656,125],{"class":124},[106,2658,150],{"class":120},[106,2660,153],{"class":128},[106,2662,283],{"class":124},[106,2664,2666],{"class":108,"line":2665},12,[106,2667,2668],{"class":192},"# → { \"keys\": [...], \"total_count\": 42 }\n",[106,2670,2672],{"class":108,"line":2671},13,[106,2673,1156],{"emptyLinePlaceholder":1155},[106,2675,2677],{"class":108,"line":2676},14,[106,2678,2679],{"class":192},"# Filter by exact alias\n",[106,2681,2683,2685,2687,2689,2691,2693,2695,2697,2699,2701,2703,2705,2707,2709,2711],{"class":108,"line":2682},15,[106,2684,113],{"class":112},[106,2686,262],{"class":116},[106,2688,125],{"class":124},[106,2690,129],{"class":128},[106,2692,269],{"class":120},[106,2694,135],{"class":124},[106,2696,274],{"class":116},[106,2698,125],{"class":124},[106,2700,150],{"class":120},[106,2702,153],{"class":128},[106,2704,135],{"class":124},[106,2706,320],{"class":116},[106,2708,125],{"class":124},[106,2710,325],{"class":120},[106,2712,283],{"class":124},[106,2714,2716],{"class":108,"line":2715},16,[106,2717,1156],{"emptyLinePlaceholder":1155},[106,2719,2721],{"class":108,"line":2720},17,[106,2722,2723],{"class":192},"# Info — use the sk-… value\n",[106,2725,2727,2729,2731,2733,2735,2737,2739,2741,2743,2745,2747,2749,2751,2753,2755,2757],{"class":108,"line":2726},18,[106,2728,113],{"class":112},[106,2730,262],{"class":116},[106,2732,125],{"class":124},[106,2734,129],{"class":128},[106,2736,360],{"class":120},[106,2738,135],{"class":124},[106,2740,274],{"class":116},[106,2742,125],{"class":124},[106,2744,150],{"class":120},[106,2746,153],{"class":128},[106,2748,135],{"class":124},[106,2750,320],{"class":116},[106,2752,125],{"class":124},[106,2754,379],{"class":120},[106,2756,382],{"class":128},[106,2758,283],{"class":124},[106,2760,2762],{"class":108,"line":2761},19,[106,2763,1156],{"emptyLinePlaceholder":1155},[106,2765,2767],{"class":108,"line":2766},20,[106,2768,2769],{"class":192},"# Update\n",[106,2771,2773,2775,2777,2779,2781,2783,2785,2787,2789,2791,2793,2795,2797,2799,2801,2803,2805,2808,2810,2813],{"class":108,"line":2772},21,[106,2774,113],{"class":112},[106,2776,117],{"class":116},[106,2778,121],{"class":120},[106,2780,125],{"class":124},[106,2782,129],{"class":128},[106,2784,413],{"class":120},[106,2786,135],{"class":124},[106,2788,274],{"class":116},[106,2790,125],{"class":124},[106,2792,150],{"class":120},[106,2794,153],{"class":128},[106,2796,135],{"class":124},[106,2798,274],{"class":116},[106,2800,125],{"class":124},[106,2802,167],{"class":120},[106,2804,135],{"class":124},[106,2806,2807],{"class":116}," -d",[106,2809,180],{"class":124},[106,2811,2812],{"class":120},"{\"key\":\"sk-…\",\"key_alias\":\"vkey-updated\"}",[106,2814,186],{"class":124},[106,2816,2818],{"class":108,"line":2817},22,[106,2819,1156],{"emptyLinePlaceholder":1155},[106,2821,2823],{"class":108,"line":2822},23,[106,2824,2825],{"class":192},"# Delete\n",[106,2827,2829,2831,2833,2835,2837,2839,2841,2843,2845,2847,2849,2851,2853,2855,2857,2859,2861,2863,2865,2867],{"class":108,"line":2828},24,[106,2830,113],{"class":112},[106,2832,117],{"class":116},[106,2834,121],{"class":120},[106,2836,125],{"class":124},[106,2838,129],{"class":128},[106,2840,485],{"class":120},[106,2842,135],{"class":124},[106,2844,274],{"class":116},[106,2846,125],{"class":124},[106,2848,150],{"class":120},[106,2850,153],{"class":128},[106,2852,135],{"class":124},[106,2854,274],{"class":116},[106,2856,125],{"class":124},[106,2858,167],{"class":120},[106,2860,135],{"class":124},[106,2862,2807],{"class":116},[106,2864,180],{"class":124},[106,2866,524],{"class":120},[106,2868,186],{"class":124},[106,2870,2872],{"class":108,"line":2871},25,[106,2873,2874],{"class":192},"# → subsequent GET \u002Fkey\u002Finfo?key=sk-… → 404 No key\n",[87,2876,2878],{"id":2877},"rules","Rules",[20,2880,2881,2886],{},[23,2882,2883,2885],{},[27,2884,199],{}," is required and must be non-empty on create and update.",[23,2887,2888,200,2890,2893,2894,2897,2898,2901],{},[53,2889,56],{"title":55},[44,2891,2892],{},"cannot"," call management routes (",[27,2895,2896],{},"POST \u002Fteam\u002Fnew"," with a v-key → ",[27,2899,2900],{},"401\u002F403","). They are inference-only.",[73,2903,2905,2906,204,2908,204,2910],{"id":2904},"choosing-models-rpm_limit-tpm_limit","Choosing ",[27,2907,207],{},[27,2909,228],{},[27,2911,231],{},[16,2913,2914,2915,2917],{},"Leave ",[27,2916,207],{}," empty for all curated models. Restrict per key when needed. Rate limits are optional per-key caps.",[16,2919,916,2920,2922],{},[782,2921,14],{"href":944}," for status codes and full endpoint tables",[922,2924,2925],{},"html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":102,"searchDepth":160,"depth":160,"links":2927},[2928,2929,2932],{"id":2432,"depth":142,"text":2433},{"id":2519,"depth":142,"text":2520,"children":2930},[2931],{"id":2877,"depth":160,"text":2878},{"id":2904,"depth":142,"text":2933},"Choosing models, rpm_limit, tpm_limit","Create, list, inspect, update and delete v-keys — from the dashboard or directly via the proxy API.",{},{"title":1484,"icon":2937},"i-lucide-settings-2",{"title":2421,"description":2934},"docs\u002Fmanaging-keys","nvsQx57ETT9rszHWCaEF4XpXx2KjltFBQOCctWqkbqc",{"id":2942,"title":2943,"body":2944,"description":3202,"extension":940,"meta":3203,"navigation":3204,"path":977,"seo":3206,"stem":3207,"__hash__":3208},"docs\u002Fdocs\u002Fmodels.md","Curated models — Cheap, tested, enough",{"type":8,"value":2945,"toc":3194},[2946,2950,2957,2965,2993,2996,3045,3049,3056,3074,3077,3081,3097,3109,3115,3121,3181,3184,3191],[11,2947,2949],{"id":2948},"curated-models","Curated models",[16,2951,2952,2953,2956],{},"Klunq Proxy does not expose the whole market. It fronts a ",[44,2954,2955],{},"small, tested set"," behind an OpenAI-compatible list. During the public beta that list is a single shared free endpoint — paid models with real pricing arrive with monetization.",[73,2958,2960,2961,2964],{"id":2959},"beta-free-ai-shared-free-endpoint","Beta: ",[27,2962,2963],{},"free-ai"," (shared free endpoint)",[20,2966,2967,2976,2983],{},[23,2968,2969,2970,2972,2973,1715],{},"Public name: ",[27,2971,2963],{}," — what clients send (",[27,2974,2975],{},"data-model=\"free-ai\"",[23,2977,2978,2979,2982],{},"Behind the name sits an OpenRouter free-model endpoint, ",[44,2980,2981],{},"shared by all users: roughly 50 requests\u002Fday in total",". When the daily pool is exhausted, inference returns rate-limit errors until it resets — this is an upstream limit, not a bug in your key or budget.",[23,2984,2985,2986,2989,2990,2992],{},"Cost resolves to ",[27,2987,2988],{},"$0.0"," per call, so budget checks are vacuous during beta (they cannot trip on zero spend) while v-keys, page-lock and spend tracking keep working normally. Tracked spend reads ",[27,2991,2988],{}," everywhere.",[16,2994,2995],{},"List available models (with any valid key):",[97,2997,2999],{"className":99,"code":2998,"language":101,"meta":102,"style":102},"curl -H \"Authorization: Bearer $VKEY\" \"$PROXY_URL\u002Fv1\u002Fmodels\"\ncurl -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \"$PROXY_URL\u002Fv1\u002Fmodels\"\n",[27,3000,3001,3023],{"__ignoreMap":102},[106,3002,3003,3005,3007,3009,3011,3013,3015,3017,3019,3021],{"class":108,"line":109},[106,3004,113],{"class":112},[106,3006,274],{"class":116},[106,3008,125],{"class":124},[106,3010,150],{"class":120},[106,3012,382],{"class":128},[106,3014,135],{"class":124},[106,3016,125],{"class":124},[106,3018,129],{"class":128},[106,3020,818],{"class":120},[106,3022,283],{"class":124},[106,3024,3025,3027,3029,3031,3033,3035,3037,3039,3041,3043],{"class":108,"line":142},[106,3026,113],{"class":112},[106,3028,274],{"class":116},[106,3030,125],{"class":124},[106,3032,150],{"class":120},[106,3034,153],{"class":128},[106,3036,135],{"class":124},[106,3038,125],{"class":124},[106,3040,129],{"class":128},[106,3042,818],{"class":120},[106,3044,283],{"class":124},[73,3046,3048],{"id":3047},"why-small-models-are-enough","Why small models are enough",[16,3050,3051,3052,3055],{},"The Klunq Widget is a ",[44,3053,3054],{},"page-agent",": read content, click, fill forms, answer from the visible page. It does not need multi-step coding or heavy reasoning.",[20,3057,3058,3064,3071],{},[23,3059,3060,3063],{},[44,3061,3062],{},"Small ~30B open models"," answer “what is this page about?”, “fill checkout”, “compare plans” reliably.",[23,3065,3066,3067,3070],{},"Pricing is ",[44,3068,3069],{},"10–100× cheaper"," than frontier multi-hundred-bilion parameter models.",[23,3072,3073],{},"Overkill models add latency and cost with little UX gain for this task.",[16,3075,3076],{},"Klunq tests each model against page tasks before adding it. The proxy will only list models that pass that bar.",[73,3078,3080],{"id":3079},"what-changes-next","What changes next",[20,3082,3083,3086,3089],{},[23,3084,3085],{},"Add more open models in the same weight class (names TBA).",[23,3087,3088],{},"Real per-token prices per model.",[23,3090,3091,3092,3094,3095,241],{},"No widget change required — just ",[27,3093,2107],{}," versus ",[27,3096,818],{},[1255,3098,3100],{"color":1257,"icon":3099},"i-lucide-piggy-bank",[16,3101,3102,3103,200,3106,3108],{},"For a SMB spending view: a 30B model at $0.2 \u002F 1M tokens handling ~500 page queries\u002Fday stays well under a ",[27,3104,3105],{},"1$\u002Fday",[53,3107,62],{"title":973}," cap. Frontier pricing would exhaust the same cap in hours.",[73,3110,3112,3113],{"id":3111},"choosing-a-model-for-a-v-key","Choosing a model for a ",[53,3114,62],{"title":973},[16,3116,3117,3118,3120],{},"Either leave ",[27,3119,207],{}," empty (all allowed) or restrict:",[97,3122,3124],{"className":99,"code":3123,"language":101,"meta":102,"style":102},"curl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"landing\",\"models\":[\"free-ai\"],\"max_budget\":2}'\n",[27,3125,3126,3144,3158,3170],{"__ignoreMap":102},[106,3127,3128,3130,3132,3134,3136,3138,3140,3142],{"class":108,"line":109},[106,3129,113],{"class":112},[106,3131,117],{"class":116},[106,3133,121],{"class":120},[106,3135,125],{"class":124},[106,3137,129],{"class":128},[106,3139,132],{"class":120},[106,3141,135],{"class":124},[106,3143,139],{"class":138},[106,3145,3146,3148,3150,3152,3154,3156],{"class":108,"line":142},[106,3147,145],{"class":116},[106,3149,125],{"class":124},[106,3151,150],{"class":120},[106,3153,153],{"class":128},[106,3155,135],{"class":124},[106,3157,139],{"class":138},[106,3159,3160,3162,3164,3166,3168],{"class":108,"line":160},[106,3161,145],{"class":116},[106,3163,125],{"class":124},[106,3165,167],{"class":120},[106,3167,135],{"class":124},[106,3169,139],{"class":138},[106,3171,3172,3174,3176,3179],{"class":108,"line":174},[106,3173,177],{"class":116},[106,3175,180],{"class":124},[106,3177,3178],{"class":120},"{\"key_alias\":\"landing\",\"models\":[\"free-ai\"],\"max_budget\":2}",[106,3180,186],{"class":124},[16,3182,3183],{},"The proxy will reject completions that request a non-allowed model.",[16,3185,916,3186,1480,3189],{},[782,3187,3188],{"href":1910},"Integration — widget → proxy",[782,3190,1497],{"href":1499},[922,3192,3193],{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}",{"title":102,"searchDepth":160,"depth":160,"links":3195},[3196,3198,3199,3200],{"id":2959,"depth":142,"text":3197},"Beta: free-ai (shared free endpoint)",{"id":3047,"depth":142,"text":3048},{"id":3079,"depth":142,"text":3080},{"id":3111,"depth":142,"text":3201},"Choosing a model for a v-key","A small list of tested open models suited for page-agents. Small 30B class beats frontier models on cost for this use case.",{},{"title":978,"icon":3205},"i-lucide-layers",{"title":2943,"description":3202},"docs\u002Fmodels","5SwJ8sDFwlA0eLyMRQLEYdMqFzXHW__RwU6FNpNh3zk",{"id":3210,"title":1940,"body":3211,"description":3723,"extension":940,"meta":3724,"navigation":3725,"path":1939,"seo":3727,"stem":3728,"__hash__":3729},"docs\u002Fdocs\u002Fquickstart.md",{"type":8,"value":3212,"toc":3718},[3213,3216,3219,3223,3292,3301,3305,3318,3621,3628,3632,3641,3709,3716],[11,3214,2100],{"id":3215},"quickstart",[16,3217,3218],{},"Pick a path — same result.",[73,3220,3222],{"id":3221},"a-dashboard-ui-no-curl","A) Dashboard UI (no curl)",[3224,3225,3226,3239,3245,3268,3280],"ol",{},[23,3227,3228,3229,3232,3233,3236,3237,1715],{},"Sign in and go to ",[27,3230,3231],{},"\u002Fdashboard"," — you will see your ",[44,3234,3235],{},"Team API key"," (management key, ",[27,3238,50],{},[23,3240,3241,3242,241],{},"Open ",[44,3243,3244],{},"Dashboard → v-keys → Create",[23,3246,3247,3248,3250,3251,3253,3254,225,3256,3253,3258,3260,3261,204,3264,218,3266,241],{},"Fill ",[27,3249,199],{}," (required), ",[27,3252,211],{}," (e.g. ",[27,3255,1037],{},[27,3257,214],{},[27,3259,217],{},"), optional ",[27,3262,3263],{},"models=gemma4",[27,3265,228],{},[27,3267,231],{},[23,3269,3270,3271,3273,3274,200,3276,3279],{},"Click ",[44,3272,1593],{}," → copy the shown ",[27,3275,50],{},[44,3277,3278],{},"once"," (hashed afterwards).",[23,3281,3282,3283,3286,3287,780,3290,1715],{},"Paste into your page’s widget: ",[27,3284,3285],{},"data-base-url=\"https:\u002F\u002Fproxy.klunqlabs.com\u002Fv1\""," + ",[27,3288,3289],{},"data-api-key=\"sk-…\"",[782,3291,1911],{"href":1910},[16,3293,3294,3295,3297,3298,3300],{},"List, edit (",[27,3296,390],{},"), and delete (",[27,3299,465],{},") from the same dashboard.",[73,3302,3304],{"id":3303},"b-programmatic-management-key","B) Programmatic (management key)",[16,3306,3307,3308,204,3311,3314,3315,3317],{},"Prerequisites: ",[27,3309,3310],{},"PROXY_URL=https:\u002F\u002Fproxy.klunqlabs.com",[27,3312,3313],{},"MODEL=gemma4",", and your ",[27,3316,2546],{}," from the dashboard (keep it secret on the server).",[97,3319,3321],{"className":99,"code":3320,"language":101,"meta":102,"style":102},"# Mint a v-key with your management key\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"vkey-quickstart\",\"models\":[\"gemma4\"],\"max_budget\":1,\"budget_duration\":\"30d\"}'\n# → {\"key\":\"sk-…\",\"token_id\":\"…\",\"max_budget\":1}\n\n# Use it — the widget handles the watermarked prompt; raw curl must include a page-bound system prompt\ncurl -X POST \"$PROXY_URL\u002Fv1\u002Fchat\u002Fcompletions\" \\\n  -H \"Authorization: Bearer $VIRTUAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[\n        {\"role\":\"system\",\"content\":\"You are the page agent. watermark\"},\n        {\"role\":\"user\",\"content\":\"Summarize this page in one sentence.\"}]}'\n# → finish_reason:\"stop\"\n\n# List, inspect, update, delete (all via management key)\ncurl -G \"$PROXY_URL\u002Fkey\u002Flist\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\"\ncurl -G \"$PROXY_URL\u002Fkey\u002Finfo\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" --data-urlencode \"key=$VIRTUAL_KEY\"\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fupdate\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" -H \"Content-Type: application\u002Fjson\" -d '{\"key\":\"sk-…\",\"max_budget\":2}'\ncurl -X POST \"$PROXY_URL\u002Fkey\u002Fdelete\" -H \"Authorization: Bearer $TEAM_MGMT_KEY\" -H \"Content-Type: application\u002Fjson\" -d '{\"keys\":[\"sk-…\"]}'\n",[27,3322,3323,3328,3346,3360,3372,3383,3388,3392,3397,3416,3431,3443,3452,3457,3464,3469,3473,3478,3502,3536,3579],{"__ignoreMap":102},[106,3324,3325],{"class":108,"line":109},[106,3326,3327],{"class":192},"# Mint a v-key with your management key\n",[106,3329,3330,3332,3334,3336,3338,3340,3342,3344],{"class":108,"line":142},[106,3331,113],{"class":112},[106,3333,117],{"class":116},[106,3335,121],{"class":120},[106,3337,125],{"class":124},[106,3339,129],{"class":128},[106,3341,132],{"class":120},[106,3343,135],{"class":124},[106,3345,139],{"class":138},[106,3347,3348,3350,3352,3354,3356,3358],{"class":108,"line":160},[106,3349,145],{"class":116},[106,3351,125],{"class":124},[106,3353,150],{"class":120},[106,3355,153],{"class":128},[106,3357,135],{"class":124},[106,3359,139],{"class":138},[106,3361,3362,3364,3366,3368,3370],{"class":108,"line":174},[106,3363,145],{"class":116},[106,3365,125],{"class":124},[106,3367,167],{"class":120},[106,3369,135],{"class":124},[106,3371,139],{"class":138},[106,3373,3374,3376,3378,3381],{"class":108,"line":189},[106,3375,177],{"class":116},[106,3377,180],{"class":124},[106,3379,3380],{"class":120},"{\"key_alias\":\"vkey-quickstart\",\"models\":[\"gemma4\"],\"max_budget\":1,\"budget_duration\":\"30d\"}",[106,3382,186],{"class":124},[106,3384,3385],{"class":108,"line":738},[106,3386,3387],{"class":192},"# → {\"key\":\"sk-…\",\"token_id\":\"…\",\"max_budget\":1}\n",[106,3389,3390],{"class":108,"line":751},[106,3391,1156],{"emptyLinePlaceholder":1155},[106,3393,3394],{"class":108,"line":1217},[106,3395,3396],{"class":192},"# Use it — the widget handles the watermarked prompt; raw curl must include a page-bound system prompt\n",[106,3398,3399,3401,3403,3405,3407,3409,3412,3414],{"class":108,"line":2629},[106,3400,113],{"class":112},[106,3402,117],{"class":116},[106,3404,121],{"class":120},[106,3406,125],{"class":124},[106,3408,129],{"class":128},[106,3410,3411],{"class":120},"\u002Fv1\u002Fchat\u002Fcompletions",[106,3413,135],{"class":124},[106,3415,139],{"class":138},[106,3417,3418,3420,3422,3424,3427,3429],{"class":108,"line":2634},[106,3419,145],{"class":116},[106,3421,125],{"class":124},[106,3423,150],{"class":120},[106,3425,3426],{"class":128},"$VIRTUAL_KEY",[106,3428,135],{"class":124},[106,3430,139],{"class":138},[106,3432,3433,3435,3437,3439,3441],{"class":108,"line":2640},[106,3434,145],{"class":116},[106,3436,125],{"class":124},[106,3438,167],{"class":120},[106,3440,135],{"class":124},[106,3442,139],{"class":138},[106,3444,3445,3447,3449],{"class":108,"line":2665},[106,3446,177],{"class":116},[106,3448,180],{"class":124},[106,3450,3451],{"class":120},"{\"model\":\"gemma4\",\"messages\":[\n",[106,3453,3454],{"class":108,"line":2671},[106,3455,3456],{"class":120},"        {\"role\":\"system\",\"content\":\"You are the page agent. watermark\"},\n",[106,3458,3459,3462],{"class":108,"line":2676},[106,3460,3461],{"class":120},"        {\"role\":\"user\",\"content\":\"Summarize this page in one sentence.\"}]}",[106,3463,186],{"class":124},[106,3465,3466],{"class":108,"line":2682},[106,3467,3468],{"class":192},"# → finish_reason:\"stop\"\n",[106,3470,3471],{"class":108,"line":2715},[106,3472,1156],{"emptyLinePlaceholder":1155},[106,3474,3475],{"class":108,"line":2720},[106,3476,3477],{"class":192},"# List, inspect, update, delete (all via management key)\n",[106,3479,3480,3482,3484,3486,3488,3490,3492,3494,3496,3498,3500],{"class":108,"line":2726},[106,3481,113],{"class":112},[106,3483,262],{"class":116},[106,3485,125],{"class":124},[106,3487,129],{"class":128},[106,3489,269],{"class":120},[106,3491,135],{"class":124},[106,3493,274],{"class":116},[106,3495,125],{"class":124},[106,3497,150],{"class":120},[106,3499,153],{"class":128},[106,3501,283],{"class":124},[106,3503,3504,3506,3508,3510,3512,3514,3516,3518,3520,3522,3524,3526,3528,3530,3532,3534],{"class":108,"line":2761},[106,3505,113],{"class":112},[106,3507,262],{"class":116},[106,3509,125],{"class":124},[106,3511,129],{"class":128},[106,3513,360],{"class":120},[106,3515,135],{"class":124},[106,3517,274],{"class":116},[106,3519,125],{"class":124},[106,3521,150],{"class":120},[106,3523,153],{"class":128},[106,3525,135],{"class":124},[106,3527,320],{"class":116},[106,3529,125],{"class":124},[106,3531,379],{"class":120},[106,3533,3426],{"class":128},[106,3535,283],{"class":124},[106,3537,3538,3540,3542,3544,3546,3548,3550,3552,3554,3556,3558,3560,3562,3564,3566,3568,3570,3572,3574,3577],{"class":108,"line":2766},[106,3539,113],{"class":112},[106,3541,117],{"class":116},[106,3543,121],{"class":120},[106,3545,125],{"class":124},[106,3547,129],{"class":128},[106,3549,413],{"class":120},[106,3551,135],{"class":124},[106,3553,274],{"class":116},[106,3555,125],{"class":124},[106,3557,150],{"class":120},[106,3559,153],{"class":128},[106,3561,135],{"class":124},[106,3563,274],{"class":116},[106,3565,125],{"class":124},[106,3567,167],{"class":120},[106,3569,135],{"class":124},[106,3571,2807],{"class":116},[106,3573,180],{"class":124},[106,3575,3576],{"class":120},"{\"key\":\"sk-…\",\"max_budget\":2}",[106,3578,186],{"class":124},[106,3580,3581,3583,3585,3587,3589,3591,3593,3595,3597,3599,3601,3603,3605,3607,3609,3611,3613,3615,3617,3619],{"class":108,"line":2772},[106,3582,113],{"class":112},[106,3584,117],{"class":116},[106,3586,121],{"class":120},[106,3588,125],{"class":124},[106,3590,129],{"class":128},[106,3592,485],{"class":120},[106,3594,135],{"class":124},[106,3596,274],{"class":116},[106,3598,125],{"class":124},[106,3600,150],{"class":120},[106,3602,153],{"class":128},[106,3604,135],{"class":124},[106,3606,274],{"class":116},[106,3608,125],{"class":124},[106,3610,167],{"class":120},[106,3612,135],{"class":124},[106,3614,2807],{"class":116},[106,3616,180],{"class":124},[106,3618,524],{"class":120},[106,3620,186],{"class":124},[1255,3622,3623],{"color":1718,"icon":1719},[16,3624,3625,3626,241],{},"Store the management key in server and never share it. The browser only ever sees ",[53,3627,56],{"title":55},[73,3629,3631],{"id":3630},"verify-page-lock","Verify page-lock",[16,3633,3634,3635,3637,3638,1112],{},"Try reusing the ",[53,3636,62],{"title":973}," for a generic prompt — it should ",[27,3639,3640],{},"block",[97,3642,3644],{"className":99,"code":3643,"language":101,"meta":102,"style":102},"curl -i -X POST \"$PROXY_URL\u002Fv1\u002Fchat\u002Fcompletions\" \\\n  -H \"Authorization: Bearer $VIRTUAL_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[{\"role\":\"user\",\"content\":\"Write a python fibonacci\"}]}'\n# → HTTP\u002F1.1 400 Bad Request — Guardrail Violation\n",[27,3645,3646,3667,3681,3693,3704],{"__ignoreMap":102},[106,3647,3648,3650,3653,3655,3657,3659,3661,3663,3665],{"class":108,"line":109},[106,3649,113],{"class":112},[106,3651,3652],{"class":116}," -i",[106,3654,117],{"class":116},[106,3656,121],{"class":120},[106,3658,125],{"class":124},[106,3660,129],{"class":128},[106,3662,3411],{"class":120},[106,3664,135],{"class":124},[106,3666,139],{"class":138},[106,3668,3669,3671,3673,3675,3677,3679],{"class":108,"line":142},[106,3670,145],{"class":116},[106,3672,125],{"class":124},[106,3674,150],{"class":120},[106,3676,3426],{"class":128},[106,3678,135],{"class":124},[106,3680,139],{"class":138},[106,3682,3683,3685,3687,3689,3691],{"class":108,"line":160},[106,3684,145],{"class":116},[106,3686,125],{"class":124},[106,3688,167],{"class":120},[106,3690,135],{"class":124},[106,3692,139],{"class":138},[106,3694,3695,3697,3699,3702],{"class":108,"line":174},[106,3696,177],{"class":116},[106,3698,180],{"class":124},[106,3700,3701],{"class":120},"{\"model\":\"gemma4\",\"messages\":[{\"role\":\"user\",\"content\":\"Write a python fibonacci\"}]}",[106,3703,186],{"class":124},[106,3705,3706],{"class":108,"line":189},[106,3707,3708],{"class":192},"# → HTTP\u002F1.1 400 Bad Request — Guardrail Violation\n",[16,3710,916,3711,1480,3713],{},[782,3712,1943],{"href":1751},[782,3714,3715],{"href":1910},"Integration — Widget + proxy",[922,3717,1740],{},{"title":102,"searchDepth":160,"depth":160,"links":3719},[3720,3721,3722],{"id":3221,"depth":142,"text":3222},{"id":3303,"depth":142,"text":3304},{"id":3630,"depth":142,"text":3631},"From zero to a page-locked, budget-capped v-key in minutes — UI or API.",{},{"title":2100,"icon":3726},"i-lucide-rocket",{"title":1940,"description":3723},"docs\u002Fquickstart","1EDpYmcBhWxPDBk7ouWjwLjK6AulUHvyxv3OoXXMVgA",{"id":3731,"title":3732,"body":3733,"description":3895,"extension":940,"meta":3896,"navigation":3897,"path":919,"seo":3899,"stem":3900,"__hash__":3901},"docs\u002Fdocs\u002Fsecurity.md","Security & limits",{"type":8,"value":3734,"toc":3889},[3735,3738,3742,3745,3774,3778,3817,3821,3849,3853,3868,3883],[11,3736,3732],{"id":3737},"security-limits",[73,3739,3741],{"id":3740},"what-protects-a-leaked-v-key","What protects a leaked v-key",[16,3743,3744],{},"Two layers apply:",[3224,3746,3747,3761],{},[23,3748,3749,3752,3753,47,3756,3758,3759,241],{},[44,3750,3751],{},"Watermark (page-lock)"," — requires the page-bound prompt. Reuse for coding\u002Fmath blocked with ",[27,3754,3755],{},"400 Bad Request",[27,3757,872],{},"). See ",[782,3760,785],{"href":784},[23,3762,3763,3766,3767,218,3769,3771,3772,241],{},[44,3764,3765],{},"Budget (hard cap)"," — workspace pool + ",[27,3768,211],{},[27,3770,214],{}," per key. Even if the prompt satisfied the watermark, spend stops at the cap. See ",[782,3773,1497],{"href":1499},[73,3775,3777],{"id":3776},"roles","Roles",[828,3779,3780,3790],{},[831,3781,3782],{},[834,3783,3784,3787],{},[837,3785,3786],{},"Principal",[837,3788,3789],{},"Can do",[844,3791,3792,3804],{},[834,3793,3794,3798],{},[849,3795,3796],{},[44,3797,46],{},[849,3799,3800,3801,3803],{},"Manage your ",[53,3802,56],{"title":55},", read your usage",[834,3805,3806,3810],{},[849,3807,3808],{},[44,3809,62],{},[849,3811,3812,3813,204,3815,1406],{},"Inference (",[27,3814,3411],{},[27,3816,818],{},[73,3818,3820],{"id":3819},"key-hygiene","Key hygiene",[20,3822,3823,3831,3841],{},[23,3824,3825,3828,3829,241],{},[44,3826,3827],{},"Never ship management keys to the browser."," Store them on the server. Only v-keys belong in ",[27,3830,1578],{},[23,3832,3833,3834,3836,3837,3840],{},"Copy v-keys ",[44,3835,3278],{},". ",[27,3838,3839],{},"GET \u002Fkey\u002Finfo"," shows metadata, not the raw secret; recreate if lost.",[23,3842,3843,3844,3286,3846,3848],{},"Rotate by ",[27,3845,465],{},[27,3847,92],{}," with same alias or new one, same alias is recommended to keep track between rotated virtual keys.",[73,3850,3852],{"id":3851},"what-the-proxy-does-not-do","What the proxy does not do",[20,3854,3855,3858],{},[23,3856,3857],{},"No budget limits unless you set them.",[23,3859,3860,3861,218,3863,218,3865,3867],{},"No rate limit by default beyond optional ",[27,3862,228],{},[27,3864,231],{},[27,3866,234],{}," you set per v-key.",[1255,3869,3871],{"color":1571,"icon":3870},"i-lucide-triangle-alert",[16,3872,3873,3874,604,3877,1824,3880,241],{},"The proxy is health-checked via ",[27,3875,3876],{},"GET \u002Fhealth\u002Freadiness",[27,3878,3879],{},"{\"status\":\"healthy\",\"db\":\"connected\"}",[27,3881,3882],{},"https:\u002F\u002Fproxy.klunqlabs.com\u002Fhealth\u002Freadiness",[16,3884,916,3885,1480,3887],{},[782,3886,2100],{"href":1939},[782,3888,14],{"href":944},{"title":102,"searchDepth":160,"depth":160,"links":3890},[3891,3892,3893,3894],{"id":3740,"depth":142,"text":3741},{"id":3776,"depth":142,"text":3777},{"id":3819,"depth":142,"text":3820},{"id":3851,"depth":142,"text":3852},"Watermarking, budgets, key hygiene and what the proxy does not do.",{},{"title":920,"icon":3898},"i-lucide-shield",{"title":3732,"description":3895},"docs\u002Fsecurity","09ko4iSFaWIbdPjpLiAoHtIlm9YaS0MCA2R_CQBaAL4",{"id":3903,"title":3904,"body":3905,"description":4214,"extension":940,"meta":4215,"navigation":4216,"path":1465,"seo":4218,"stem":4219,"__hash__":4220},"docs\u002Fdocs\u002Fstrategies.md","Deployment strategies — Who gets which key",{"type":8,"value":3906,"toc":4205},[3907,3911,3916,3920,3932,3957,3963,3967,3972,3980,4040,4058,4063,4077,4081,4084,4109,4112,4116,4119,4138,4141,4145,4162,4175,4179,4196,4202],[11,3908,3910],{"id":3909},"deployment-strategies","Deployment strategies",[16,3912,3913,3915],{},[53,3914,56],{"title":55}," make many rollout styles trivial. Pick one, or mix.",[73,3917,3919],{"id":3918},"_1-signed-in-only","1) Signed-in only",[3921,3922,3923],"blockquote",{},[16,3924,3925,3926,3928,3929,241],{},"Only authenticated users get a ",[53,3927,62],{"title":973},". Anonymous visitors get ",[27,3930,3931],{},"none",[20,3933,3934,3937,3951],{},[23,3935,3936],{},"Klunq Widget shows read-only state with a callout: “Sign in to chat with the page agent.”",[23,3938,3939,3940,3942,3943,3945,3946,3948,3949,1715],{},"On sign-in, your backend uses the management key to call ",[27,3941,92],{}," with a user-specific ",[27,3944,199],{}," and returns the ",[27,3947,50],{}," to the widget (",[27,3950,1578],{},[23,3952,3953,3954,241],{},"Each user gets their own micro-budget, e.g. ",[27,3955,3956],{},"2$\u002F30d",[16,3958,3959,3962],{},[44,3960,3961],{},"Best for:"," apps where anonymous AI would be abuse-prone.",[73,3964,3966],{"id":3965},"_2-anonymous-global-pot","2) Anonymous global pot",[3921,3968,3969],{},[16,3970,3971],{},"One shared key for unsigned visitors, capped tightly.",[20,3973,3974],{},[23,3975,3976,3977,1112],{},"Create a single v-key with a deliberately low budget that ",[44,3978,3979],{},"resets daily",[97,3981,3983],{"className":99,"code":3982,"language":101,"meta":102,"style":102},"curl -X POST \"$PROXY_URL\u002Fkey\u002Fgenerate\" \\\n  -H \"Authorization: Bearer $TEAM_MGMT_KEY\" \\\n  -H \"Content-Type: application\u002Fjson\" \\\n  -d '{\"key_alias\":\"default\",\"max_budget\":1,\"budget_duration\":\"1d\",\"models\":[\"gemma4\"]}'\n",[27,3984,3985,4003,4017,4029],{"__ignoreMap":102},[106,3986,3987,3989,3991,3993,3995,3997,3999,4001],{"class":108,"line":109},[106,3988,113],{"class":112},[106,3990,117],{"class":116},[106,3992,121],{"class":120},[106,3994,125],{"class":124},[106,3996,129],{"class":128},[106,3998,132],{"class":120},[106,4000,135],{"class":124},[106,4002,139],{"class":138},[106,4004,4005,4007,4009,4011,4013,4015],{"class":108,"line":142},[106,4006,145],{"class":116},[106,4008,125],{"class":124},[106,4010,150],{"class":120},[106,4012,153],{"class":128},[106,4014,135],{"class":124},[106,4016,139],{"class":138},[106,4018,4019,4021,4023,4025,4027],{"class":108,"line":160},[106,4020,145],{"class":116},[106,4022,125],{"class":124},[106,4024,167],{"class":120},[106,4026,135],{"class":124},[106,4028,139],{"class":138},[106,4030,4031,4033,4035,4038],{"class":108,"line":174},[106,4032,177],{"class":116},[106,4034,180],{"class":124},[106,4036,4037],{"class":120},"{\"key_alias\":\"default\",\"max_budget\":1,\"budget_duration\":\"1d\",\"models\":[\"gemma4\"]}",[106,4039,186],{"class":124},[20,4041,4042,4055],{},[23,4043,4044,4045,4047,4048,4051,4052,4054],{},"Bake its ",[27,4046,50],{}," into the public ",[27,4049,4050],{},"\u003Cscript data-api-key=\"sk-default…\">",". All anonymous traffic shares the ",[27,4053,3105],{}," pot.",[23,4056,4057],{},"Signed-in users still get a personal key (strategy 1) — anonymous pot caps trial usage without a backend.",[16,4059,4060,4062],{},[44,4061,3961],{}," landing pages that want anonymous “try it” but bounded cost.",[1255,4064,4066],{"color":1571,"icon":4065},"i-lucide-alert-triangle",[16,4067,4068,4069,4071,4072,4074,4075,241],{},"Anonymous keys are shared — one burst can exhaust the day. Keep the cap small and duration short (",[27,4070,221],{}," or even ",[27,4073,224],{},"). Monitor usage via the dashboard or ",[27,4076,626],{},[73,4078,4080],{"id":4079},"_3-hybrid-default-pot-per-user-upgrades","3) Hybrid — default pot + per-user upgrades",[16,4082,4083],{},"Combine both:",[20,4085,4086,4094,4103],{},[23,4087,4088,4089,604,4091,4093],{},"Public ",[27,4090,1174],{},[27,4092,3105],{}," (global)",[23,4095,4096,4097,604,4100],{},"On sign-in → mint ",[27,4098,4099],{},"user-{id}",[27,4101,4102],{},"5$\u002F30d",[23,4104,4105,4106,4108],{},"Widget swaps ",[27,4107,1578],{}," on auth state change.",[16,4110,4111],{},"Anonymous users see degraded\u002Flow-quota AI; signed-in users are unconstrained (within their larger cap). This nudges sign-ups.",[73,4113,4115],{"id":4114},"_4-per-surface-keys","4) Per-surface keys",[16,4117,4118],{},"Give each surface its own alias:",[20,4120,4121,4132],{},[23,4122,4123,204,4125,204,4127,204,4129],{},[27,4124,1730],{},[27,4126,1733],{},[27,4128,1736],{},[27,4130,4131],{},"support",[23,4133,4134,4135],{},"Or per-tenant: ",[27,4136,4137],{},"tenant-{id}",[16,4139,4140],{},"Spend per alias shows in the usage dashboard.",[73,4142,4144],{"id":4143},"_5-other-ideas","5) Other ideas",[20,4146,4147,4154],{},[23,4148,4149,4150,4153],{},"Ephemeral session keys (",[27,4151,4152],{},"budget_duration:\"1h\"","), deleted on tab close.",[23,4155,4156,4157,204,4159,4161],{},"Rate-limited keys (",[27,4158,228],{},[27,4160,231],{},") for bots.",[16,4163,4164,4165,4168,4169,4171,4172,4174],{},"All strategies use the ",[44,4166,4167],{},"same embed"," — see ",[782,4170,1911],{"href":1910},". Only ",[27,4173,1578],{}," changes.",[87,4176,4178],{"id":4177},"choosing-reset-cadence","Choosing reset cadence",[20,4180,4181,4186,4191],{},[23,4182,4183,4185],{},[27,4184,217],{}," — matches monthly billing, best for per-user pots",[23,4187,4188,4190],{},[27,4189,221],{}," — daily anonymous pot",[23,4192,4193,4195],{},[27,4194,224],{}," — demo rooms or per-session",[16,4197,916,4198,1480,4200],{},[782,4199,1911],{"href":1910},[782,4201,1484],{"href":1483},[922,4203,4204],{},"html pre.shiki code .sbgvK, html code.shiki .sbgvK{--shiki-light:#E2931D;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .stzsN, html code.shiki .stzsN{--shiki-light:#91B859;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}",{"title":102,"searchDepth":160,"depth":160,"links":4206},[4207,4208,4209,4210,4211],{"id":3918,"depth":142,"text":3919},{"id":3965,"depth":142,"text":3966},{"id":4079,"depth":142,"text":4080},{"id":4114,"depth":142,"text":4115},{"id":4143,"depth":142,"text":4144,"children":4212},[4213],{"id":4177,"depth":160,"text":4178},"Pick a pot-per-visitor strategy that matches your auth model — signed-in users, anonymous global pots, or a hybrid.",{},{"title":1466,"icon":4217},"i-lucide-users-round",{"title":3904,"description":4214},"docs\u002Fstrategies","G60NBtw5LPeQ_vfgSuAY26Qr-1Ke-wRJYSHVgLREoOo",{"id":4222,"title":4223,"body":4224,"description":4561,"extension":940,"meta":4562,"navigation":4563,"path":784,"seo":4565,"stem":4566,"__hash__":4567},"docs\u002Fdocs\u002Fwatermarking.md","Watermarking — Page-locked keys that cannot be repurposed",{"type":8,"value":4225,"toc":4555},[4226,4230,4242,4246,4249,4261,4263,4287,4291,4303,4309,4521,4525,4542,4547,4553],[11,4227,4229],{"id":4228},"page-lock-watermark","Page-lock — watermark",[16,4231,1514,4232,4234,4235,4238,4239,4241],{},[53,4233,62],{"title":973}," is only useful ",[44,4236,4237],{},"inside your page",". If someone copies the ",[27,4240,50],{}," from devtools and tries to use it for coding, math or generic chat, the request is rejected.",[73,4243,4245],{"id":4244},"how-it-works","How it works",[16,4247,4248],{},"Every request through the proxy is inspected before it reaches the model. The proxy requires a page-specific watermark in the system prompt — the Klunq Widget sends it automatically. Requests that do not carry the watermark, or that try to move the system prompt, are blocked.",[20,4250,4251,4258],{},[23,4252,4253,4254,4257],{},"Runs ",[44,4255,4256],{},"on every request",", no client opt-in.",[23,4259,4260],{},"Only the widget’s page-bound prompt satisfies the check.",[73,4262,2878],{"id":2877},[3224,4264,4265,4271,4278,4284],{},[23,4266,4267,4270],{},[27,4268,4269],{},"messages"," must be non-empty",[23,4272,4273,4274,4277],{},"At most ",[44,4275,4276],{},"one"," system message",[23,4279,4280,4281],{},"The system message must be ",[27,4282,4283],{},"messages[0]",[23,4285,4286],{},"It must contain the required watermark (handled by the widget)",[73,4288,4290],{"id":4289},"what-the-client-sees","What the client sees",[16,4292,4293,4294,4299,4300,4302],{},"The proxy rejects them with ",[44,4295,4296,4297],{},"HTTP ",[27,4298,3755],{}," containing a ",[27,4301,872],{}," message.",[16,4304,4305,4306,4308],{},"The widget is built to send a watermarked system prompt that satisfies this. Direct ",[27,4307,113],{}," without it is blocked:",[97,4310,4312],{"className":99,"code":4311,"language":101,"meta":102,"style":102},"# Blocked — system not first\ncurl -i -X POST \"$PROXY_URL\u002Fv1\u002Fchat\u002Fcompletions\" \\\n  -H \"Authorization: Bearer $VKEY\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[\n        {\"role\":\"user\",\"content\":\"hi\"},\n        {\"role\":\"system\",\"content\":\"… watermark\"}]}'\n# → HTTP\u002F1.1 400 Bad Request\n#   Guardrail Violation: system message, when present, must be the first element in messages\n\n# Blocked — missing watermark\ncurl -i -X POST \"$PROXY_URL\u002Fv1\u002Fchat\u002Fcompletions\" \\\n  -H \"Authorization: Bearer $VKEY\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[\n        {\"role\":\"system\",\"content\":\"You are helpful.\"},\n        {\"role\":\"user\",\"content\":\"hi\"}]}'\n# → HTTP\u002F1.1 400 Bad Request\n#   Guardrail Violation: messages[0] content must contain the required watermark\n\n# Allowed (widget does this for you)\ncurl -X POST \"$PROXY_URL\u002Fv1\u002Fchat\u002Fcompletions\" \\\n  -H \"Authorization: Bearer $VKEY\" \\\n  -d '{\"model\":\"gemma4\",\"messages\":[\n        {\"role\":\"system\",\"content\":\"You are the page agent for https:\u002F\u002Fexample.com. watermark\"},\n        {\"role\":\"user\",\"content\":\"Summarize this page.\"}]}'\n# → HTTP\u002F1.1 200 OK  finish_reason:\"stop\"\n",[27,4313,4314,4319,4339,4353,4361,4366,4373,4378,4383,4387,4392,4412,4426,4434,4439,4446,4450,4455,4459,4464,4482,4496,4504,4509,4516],{"__ignoreMap":102},[106,4315,4316],{"class":108,"line":109},[106,4317,4318],{"class":192},"# Blocked — system not first\n",[106,4320,4321,4323,4325,4327,4329,4331,4333,4335,4337],{"class":108,"line":142},[106,4322,113],{"class":112},[106,4324,3652],{"class":116},[106,4326,117],{"class":116},[106,4328,121],{"class":120},[106,4330,125],{"class":124},[106,4332,129],{"class":128},[106,4334,3411],{"class":120},[106,4336,135],{"class":124},[106,4338,139],{"class":138},[106,4340,4341,4343,4345,4347,4349,4351],{"class":108,"line":160},[106,4342,145],{"class":116},[106,4344,125],{"class":124},[106,4346,150],{"class":120},[106,4348,382],{"class":128},[106,4350,135],{"class":124},[106,4352,139],{"class":138},[106,4354,4355,4357,4359],{"class":108,"line":174},[106,4356,177],{"class":116},[106,4358,180],{"class":124},[106,4360,3451],{"class":120},[106,4362,4363],{"class":108,"line":189},[106,4364,4365],{"class":120},"        {\"role\":\"user\",\"content\":\"hi\"},\n",[106,4367,4368,4371],{"class":108,"line":738},[106,4369,4370],{"class":120},"        {\"role\":\"system\",\"content\":\"… watermark\"}]}",[106,4372,186],{"class":124},[106,4374,4375],{"class":108,"line":751},[106,4376,4377],{"class":192},"# → HTTP\u002F1.1 400 Bad Request\n",[106,4379,4380],{"class":108,"line":1217},[106,4381,4382],{"class":192},"#   Guardrail Violation: system message, when present, must be the first element in messages\n",[106,4384,4385],{"class":108,"line":2629},[106,4386,1156],{"emptyLinePlaceholder":1155},[106,4388,4389],{"class":108,"line":2634},[106,4390,4391],{"class":192},"# Blocked — missing watermark\n",[106,4393,4394,4396,4398,4400,4402,4404,4406,4408,4410],{"class":108,"line":2640},[106,4395,113],{"class":112},[106,4397,3652],{"class":116},[106,4399,117],{"class":116},[106,4401,121],{"class":120},[106,4403,125],{"class":124},[106,4405,129],{"class":128},[106,4407,3411],{"class":120},[106,4409,135],{"class":124},[106,4411,139],{"class":138},[106,4413,4414,4416,4418,4420,4422,4424],{"class":108,"line":2665},[106,4415,145],{"class":116},[106,4417,125],{"class":124},[106,4419,150],{"class":120},[106,4421,382],{"class":128},[106,4423,135],{"class":124},[106,4425,139],{"class":138},[106,4427,4428,4430,4432],{"class":108,"line":2671},[106,4429,177],{"class":116},[106,4431,180],{"class":124},[106,4433,3451],{"class":120},[106,4435,4436],{"class":108,"line":2676},[106,4437,4438],{"class":120},"        {\"role\":\"system\",\"content\":\"You are helpful.\"},\n",[106,4440,4441,4444],{"class":108,"line":2682},[106,4442,4443],{"class":120},"        {\"role\":\"user\",\"content\":\"hi\"}]}",[106,4445,186],{"class":124},[106,4447,4448],{"class":108,"line":2715},[106,4449,4377],{"class":192},[106,4451,4452],{"class":108,"line":2720},[106,4453,4454],{"class":192},"#   Guardrail Violation: messages[0] content must contain the required watermark\n",[106,4456,4457],{"class":108,"line":2726},[106,4458,1156],{"emptyLinePlaceholder":1155},[106,4460,4461],{"class":108,"line":2761},[106,4462,4463],{"class":192},"# Allowed (widget does this for you)\n",[106,4465,4466,4468,4470,4472,4474,4476,4478,4480],{"class":108,"line":2766},[106,4467,113],{"class":112},[106,4469,117],{"class":116},[106,4471,121],{"class":120},[106,4473,125],{"class":124},[106,4475,129],{"class":128},[106,4477,3411],{"class":120},[106,4479,135],{"class":124},[106,4481,139],{"class":138},[106,4483,4484,4486,4488,4490,4492,4494],{"class":108,"line":2772},[106,4485,145],{"class":116},[106,4487,125],{"class":124},[106,4489,150],{"class":120},[106,4491,382],{"class":128},[106,4493,135],{"class":124},[106,4495,139],{"class":138},[106,4497,4498,4500,4502],{"class":108,"line":2817},[106,4499,177],{"class":116},[106,4501,180],{"class":124},[106,4503,3451],{"class":120},[106,4505,4506],{"class":108,"line":2822},[106,4507,4508],{"class":120},"        {\"role\":\"system\",\"content\":\"You are the page agent for https:\u002F\u002Fexample.com. watermark\"},\n",[106,4510,4511,4514],{"class":108,"line":2828},[106,4512,4513],{"class":120},"        {\"role\":\"user\",\"content\":\"Summarize this page.\"}]}",[106,4515,186],{"class":124},[106,4517,4518],{"class":108,"line":2871},[106,4519,4520],{"class":192},"# → HTTP\u002F1.1 200 OK  finish_reason:\"stop\"\n",[73,4522,4524],{"id":4523},"why-this-helps-business","Why this helps business",[20,4526,4527,4536],{},[23,4528,4529,4532,4533,4535],{},[44,4530,4531],{},"Leak tolerance:"," Even if a ",[53,4534,62],{"title":973}," is scraped, it cannot be automated against another prompt style.",[23,4537,4538,4541],{},[44,4539,4540],{},"Predictable scope:"," Klunq Widget page agentsends a page-specific prompt - usage stays tied to that surface -the website.",[1255,4543,4544],{"color":1813,"icon":1814},[16,4545,4546],{},"Today the proxy only accepts the Klunq Widget watermark — any other OpenAI-compatible client without it is rejected. Custom watermarks for your own apps are planned.",[16,4548,916,4549,1480,4551],{},[782,4550,2949],{"href":977},[782,4552,3910],{"href":1465},[922,4554,1740],{},{"title":102,"searchDepth":160,"depth":160,"links":4556},[4557,4558,4559,4560],{"id":4244,"depth":142,"text":4245},{"id":2877,"depth":142,"text":2878},{"id":4289,"depth":142,"text":4290},{"id":4523,"depth":142,"text":4524},"v-keys only work in your page context. Leaked keys cannot be reused for coding or generic chat.",{},{"title":785,"icon":4564},"i-lucide-fingerprint",{"title":4223,"description":4561},"docs\u002Fwatermarking","dNfCQ7sjIOqAjh5oTQ1kYPVcPElzoXw69j5wZ-HZB_s",{"id":1504,"title":1505,"body":4569,"description":1746,"extension":940,"meta":4758,"navigation":4759,"path":1751,"seo":4760,"stem":1753,"__hash__":1754},{"type":8,"value":4570,"toc":4753},[4571,4575,4583,4585,4617,4619,4625,4627,4629,4661,4663,4665,4731,4737,4751],[11,4572,4573],{"id":62},[53,4574,62],{"title":973},[16,4576,1514,4577,1517,4579,1521,4581,1524],{},[53,4578,62],{"title":973},[27,4580,1520],{},[53,4582,56],{"title":55},[73,4584,1528],{"id":1527},[828,4586,4587,4595],{},[831,4588,4589],{},[834,4590,4591,4593],{},[837,4592,1537],{},[837,4594,1540],{},[844,4596,4597,4605],{},[834,4598,4599,4603],{},[849,4600,4601],{},[44,4602,46],{},[849,4604,1551],{},[834,4606,4607,4611],{},[849,4608,4609],{},[44,4610,62],{},[849,4612,4613,204,4615,1565],{},[27,4614,775],{},[27,4616,1564],{},[16,4618,1568],{},[1255,4620,4621],{"color":1571,"icon":1572},[16,4622,1575,4623,1579],{},[27,4624,1578],{},[73,4626,1583],{"id":1582},[16,4628,1586],{},[20,4630,4631,4645,4655],{},[23,4632,4633,1594,4635,204,4637,204,4639,204,4641,1603,4643,1606],{},[44,4634,1593],{},[27,4636,211],{},[27,4638,214],{},[27,4640,207],{},[27,4642,228],{},[27,4644,199],{},[23,4646,4647,1612,4649,1616,4651,604,4653],{},[44,4648,1611],{},[27,4650,1615],{},[27,4652,1619],{},[27,4654,900],{},[23,4656,4657,1627,4659],{},[44,4658,1626],{},[27,4660,199],{},[16,4662,1632],{},[73,4664,1636],{"id":1635},[97,4666,4667],{"className":99,"code":1639,"language":101,"meta":102,"style":102},[27,4668,4669,4673,4691,4705,4717,4727],{"__ignoreMap":102},[106,4670,4671],{"class":108,"line":109},[106,4672,1646],{"class":192},[106,4674,4675,4677,4679,4681,4683,4685,4687,4689],{"class":108,"line":142},[106,4676,113],{"class":112},[106,4678,117],{"class":116},[106,4680,121],{"class":120},[106,4682,125],{"class":124},[106,4684,129],{"class":128},[106,4686,132],{"class":120},[106,4688,135],{"class":124},[106,4690,139],{"class":138},[106,4692,4693,4695,4697,4699,4701,4703],{"class":108,"line":160},[106,4694,145],{"class":116},[106,4696,125],{"class":124},[106,4698,150],{"class":120},[106,4700,153],{"class":128},[106,4702,135],{"class":124},[106,4704,139],{"class":138},[106,4706,4707,4709,4711,4713,4715],{"class":108,"line":174},[106,4708,145],{"class":116},[106,4710,125],{"class":124},[106,4712,167],{"class":120},[106,4714,135],{"class":124},[106,4716,139],{"class":138},[106,4718,4719,4721,4723,4725],{"class":108,"line":189},[106,4720,177],{"class":116},[106,4722,180],{"class":124},[106,4724,1699],{"class":120},[106,4726,186],{"class":124},[106,4728,4729],{"class":108,"line":738},[106,4730,1706],{"class":192},[16,4732,1709,4733,1712,4735,1715],{},[782,4734,1497],{"href":1499},[782,4736,785],{"href":784},[1255,4738,4739],{"color":1718,"icon":1719},[16,4740,4741,1725,4743,47,4745,204,4747,204,4749,1737],{},[44,4742,1724],{},[27,4744,199],{},[27,4746,1730],{},[27,4748,1733],{},[27,4750,1736],{},[922,4752,1740],{},{"title":102,"searchDepth":160,"depth":160,"links":4754},[4755,4756,4757],{"id":1527,"depth":142,"text":1528},{"id":1582,"depth":142,"text":1583},{"id":1635,"depth":142,"text":1636},{},{"title":1749,"icon":1750},{"title":1505,"description":1746},1789036728962]