[{"data":1,"prerenderedAt":736},["ShallowReactive",2],{"docs-\u002Fapi\u002Fadmin":3},{"id":4,"title":5,"body":6,"description":728,"extension":729,"meta":730,"navigation":731,"path":732,"seo":733,"stem":734,"__hash__":735},"docs\u002Fdocs\u002Fapi\u002Fadmin.md","Admin API",{"type":7,"value":8,"toc":704},"minimark",[9,13,21,53,59,85,91,129,135,158,164,187,193,218,224,259,265,291,297,324,330,378,384,409,415,446,452,480,486,516,522,552,558,590,596,625,631,666,672],[10,11,5],"h1",{"id":12},"admin-api",[14,15,17],"h3",{"id":16},"get-apiadminoverview",[18,19,20],"code",{},"GET \u002Fapi\u002Fadmin\u002Foverview",[22,23,24,28,31,34,37,48],"ul",{},[25,26,27],"li",{},"Purpose: Global admin overview metrics.",[25,29,30],{},"Auth: Master admin.",[25,32,33],{},"Request shape: Optional period\u002Ffilter query.",[25,35,36],{},"Response shape: Aggregated platform metrics.",[25,38,39,40,43,44,47],{},"Key errors: ",[18,41,42],{},"401",", ",[18,45,46],{},"403",".",[25,49,50,51,47],{},"Example: ",[18,52,20],{},[14,54,56],{"id":55},"get-apiadminbandwidth-daily",[18,57,58],{},"GET \u002Fapi\u002Fadmin\u002Fbandwidth-daily",[22,60,61,64,66,69,72,81],{},[25,62,63],{},"Purpose: Global daily bandwidth aggregates.",[25,65,30],{},[25,67,68],{},"Request shape: Query period\u002Frange.",[25,70,71],{},"Response shape: List of daily bandwidth values.",[25,73,39,74,43,77,43,79,47],{},[18,75,76],{},"400",[18,78,42],{},[18,80,46],{},[25,82,50,83,47],{},[18,84,58],{},[14,86,88],{"id":87},"get-apiadmincloudflare-cost",[18,89,90],{},"GET \u002Fapi\u002Fadmin\u002Fcloudflare-cost",[22,92,93,100,102,109,115,124],{},[25,94,95,96,99],{},"Purpose: Estimated Cloudflare infrastructure cost for the current period. When ",[18,97,98],{},"CF_COST_LIVE_ENABLED=true"," and the CF Analytics fetch succeeds, returns live-backed numbers; otherwise a modeled fallback. Cached for 10 minutes.",[25,101,30],{},[25,103,104,105,108],{},"Request shape: Optional ",[18,106,107],{},"?period=YYYY-MM"," query (defaults to current billing period).",[25,110,111,112,47],{},"Response shape: ",[18,113,114],{},"{ period, costSource: 'live' | 'modeled', costConfidence, fetchedAt, cacheAgeMs, cost: { workersCost, d1Cost, kvCost, totalCost, ... }, fallbackReason }",[25,116,39,117,119,120,43,122,47],{},[18,118,76],{}," invalid period, ",[18,121,42],{},[18,123,46],{},[25,125,50,126,47],{},[18,127,128],{},"GET \u002Fapi\u002Fadmin\u002Fcloudflare-cost?period=2026-04",[14,130,132],{"id":131},"get-apiadminusage-stream",[18,133,134],{},"GET \u002Fapi\u002Fadmin\u002Fusage-stream",[22,136,137,140,142,145,148,154],{},[25,138,139],{},"Purpose: Stream\u002Fnear-real-time usage feed for admin views.",[25,141,30],{},[25,143,144],{},"Request shape: Optional cursor\u002Flimit query.",[25,146,147],{},"Response shape: Stream items + metadata.",[25,149,39,150,43,152,47],{},[18,151,42],{},[18,153,46],{},[25,155,50,156,47],{},[18,157,134],{},[14,159,161],{"id":160},"get-apiadminusage-diagnostic",[18,162,163],{},"GET \u002Fapi\u002Fadmin\u002Fusage-diagnostic",[22,165,166,169,171,174,177,183],{},[25,167,168],{},"Purpose: Usage pipeline diagnostics.",[25,170,30],{},[25,172,173],{},"Request shape: Optional diagnostics query.",[25,175,176],{},"Response shape: Health\u002Fdiagnostic data.",[25,178,39,179,43,181,47],{},[18,180,42],{},[18,182,46],{},[25,184,50,185,47],{},[18,186,163],{},[14,188,190],{"id":189},"get-apiadminusage-aggregator-status",[18,191,192],{},"GET \u002Fapi\u002Fadmin\u002Fusage-aggregator-status",[22,194,195,198,200,203,208,214],{},[25,196,197],{},"Purpose: Telemetry snapshot for the in-process usage write-behind aggregator and the threshold-check gate. Use for incident debugging (\"is the feature flag on?\", \"when did we last flush?\", \"how many logs were dropped by sampling?\"). No D1 reads — entirely in-memory.",[25,199,30],{},[25,201,202],{},"Request shape: No query params.",[25,204,111,205,47],{},[18,206,207],{},"{ generatedAt, aggregator: { enabled, flushIntervalMs, flushMaxEntries, requestLogSampleRate, enqueuedDeltas, droppedWhenDisabled, sampledLogs, skippedLogs, flushes, flushErrors, lastFlushAt, lastFlushDurationMs, lastFlushBucketCount, lastFlushLogCount, lastError, pendingBuckets, pendingLogs, prunes, lastPruneAt, lastPruneRowsDeleted }, thresholdGate: { enabled, intervalMs, allowed, skippedThrottled, skippedDisabled, evictedEntries, trackedOrgs } }",[25,209,39,210,43,212,47],{},[18,211,42],{},[18,213,46],{},[25,215,50,216,47],{},[18,217,192],{},[14,219,221],{"id":220},"get-apiadminlogs",[18,222,223],{},"GET \u002Fapi\u002Fadmin\u002Flogs",[22,225,226,229,231,244,247,255],{},[25,227,228],{},"Purpose: Platform request\u002Ferror log listing.",[25,230,30],{},[25,232,233,234,43,237,43,240,243],{},"Request shape: Query filters (",[18,235,236],{},"cursor",[18,238,239],{},"limit",[18,241,242],{},"level",", etc).",[25,245,246],{},"Response shape: Log entries + pagination.",[25,248,39,249,43,251,43,253,47],{},[18,250,76],{},[18,252,42],{},[18,254,46],{},[25,256,50,257,47],{},[18,258,223],{},[14,260,262],{"id":261},"post-apiadminlogs-test",[18,263,264],{},"POST \u002Fapi\u002Fadmin\u002Flogs-test",[22,266,267,270,272,275,281,287],{},[25,268,269],{},"Purpose: Test endpoint for log pipeline.",[25,271,30],{},[25,273,274],{},"Request shape: Optional test payload.",[25,276,111,277,280],{},[18,278,279],{},"{ ok }"," + test metadata.",[25,282,39,283,43,285,47],{},[18,284,42],{},[18,286,46],{},[25,288,50,289,47],{},[18,290,264],{},[14,292,294],{"id":293},"post-apiadmind1-init",[18,295,296],{},"POST \u002Fapi\u002Fadmin\u002Fd1-init",[22,298,299,302,304,307,310,320],{},[25,300,301],{},"Purpose: Initialize D1 structures\u002Ftables.",[25,303,30],{},[25,305,306],{},"Request shape: none.",[25,308,309],{},"Response shape: Init result.",[25,311,39,312,43,314,43,316,319],{},[18,313,42],{},[18,315,46],{},[18,317,318],{},"500"," DB errors.",[25,321,50,322,47],{},[18,323,296],{},[14,325,327],{"id":326},"post-apiadminprune-logs",[18,328,329],{},"POST \u002Fapi\u002Fadmin\u002Fprune-logs",[22,331,332,339,341,352,362,370],{},[25,333,334,335,338],{},"Purpose: Manually sweep ",[18,336,337],{},"request_logs"," older than the retention window. Complements the aggregator's opportunistic prune — use from an external cron (Github Actions, uptime pinger) if you want a fixed cadence.",[25,340,30],{},[25,342,343,344,347,348,351],{},"Request shape: Optional body ",[18,345,346],{},"{ retentionDays?: number }"," (defaults to the repository's ",[18,349,350],{},"PRUNE_THRESHOLD_DAYS",").",[25,353,111,354,357,358,361],{},[18,355,356],{},"{ ok, deleted }"," where ",[18,359,360],{},"deleted"," is the row count removed.",[25,363,39,364,43,366,43,368,319],{},[18,365,42],{},[18,367,46],{},[18,369,318],{},[25,371,50,372,374,375,47],{},[18,373,329],{}," with body ",[18,376,377],{},"{ \"retentionDays\": 30 }",[14,379,381],{"id":380},"post-apiadminmigrate-kv-to-d1",[18,382,383],{},"POST \u002Fapi\u002Fadmin\u002Fmigrate-kv-to-d1",[22,385,386,389,391,394,397,405],{},[25,387,388],{},"Purpose: Migrate data from KV to D1.",[25,390,30],{},[25,392,393],{},"Request shape: Optional migration parameters.",[25,395,396],{},"Response shape: Migration report.",[25,398,39,399,43,401,43,403,47],{},[18,400,42],{},[18,402,46],{},[18,404,318],{},[25,406,50,407,47],{},[18,408,383],{},[14,410,412],{"id":411},"get-apiadmintenantsslugearned",[18,413,414],{},"GET \u002Fapi\u002Fadmin\u002Ftenants\u002F{slug}\u002Fearned",[22,416,417,420,422,429,432,441],{},[25,418,419],{},"Purpose: Billing\u002Fearnings overview for a tenant.",[25,421,30],{},[25,423,424,425,428],{},"Request shape: Path ",[18,426,427],{},"{slug}"," + optional period.",[25,430,431],{},"Response shape: Earnings summary.",[25,433,39,434,43,437,43,439,47],{},[18,435,436],{},"404",[18,438,42],{},[18,440,46],{},[25,442,50,443,47],{},[18,444,445],{},"GET \u002Fapi\u002Fadmin\u002Ftenants\u002Facme\u002Fearned",[14,447,449],{"id":448},"get-apiadminusersuserid",[18,450,451],{},"GET \u002Fapi\u002Fadmin\u002Fusers\u002F{userId}",[22,453,454,457,459,464,467,475],{},[25,455,456],{},"Purpose: Read details for an admin user record.",[25,458,30],{},[25,460,424,461,47],{},[18,462,463],{},"{userId}",[25,465,466],{},"Response shape: User admin view model.",[25,468,39,469,43,471,43,473,47],{},[18,470,436],{},[18,472,42],{},[18,474,46],{},[25,476,50,477,47],{},[18,478,479],{},"GET \u002Fapi\u002Fadmin\u002Fusers\u002Fuser_123",[14,481,483],{"id":482},"patch-apiadminusersuserid",[18,484,485],{},"PATCH \u002Fapi\u002Fadmin\u002Fusers\u002F{userId}",[22,487,488,491,493,498,501,511],{},[25,489,490],{},"Purpose: Partial update of admin user state.",[25,492,30],{},[25,494,424,495,497],{},[18,496,463],{}," + patch body.",[25,499,500],{},"Response shape: Updated user model.",[25,502,39,503,43,505,43,507,43,509,47],{},[18,504,76],{},[18,506,436],{},[18,508,42],{},[18,510,46],{},[25,512,50,513,47],{},[18,514,515],{},"PATCH \u002Fapi\u002Fadmin\u002Fusers\u002Fuser_123",[14,517,519],{"id":518},"get-apiadminusersuseriddaily",[18,520,521],{},"GET \u002Fapi\u002Fadmin\u002Fusers\u002F{userId}\u002Fdaily",[22,523,524,527,529,534,537,547],{},[25,525,526],{},"Purpose: Daily metrics for a specific user.",[25,528,30],{},[25,530,424,531,533],{},[18,532,463],{}," + period query.",[25,535,536],{},"Response shape: Daily usage series.",[25,538,39,539,43,541,43,543,43,545,47],{},[18,540,76],{},[18,542,436],{},[18,544,42],{},[18,546,46],{},[25,548,50,549,47],{},[18,550,551],{},"GET \u002Fapi\u002Fadmin\u002Fusers\u002Fuser_123\u002Fdaily",[14,553,555],{"id":554},"post-apiadminusersuseridblock",[18,556,557],{},"POST \u002Fapi\u002Fadmin\u002Fusers\u002F{userId}\u002Fblock",[22,559,560,563,565,570,575,585],{},[25,561,562],{},"Purpose: Block\u002Funblock a user according to policy.",[25,564,30],{},[25,566,424,567,569],{},[18,568,463],{}," + block payload.",[25,571,111,572,574],{},[18,573,279],{}," + updated status.",[25,576,39,577,43,579,43,581,43,583,47],{},[18,578,76],{},[18,580,436],{},[18,582,42],{},[18,584,46],{},[25,586,50,587,47],{},[18,588,589],{},"POST \u002Fapi\u002Fadmin\u002Fusers\u002Fuser_123\u002Fblock",[14,591,593],{"id":592},"post-apiadminusersuseridreset-password",[18,594,595],{},"POST \u002Fapi\u002Fadmin\u002Fusers\u002F{userId}\u002Freset-password",[22,597,598,601,603,608,612,620],{},[25,599,600],{},"Purpose: Trigger admin password reset for a user.",[25,602,30],{},[25,604,424,605,607],{},[18,606,463],{}," + reset payload (if applicable).",[25,609,111,610,47],{},[18,611,279],{},[25,613,39,614,43,616,43,618,47],{},[18,615,436],{},[18,617,42],{},[18,619,46],{},[25,621,50,622,47],{},[18,623,624],{},"POST \u002Fapi\u002Fadmin\u002Fusers\u002Fuser_123\u002Freset-password",[14,626,628],{"id":627},"patch-apiadminbillingorgid",[18,629,630],{},"PATCH \u002Fapi\u002Fadmin\u002Fbilling\u002F{orgId}",[22,632,633,636,638,644,649,658],{},[25,634,635],{},"Purpose: Override the billing plan for a specific org\u002Fuser. Sets an admin override flag so Stripe webhooks will not revert the change.",[25,637,30],{},[25,639,640,641,47],{},"Request shape: Body ",[18,642,643],{},"{ planCode: \"free\" | \"pro\" }",[25,645,111,646,47],{},[18,647,648],{},"{ ok, billing }",[25,650,39,651,653,654,43,656,47],{},[18,652,76],{}," invalid planCode, ",[18,655,42],{},[18,657,46],{},[25,659,50,660,374,663,47],{},[18,661,662],{},"PATCH \u002Fapi\u002Fadmin\u002Fbilling\u002Fuser_123",[18,664,665],{},"{ \"planCode\": \"pro\" }",[14,667,669],{"id":668},"post-apiadminbackfill-members",[18,670,671],{},"POST \u002Fapi\u002Fadmin\u002Fbackfill-members",[22,673,674,685,687,689,694,700],{},[25,675,676,677,680,681,684],{},"Purpose: One-time migration that seeds ",[18,678,679],{},"tenant_members"," rows from ",[18,682,683],{},"tenants.created_by",". Safe to call multiple times (uses INSERT OR IGNORE).",[25,686,30],{},[25,688,306],{},[25,690,111,691,47],{},[18,692,693],{},"{ ok, seeded }",[25,695,39,696,43,698,47],{},[18,697,42],{},[18,699,46],{},[25,701,50,702,47],{},[18,703,671],{},{"title":705,"searchDepth":706,"depth":706,"links":707},"",2,[708,710,711,712,713,714,715,716,717,718,719,720,721,722,723,724,725,726,727],{"id":16,"depth":709,"text":20},3,{"id":55,"depth":709,"text":58},{"id":87,"depth":709,"text":90},{"id":131,"depth":709,"text":134},{"id":160,"depth":709,"text":163},{"id":189,"depth":709,"text":192},{"id":220,"depth":709,"text":223},{"id":261,"depth":709,"text":264},{"id":293,"depth":709,"text":296},{"id":326,"depth":709,"text":329},{"id":380,"depth":709,"text":383},{"id":411,"depth":709,"text":414},{"id":448,"depth":709,"text":451},{"id":482,"depth":709,"text":485},{"id":518,"depth":709,"text":521},{"id":554,"depth":709,"text":557},{"id":592,"depth":709,"text":595},{"id":627,"depth":709,"text":630},{"id":668,"depth":709,"text":671},"Internal admin and operations endpoints for platform oversight and user controls.","md",{},true,"\u002Fdocs\u002Fapi\u002Fadmin",{"title":5,"description":728},"docs\u002Fapi\u002Fadmin","cQj-Mr_mgj6fn985ScfkMUOjyxIFK59rM3WFL-Z6A18",1777579477593]