Skip to main content

uarp_sdk/generated/api/
admin_config.rs

1// Code generated by @uarp/codegen from spec/openapi.json. DO NOT EDIT.
2//!
3//! Platform configuration: pricing, plans, feature flags, rate limits, runtime
4
5#![allow(unused_imports, clippy::too_many_arguments)]
6
7use reqwest::Method;
8use serde::{Deserialize, Serialize};
9
10use crate::client::{Client, Request, NO_BODY, NO_QUERY};
11use crate::error::Result;
12use crate::generated::models;
13use crate::multipart::{field_text, FilePart};
14use crate::util::encode_path;
15
16/// Query and header parameters for `deleteCustomPlan`.
17#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
18pub struct DeleteCustomPlanParams {
19    /// Exactly `1`. Deletes despite assigned tenants.
20    #[serde(default, skip_serializing_if = "Option::is_none")]
21    pub force: Option<models::DeleteCustomPlanForce>,
22}
23
24/// Query and header parameters for `updateAdminSpecPackages`.
25#[derive(Debug, Clone, Default, PartialEq, Serialize, Deserialize)]
26pub struct UpdateAdminSpecPackagesParams {
27    /// Comma-separated package ids the caller intends to delete despite a wired Stripe price. Ids
28    /// not listed still refuse.
29    #[serde(default, skip_serializing_if = "Option::is_none")]
30    pub confirm_drop: Option<String>,
31}
32
33/// Platform configuration: pricing, plans, feature flags, rate limits, runtime
34#[derive(Debug, Clone)]
35pub struct AdminConfigApi {
36    pub(crate) client: Client,
37}
38
39impl Client {
40    /// Platform configuration: pricing, plans, feature flags, rate limits, runtime
41    pub fn admin_config(&self) -> AdminConfigApi {
42        AdminConfigApi { client: self.clone() }
43    }
44}
45
46impl AdminConfigApi {
47    /// Create the Stripe product and price for a package
48    ///
49    /// Creates the product and price in Stripe and persists the resulting price id onto the
50    /// package. Until this has run, the package cannot be bought: `POST
51    /// /api/v1/billing/spec-packages/{packageId}/checkout-session` answers 400 and says so.
52    ///
53    /// `POST /api/v1/admin/config/spec-packages/{packageId}/stripe-price`
54    ///
55    /// Required scopes: `admin`.
56    pub async fn create_admin_spec_package_stripe_price(&self, package_id: &str) -> Result<serde_json::Map<String, serde_json::Value>> {
57        self.client
58            .request_json(Request {
59                method: Method::POST,
60                path: format!("/api/v1/admin/config/spec-packages/{}/stripe-price", encode_path(package_id)),
61                query: NO_QUERY,
62                body: NO_BODY,
63                headers: Vec::new(),
64                idempotent: true,
65            })
66            .await
67    }
68
69    /// Create Stripe Product+Price for plan
70    ///
71    /// `POST /api/v1/admin/config/plans/{planId}/stripe-price`
72    ///
73    /// Required scopes: `admin`.
74    pub async fn create_plan_stripe_price(&self, plan_id: &models::PlanLLMLimitsTierAccessItem, body: &models::CreatePlanStripePriceRequest) -> Result<models::CreatePlanStripePriceResponse> {
75        self.client
76            .request_json(Request {
77                method: Method::POST,
78                path: format!("/api/v1/admin/config/plans/{}/stripe-price", encode_path(&plan_id.to_string())),
79                query: NO_QUERY,
80                body: Some(body),
81                headers: Vec::new(),
82                idempotent: true,
83            })
84            .await
85    }
86
87    /// Remove a custom plan
88    ///
89    /// **Refuses while tenants are assigned to the plan.** The answer is 409 naming how many, and
90    /// the caller opts in with `?force=1` — an exact string match, so `?force=true` does NOT force.
91    /// Deleting a plan out from under its tenants leaves them on an id that no longer resolves,
92    /// which is why the guard is there.
93    ///
94    /// The count in the message is a floor, not a census: it is what the tenant scan saw at that
95    /// moment.
96    ///
97    /// `DELETE /api/v1/admin/config/custom-plans/{planId}`
98    ///
99    /// Required scopes: `admin`.
100    pub async fn delete_custom_plan(&self, plan_id: &str, params: &DeleteCustomPlanParams) -> Result<models::DeleteCustomPlanResponse> {
101        self.client
102            .request_json(Request {
103                method: Method::DELETE,
104                path: format!("/api/v1/admin/config/custom-plans/{}", encode_path(plan_id)),
105                query: Some(params),
106                body: NO_BODY,
107                headers: Vec::new(),
108                idempotent: true,
109            })
110            .await
111    }
112
113    /// Drop the price override for one model
114    ///
115    /// Removes the override so the model bills at its catalogue rate again. The 404 is keyed on the
116    /// OVERRIDE map, not the model catalogue: deleting an override that was never set is 404 even
117    /// for a model that exists.
118    ///
119    /// `DELETE /api/v1/admin/config/model-pricing/{modelRef}`
120    ///
121    /// Required scopes: `admin`.
122    pub async fn delete_model_pricing_override(&self, model_ref: &str) -> Result<models::DeleteModelPricingOverrideResponse> {
123        self.client
124            .request_json(Request {
125                method: Method::DELETE,
126                path: format!("/api/v1/admin/config/model-pricing/{}", encode_path(model_ref)),
127                query: NO_QUERY,
128                body: NO_BODY,
129                headers: Vec::new(),
130                idempotent: true,
131            })
132            .await
133    }
134
135    /// Remove a promo code
136    ///
137    /// Removes the code only. Redemption and reward records already written against it are NOT
138    /// cascaded — they remain, keyed by the code string, so a code deleted and later re-created
139    /// inherits the history of its name.
140    ///
141    /// `DELETE /api/v1/admin/config/promo-codes/{code}`
142    ///
143    /// Required scopes: `admin`.
144    pub async fn delete_promo_code(&self, code: &str) -> Result<models::DeletePromoCodeResponse> {
145        self.client
146            .request_json(Request {
147                method: Method::DELETE,
148                path: format!("/api/v1/admin/config/promo-codes/{}", encode_path(code)),
149                query: NO_QUERY,
150                body: NO_BODY,
151                headers: Vec::new(),
152                idempotent: true,
153            })
154            .await
155    }
156
157    /// Bulk download of every admin-config KV override
158    ///
159    /// `GET /api/v1/admin/config/export`
160    ///
161    /// Required scopes: `admin`.
162    pub async fn export(&self) -> Result<models::ExportAdminConfigResponse> {
163        self.client
164            .request_json(Request {
165                method: Method::GET,
166                path: "/api/v1/admin/config/export".to_string(),
167                query: NO_QUERY,
168                body: NO_BODY,
169                headers: Vec::new(),
170                idempotent: false,
171            })
172            .await
173    }
174
175    /// Get agent memory overrides (decay, models, embedding dims)
176    ///
177    /// `GET /api/v1/admin/config/agent-memory`
178    ///
179    /// Required scopes: `admin`.
180    pub async fn get_admin_agent_memory_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
181        self.client
182            .request_json(Request {
183                method: Method::GET,
184                path: "/api/v1/admin/config/agent-memory".to_string(),
185                query: NO_QUERY,
186                body: NO_BODY,
187                headers: Vec::new(),
188                idempotent: false,
189            })
190            .await
191    }
192
193    /// Get auth runtime overrides (super-admin email, OTP/JWKS TTLs)
194    ///
195    /// `GET /api/v1/admin/config/auth`
196    ///
197    /// Required scopes: `admin`.
198    pub async fn get_admin_auth_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
199        self.client
200            .request_json(Request {
201                method: Method::GET,
202                path: "/api/v1/admin/config/auth".to_string(),
203                query: NO_QUERY,
204                body: NO_BODY,
205                headers: Vec::new(),
206                idempotent: false,
207            })
208            .await
209    }
210
211    /// Get backpressure overrides (SSE buffers + tool queue watermarks)
212    ///
213    /// `GET /api/v1/admin/config/backpressure`
214    ///
215    /// Required scopes: `admin`.
216    pub async fn get_admin_backpressure_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
217        self.client
218            .request_json(Request {
219                method: Method::GET,
220                path: "/api/v1/admin/config/backpressure".to_string(),
221                query: NO_QUERY,
222                body: NO_BODY,
223                headers: Vec::new(),
224                idempotent: false,
225            })
226            .await
227    }
228
229    /// Get code-interpreter overrides (isolation, timeout, memory)
230    ///
231    /// `GET /api/v1/admin/config/code-interpreter`
232    ///
233    /// Required scopes: `admin`.
234    pub async fn get_admin_code_interpreter_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
235        self.client
236            .request_json(Request {
237                method: Method::GET,
238                path: "/api/v1/admin/config/code-interpreter".to_string(),
239                query: NO_QUERY,
240                body: NO_BODY,
241                headers: Vec::new(),
242                idempotent: false,
243            })
244            .await
245    }
246
247    /// Tool ids disabled platform-wide
248    ///
249    /// `GET /api/v1/admin/config/disabled-tools`
250    ///
251    /// Required scopes: `admin`.
252    pub async fn get_admin_disabled_tools(&self) -> Result<models::GetAdminDisabledToolsResponse> {
253        self.client
254            .request_json(Request {
255                method: Method::GET,
256                path: "/api/v1/admin/config/disabled-tools".to_string(),
257                query: NO_QUERY,
258                body: NO_BODY,
259                headers: Vec::new(),
260                idempotent: false,
261            })
262            .await
263    }
264
265    /// Get evaluation overrides (timeouts, regression threshold, auto-rollback)
266    ///
267    /// `GET /api/v1/admin/config/evaluation`
268    ///
269    /// Required scopes: `admin`.
270    pub async fn get_admin_evaluation_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
271        self.client
272            .request_json(Request {
273                method: Method::GET,
274                path: "/api/v1/admin/config/evaluation".to_string(),
275                query: NO_QUERY,
276                body: NO_BODY,
277                headers: Vec::new(),
278                idempotent: false,
279            })
280            .await
281    }
282
283    /// Founder identity, stored and from the environment
284    ///
285    /// Same three-layer read as SMTP, except the third key is `effective` rather than `source`: the
286    /// resolved values themselves, not a label saying where they came from. Resolution is per
287    /// FIELD, so a founder id from storage can sit beside a public key from the environment.
288    ///
289    /// `GET /api/v1/admin/config/founder`
290    ///
291    /// Required scopes: `admin`.
292    pub async fn get_admin_founder_config(&self) -> Result<models::GetAdminFounderConfigResponse> {
293        self.client
294            .request_json(Request {
295                method: Method::GET,
296                path: "/api/v1/admin/config/founder".to_string(),
297                query: NO_QUERY,
298                body: NO_BODY,
299                headers: Vec::new(),
300                idempotent: false,
301            })
302            .await
303    }
304
305    /// Get guardrail config
306    ///
307    /// `GET /api/v1/admin/config/guardrails`
308    ///
309    /// Required scopes: `admin`.
310    pub async fn get_admin_guardrails(&self) -> Result<models::GetAdminGuardrailsResponse> {
311        self.client
312            .request_json(Request {
313                method: Method::GET,
314                path: "/api/v1/admin/config/guardrails".to_string(),
315                query: NO_QUERY,
316                body: NO_BODY,
317                headers: Vec::new(),
318                idempotent: false,
319            })
320            .await
321    }
322
323    /// Get idempotency overrides (enabled, TTL hours, max cache bytes)
324    ///
325    /// `GET /api/v1/admin/config/idempotency`
326    ///
327    /// Required scopes: `admin`.
328    pub async fn get_admin_idempotency_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
329        self.client
330            .request_json(Request {
331                method: Method::GET,
332                path: "/api/v1/admin/config/idempotency".to_string(),
333                query: NO_QUERY,
334                body: NO_BODY,
335                headers: Vec::new(),
336                idempotent: false,
337            })
338            .await
339    }
340
341    /// Get integration toggles
342    ///
343    /// `GET /api/v1/admin/config/integrations`
344    ///
345    /// Required scopes: `admin`.
346    pub async fn get_admin_integrations(&self) -> Result<models::GetAdminIntegrationsResponse> {
347        self.client
348            .request_json(Request {
349                method: Method::GET,
350                path: "/api/v1/admin/config/integrations".to_string(),
351                query: NO_QUERY,
352                body: NO_BODY,
353                headers: Vec::new(),
354                idempotent: false,
355            })
356            .await
357    }
358
359    /// Get LLM adapter overrides (retries, circuit breaker, per-provider RPM)
360    ///
361    /// `GET /api/v1/admin/config/llm-adapters`
362    ///
363    /// Required scopes: `admin`.
364    pub async fn get_admin_llm_adapters_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
365        self.client
366            .request_json(Request {
367                method: Method::GET,
368                path: "/api/v1/admin/config/llm-adapters".to_string(),
369                query: NO_QUERY,
370                body: NO_BODY,
371                headers: Vec::new(),
372                idempotent: false,
373            })
374            .await
375    }
376
377    /// Get logging overrides (PII mode, file level, activity verbosity)
378    ///
379    /// `GET /api/v1/admin/config/logging`
380    ///
381    /// Required scopes: `admin`.
382    pub async fn get_admin_logging_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
383        self.client
384            .request_json(Request {
385                method: Method::GET,
386                path: "/api/v1/admin/config/logging".to_string(),
387                query: NO_QUERY,
388                body: NO_BODY,
389                headers: Vec::new(),
390                idempotent: false,
391            })
392            .await
393    }
394
395    /// Get long-running run overrides
396    ///
397    /// `GET /api/v1/admin/config/long-running`
398    ///
399    /// Required scopes: `admin`.
400    pub async fn get_admin_long_running_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
401        self.client
402            .request_json(Request {
403                method: Method::GET,
404                path: "/api/v1/admin/config/long-running".to_string(),
405                query: NO_QUERY,
406                body: NO_BODY,
407                headers: Vec::new(),
408                idempotent: false,
409            })
410            .await
411    }
412
413    /// Get MCP overrides (session limits, idle timeout)
414    ///
415    /// `GET /api/v1/admin/config/mcp`
416    ///
417    /// Required scopes: `admin`.
418    pub async fn get_admin_mcp_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
419        self.client
420            .request_json(Request {
421                method: Method::GET,
422                path: "/api/v1/admin/config/mcp".to_string(),
423                query: NO_QUERY,
424                body: NO_BODY,
425                headers: Vec::new(),
426                idempotent: false,
427            })
428            .await
429    }
430
431    /// Get multimodal overrides (size + duration caps + format allowlists)
432    ///
433    /// `GET /api/v1/admin/config/multimodal`
434    ///
435    /// Required scopes: `admin`.
436    pub async fn get_admin_multimodal_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
437        self.client
438            .request_json(Request {
439                method: Method::GET,
440                path: "/api/v1/admin/config/multimodal".to_string(),
441                query: NO_QUERY,
442                body: NO_BODY,
443                headers: Vec::new(),
444                idempotent: false,
445            })
446            .await
447    }
448
449    /// Apple native sign-in identifiers and the OAuth return-to allowlist
450    ///
451    /// Three-layer read with `effective`, as with founder identity. The environment's
452    /// `oauth_return_to_hosts` is a comma-separated variable, split, trimmed and lower-cased before
453    /// it appears here.
454    ///
455    /// `GET /api/v1/admin/config/oauth-identity`
456    ///
457    /// Required scopes: `admin`.
458    pub async fn get_admin_o_auth_identity_config(&self) -> Result<models::GetAdminOAuthIdentityConfigResponse> {
459        self.client
460            .request_json(Request {
461                method: Method::GET,
462                path: "/api/v1/admin/config/oauth-identity".to_string(),
463                query: NO_QUERY,
464                body: NO_BODY,
465                headers: Vec::new(),
466                idempotent: false,
467            })
468            .await
469    }
470
471    /// Get persistence overrides (snapshot interval, KV auto-cap)
472    ///
473    /// `GET /api/v1/admin/config/persistence`
474    ///
475    /// Required scopes: `admin`.
476    pub async fn get_admin_persistence_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
477        self.client
478            .request_json(Request {
479                method: Method::GET,
480                path: "/api/v1/admin/config/persistence".to_string(),
481                query: NO_QUERY,
482                body: NO_BODY,
483                headers: Vec::new(),
484                idempotent: false,
485            })
486            .await
487    }
488
489    /// Get plan overrides
490    ///
491    /// `GET /api/v1/admin/config/plans`
492    ///
493    /// Required scopes: `admin`.
494    pub async fn get_admin_plans(&self) -> Result<models::GetAdminPlansResponse> {
495        self.client
496            .request_json(Request {
497                method: Method::GET,
498                path: "/api/v1/admin/config/plans".to_string(),
499                query: NO_QUERY,
500                body: NO_BODY,
501                headers: Vec::new(),
502                idempotent: false,
503            })
504            .await
505    }
506
507    /// Registration state, setup progress, and the waitlist
508    ///
509    /// Answers three things at once because the admin screen needs all three to decide whether the
510    /// doors CAN open: the effective registration config, how far platform setup has got, and who
511    /// signed up while it was shut.
512    ///
513    /// The waitlist is real registered tenants in status `waitlisted`, not leads — they activate
514    /// lazily on their first login after the doors open.
515    ///
516    /// `GET /api/v1/admin/config/registration`
517    ///
518    /// Required scopes: `admin`.
519    pub async fn get_admin_registration_config(&self) -> Result<models::GetAdminRegistrationConfigResponse> {
520        self.client
521            .request_json(Request {
522                method: Method::GET,
523                path: "/api/v1/admin/config/registration".to_string(),
524                query: NO_QUERY,
525                body: NO_BODY,
526                headers: Vec::new(),
527                idempotent: false,
528            })
529            .await
530    }
531
532    /// Get retention overrides (run / event / audit / feed / artifact TTLs)
533    ///
534    /// `GET /api/v1/admin/config/retention`
535    ///
536    /// Required scopes: `admin`.
537    pub async fn get_admin_retention_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
538        self.client
539            .request_json(Request {
540                method: Method::GET,
541                path: "/api/v1/admin/config/retention".to_string(),
542                query: NO_QUERY,
543                body: NO_BODY,
544                headers: Vec::new(),
545                idempotent: false,
546            })
547            .await
548    }
549
550    /// Get run_command overrides (enabled, allowed commands, deno_allow)
551    ///
552    /// `GET /api/v1/admin/config/run-command`
553    ///
554    /// Required scopes: `admin`.
555    pub async fn get_admin_run_command_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
556        self.client
557            .request_json(Request {
558                method: Method::GET,
559                path: "/api/v1/admin/config/run-command".to_string(),
560                query: NO_QUERY,
561                body: NO_BODY,
562                headers: Vec::new(),
563                idempotent: false,
564            })
565            .await
566    }
567
568    /// Get HTTP server overrides (trust_proxy, body cap, shutdown timeout)
569    ///
570    /// `GET /api/v1/admin/config/server`
571    ///
572    /// Required scopes: `admin`.
573    pub async fn get_admin_server_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
574        self.client
575            .request_json(Request {
576                method: Method::GET,
577                path: "/api/v1/admin/config/server".to_string(),
578                query: NO_QUERY,
579                body: NO_BODY,
580                headers: Vec::new(),
581                idempotent: false,
582            })
583            .await
584    }
585
586    /// Platform setup progress
587    ///
588    /// Answers the state plus the two vocabularies needed to read it — which steps exist and which
589    /// are required — so a client does not hard-code either and drift when the list changes.
590    ///
591    /// `GET /api/v1/admin/config/setup-state`
592    ///
593    /// Required scopes: `admin`.
594    pub async fn get_admin_setup_state(&self) -> Result<models::SetupStateResponse> {
595        self.client
596            .request_json(Request {
597                method: Method::GET,
598                path: "/api/v1/admin/config/setup-state".to_string(),
599                query: NO_QUERY,
600                body: NO_BODY,
601                headers: Vec::new(),
602                idempotent: false,
603            })
604            .await
605    }
606
607    /// Get SMTP config, stored and from the environment
608    ///
609    /// Three-layer read, the shape this whole config family uses: `kv` is what an operator saved,
610    /// `env` is what the process environment supplies, and `source` says which of them is actually
611    /// in force. The password is never in either — only `has_password`, so a UI can show that a
612    /// credential exists without ever holding it.
613    ///
614    /// `GET /api/v1/admin/config/smtp`
615    ///
616    /// Required scopes: `admin`.
617    pub async fn get_admin_smtp_config(&self) -> Result<models::GetAdminSmtpConfigResponse> {
618        self.client
619            .request_json(Request {
620                method: Method::GET,
621                path: "/api/v1/admin/config/smtp".to_string(),
622                query: NO_QUERY,
623                body: NO_BODY,
624                headers: Vec::new(),
625                idempotent: false,
626            })
627            .await
628    }
629
630    /// Every SPEC package, archived ones included
631    ///
632    /// The operator's view: unlike the tenant-facing `/api/v1/billing/spec-packages`, archived
633    /// packages are present and the Stripe price id is NOT redacted. Sorted by `display_order`,
634    /// then by name.
635    ///
636    /// `GET /api/v1/admin/config/spec-packages`
637    ///
638    /// Required scopes: `admin`.
639    pub async fn get_admin_spec_packages(&self) -> Result<models::GetAdminSpecPackagesResponse> {
640        self.client
641            .request_json(Request {
642                method: Method::GET,
643                path: "/api/v1/admin/config/spec-packages".to_string(),
644                query: NO_QUERY,
645                body: NO_BODY,
646                headers: Vec::new(),
647                idempotent: false,
648            })
649            .await
650    }
651
652    /// Get SSE overrides (heartbeat, polling, reconnect hint)
653    ///
654    /// `GET /api/v1/admin/config/sse`
655    ///
656    /// Required scopes: `admin`.
657    pub async fn get_admin_sse_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
658        self.client
659            .request_json(Request {
660                method: Method::GET,
661                path: "/api/v1/admin/config/sse".to_string(),
662                query: NO_QUERY,
663                body: NO_BODY,
664                headers: Vec::new(),
665                idempotent: false,
666            })
667            .await
668    }
669
670    /// Get Stripe runtime config (keys redacted)
671    ///
672    /// `GET /api/v1/admin/config/stripe`
673    ///
674    /// Required scopes: `admin`.
675    pub async fn get_admin_stripe_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
676        self.client
677            .request_json(Request {
678                method: Method::GET,
679                path: "/api/v1/admin/config/stripe".to_string(),
680                query: NO_QUERY,
681                body: NO_BODY,
682                headers: Vec::new(),
683                idempotent: false,
684            })
685            .await
686    }
687
688    /// Per-tool presentation overrides
689    ///
690    /// A map keyed by tool id. Empty object when nothing is stored — never null.
691    ///
692    /// `GET /api/v1/admin/config/tool-overrides`
693    ///
694    /// Required scopes: `admin`.
695    pub async fn get_admin_tool_overrides(&self) -> Result<models::GetAdminToolOverridesResponse> {
696        self.client
697            .request_json(Request {
698                method: Method::GET,
699                path: "/api/v1/admin/config/tool-overrides".to_string(),
700                query: NO_QUERY,
701                body: NO_BODY,
702                headers: Vec::new(),
703                idempotent: false,
704            })
705            .await
706    }
707
708    /// Get tool security overrides (egress, SSRF, payload caps, concurrency)
709    ///
710    /// `GET /api/v1/admin/config/tool-security`
711    ///
712    /// Required scopes: `admin`.
713    pub async fn get_admin_tool_security_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
714        self.client
715            .request_json(Request {
716                method: Method::GET,
717                path: "/api/v1/admin/config/tool-security".to_string(),
718                query: NO_QUERY,
719                body: NO_BODY,
720                headers: Vec::new(),
721                idempotent: false,
722            })
723            .await
724    }
725
726    /// Get webhook delivery overrides (separate from webhooks-policy)
727    ///
728    /// `GET /api/v1/admin/config/webhooks`
729    ///
730    /// Required scopes: `admin`.
731    pub async fn get_admin_webhooks_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
732        self.client
733            .request_json(Request {
734                method: Method::GET,
735                path: "/api/v1/admin/config/webhooks".to_string(),
736                query: NO_QUERY,
737                body: NO_BODY,
738                headers: Vec::new(),
739                idempotent: false,
740            })
741            .await
742    }
743
744    /// Get worker pool overrides (max workers, mode, queue size)
745    ///
746    /// `GET /api/v1/admin/config/worker-pool`
747    ///
748    /// Required scopes: `admin`.
749    pub async fn get_admin_worker_pool_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
750        self.client
751            .request_json(Request {
752                method: Method::GET,
753                path: "/api/v1/admin/config/worker-pool".to_string(),
754                query: NO_QUERY,
755                body: NO_BODY,
756                headers: Vec::new(),
757                idempotent: false,
758            })
759            .await
760    }
761
762    /// Get feature flags
763    ///
764    /// `GET /api/v1/admin/config/feature-flags`
765    ///
766    /// Required scopes: `admin`.
767    pub async fn get_feature_flags(&self) -> Result<models::GetFeatureFlagsResponse> {
768        self.client
769            .request_json(Request {
770                method: Method::GET,
771                path: "/api/v1/admin/config/feature-flags".to_string(),
772                query: NO_QUERY,
773                body: NO_BODY,
774                headers: Vec::new(),
775                idempotent: false,
776            })
777            .await
778    }
779
780    /// Get markup config
781    ///
782    /// `GET /api/v1/admin/config/markup`
783    ///
784    /// Required scopes: `admin`.
785    pub async fn get_markup_config(&self) -> Result<models::GetMarkupConfigResponse> {
786        self.client
787            .request_json(Request {
788                method: Method::GET,
789                path: "/api/v1/admin/config/markup".to_string(),
790                query: NO_QUERY,
791                body: NO_BODY,
792                headers: Vec::new(),
793                idempotent: false,
794            })
795            .await
796    }
797
798    /// Get platform base URLs (public_base_url, webhook_base_url)
799    ///
800    /// `GET /api/v1/admin/config/platform-urls`
801    ///
802    /// Required scopes: `admin`.
803    pub async fn get_platform_urls(&self) -> Result<models::GetPlatformURLSResponse> {
804        self.client
805            .request_json(Request {
806                method: Method::GET,
807                path: "/api/v1/admin/config/platform-urls".to_string(),
808                query: NO_QUERY,
809                body: NO_BODY,
810                headers: Vec::new(),
811                idempotent: false,
812            })
813            .await
814    }
815
816    /// Get rate limit config
817    ///
818    /// `GET /api/v1/admin/config/rate-limits`
819    ///
820    /// Required scopes: `admin`.
821    pub async fn get_rate_limits(&self) -> Result<models::GetRateLimitsResponse> {
822        self.client
823            .request_json(Request {
824                method: Method::GET,
825                path: "/api/v1/admin/config/rate-limits".to_string(),
826                query: NO_QUERY,
827                body: NO_BODY,
828                headers: Vec::new(),
829                idempotent: false,
830            })
831            .await
832    }
833
834    /// Get last reconciliation result
835    ///
836    /// `GET /api/v1/admin/config/reconciliation`
837    ///
838    /// Required scopes: `admin`.
839    pub async fn get_reconciliation(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
840        self.client
841            .request_json(Request {
842                method: Method::GET,
843                path: "/api/v1/admin/config/reconciliation".to_string(),
844                query: NO_QUERY,
845                body: NO_BODY,
846                headers: Vec::new(),
847                idempotent: false,
848            })
849            .await
850    }
851
852    /// Get runtime config
853    ///
854    /// `GET /api/v1/admin/config/runtime`
855    ///
856    /// Required scopes: `admin`.
857    pub async fn get_runtime_config(&self) -> Result<models::GetRuntimeConfigResponse> {
858        self.client
859            .request_json(Request {
860                method: Method::GET,
861                path: "/api/v1/admin/config/runtime".to_string(),
862                query: NO_QUERY,
863                body: NO_BODY,
864                headers: Vec::new(),
865                idempotent: false,
866            })
867            .await
868    }
869
870    /// Get CORS / SSRF / upload / admin-RBAC policies
871    ///
872    /// `GET /api/v1/admin/config/security-policies`
873    ///
874    /// Required scopes: `admin`.
875    pub async fn get_security_policies(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
876        self.client
877            .request_json(Request {
878                method: Method::GET,
879                path: "/api/v1/admin/config/security-policies".to_string(),
880                query: NO_QUERY,
881                body: NO_BODY,
882                headers: Vec::new(),
883                idempotent: false,
884            })
885            .await
886    }
887
888    /// Get webhook delivery + Stripe verification policy
889    ///
890    /// `GET /api/v1/admin/config/webhooks-policy`
891    ///
892    /// Required scopes: `admin`.
893    pub async fn get_webhooks_policy(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
894        self.client
895            .request_json(Request {
896                method: Method::GET,
897                path: "/api/v1/admin/config/webhooks-policy".to_string(),
898                query: NO_QUERY,
899                body: NO_BODY,
900                headers: Vec::new(),
901                idempotent: false,
902            })
903            .await
904    }
905
906    /// Bulk-apply a previously exported snapshot
907    ///
908    /// `POST /api/v1/admin/config/import`
909    ///
910    /// Required scopes: `admin`.
911    pub async fn import(&self, body: &models::ImportAdminConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
912        self.client
913            .request_json(Request {
914                method: Method::POST,
915                path: "/api/v1/admin/config/import".to_string(),
916                query: NO_QUERY,
917                body: Some(body),
918                headers: Vec::new(),
919                idempotent: true,
920            })
921            .await
922    }
923
924    /// The admin-authored plan catalogue
925    ///
926    /// Custom plans layer over the four built-in tiers. Ordered by `program` ascending — rows with
927    /// no program sort FIRST, because an absent program compares as the empty string — then by
928    /// `id`. `count` is `plans.length`, not a total across pages: there is no paging, the catalogue
929    /// is one stored record.
930    ///
931    /// Optional fields are ABSENT rather than null throughout, so a client must test presence and
932    /// not compare against null.
933    ///
934    /// `GET /api/v1/admin/config/custom-plans`
935    ///
936    /// Required scopes: `admin`.
937    pub async fn list_custom_plans(&self) -> Result<models::ListCustomPlansResponse> {
938        self.client
939            .request_json(Request {
940                method: Method::GET,
941                path: "/api/v1/admin/config/custom-plans".to_string(),
942                query: NO_QUERY,
943                body: NO_BODY,
944                headers: Vec::new(),
945                idempotent: false,
946            })
947            .await
948    }
949
950    /// Referral and promo codes
951    ///
952    /// A promo code pays its owner tenant bonus tokens for every paid subscription redeemed with
953    /// it, and grants the subscriber a welcome balance. `count` is the array length; there is no
954    /// paging.
955    ///
956    /// `GET /api/v1/admin/config/promo-codes`
957    ///
958    /// Required scopes: `admin`.
959    pub async fn list_promo_codes(&self) -> Result<models::ListPromoCodesResponse> {
960        self.client
961            .request_json(Request {
962                method: Method::GET,
963                path: "/api/v1/admin/config/promo-codes".to_string(),
964                query: NO_QUERY,
965                body: NO_BODY,
966                headers: Vec::new(),
967                idempotent: false,
968            })
969            .await
970    }
971
972    /// What one promo code has paid out
973    ///
974    /// One entry per reward actually granted — the audit trail behind a code's `uses`. Matched
975    /// before the `{code}` route, so a code literally named `rewards` cannot shadow it.
976    ///
977    /// `GET /api/v1/admin/config/promo-codes/{code}/rewards`
978    ///
979    /// Required scopes: `admin`.
980    pub async fn list_promo_rewards(&self, code: &str) -> Result<models::ListPromoRewardsResponse> {
981        self.client
982            .request_json(Request {
983                method: Method::GET,
984                path: format!("/api/v1/admin/config/promo-codes/{}/rewards", encode_path(code)),
985                query: NO_QUERY,
986                body: NO_BODY,
987                headers: Vec::new(),
988                idempotent: false,
989            })
990            .await
991    }
992
993    /// Run reconciliation
994    ///
995    /// `POST /api/v1/admin/config/reconciliation`
996    ///
997    /// Required scopes: `admin`.
998    pub async fn run_reconciliation(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
999        self.client
1000            .request_json(Request {
1001                method: Method::POST,
1002                path: "/api/v1/admin/config/reconciliation".to_string(),
1003                query: NO_QUERY,
1004                body: NO_BODY,
1005                headers: Vec::new(),
1006                idempotent: true,
1007            })
1008            .await
1009    }
1010
1011    /// Set feature flags
1012    ///
1013    /// `PUT /api/v1/admin/config/feature-flags`
1014    ///
1015    /// Required scopes: `admin`.
1016    pub async fn set_feature_flags(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1017        self.client
1018            .request_json(Request {
1019                method: Method::PUT,
1020                path: "/api/v1/admin/config/feature-flags".to_string(),
1021                query: NO_QUERY,
1022                body: Some(body),
1023                headers: Vec::new(),
1024                idempotent: true,
1025            })
1026            .await
1027    }
1028
1029    /// Override the billed price of one model
1030    ///
1031    /// Sets what the platform charges for a model, independent of the catalogue. Validated by hand
1032    /// rather than by a schema, so the failures are worth stating: a body that is not JSON is 400;
1033    /// `input_per_million` or `output_per_million` missing, negative, or not coercible to a finite
1034    /// number is 400; `cached_input_per_million`, when present, must be a non-negative number or
1035    /// 400.
1036    ///
1037    /// WRITE SEMANTICS: the entry replaces, the map merges. This overwrites the override for this
1038    /// model only and leaves every other model's override untouched. Omitting
1039    /// `cached_input_per_million` removes it, and cached tokens then bill at the full input rate.
1040    ///
1041    /// Note the response key is `modelRef` — camelCase, an outlier in a snake_case API, and
1042    /// documented as sent.
1043    ///
1044    /// `PUT /api/v1/admin/config/model-pricing/{modelRef}`
1045    ///
1046    /// Required scopes: `admin`.
1047    pub async fn set_model_pricing_override(&self, model_ref: &str, body: &models::SetModelPricingOverrideRequest) -> Result<models::SetModelPricingOverrideResponse> {
1048        self.client
1049            .request_json(Request {
1050                method: Method::PUT,
1051                path: format!("/api/v1/admin/config/model-pricing/{}", encode_path(model_ref)),
1052                query: NO_QUERY,
1053                body: Some(body),
1054                headers: Vec::new(),
1055                idempotent: true,
1056            })
1057            .await
1058    }
1059
1060    /// Set rate limits
1061    ///
1062    /// `PUT /api/v1/admin/config/rate-limits`
1063    ///
1064    /// Required scopes: `admin`.
1065    pub async fn set_rate_limits(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1066        self.client
1067            .request_json(Request {
1068                method: Method::PUT,
1069                path: "/api/v1/admin/config/rate-limits".to_string(),
1070                query: NO_QUERY,
1071                body: Some(body),
1072                headers: Vec::new(),
1073                idempotent: true,
1074            })
1075            .await
1076    }
1077
1078    /// Send a test email through the effective SMTP config
1079    ///
1080    /// Sends for real, using whichever layer `source` reports — this is not a dry run. A delivery
1081    /// failure is **500** carrying the SMTP error text, not a 200 with `ok: false`, so a client
1082    /// must read the status rather than a field.
1083    ///
1084    /// `POST /api/v1/admin/config/smtp/test`
1085    ///
1086    /// Required scopes: `admin`.
1087    pub async fn test_admin_smtp_config(&self, body: &models::TestAdminSmtpConfigRequest) -> Result<models::TestAdminSmtpConfigResponse> {
1088        self.client
1089            .request_json(Request {
1090                method: Method::POST,
1091                path: "/api/v1/admin/config/smtp/test".to_string(),
1092                query: NO_QUERY,
1093                body: Some(body),
1094                headers: Vec::new(),
1095                idempotent: true,
1096            })
1097            .await
1098    }
1099
1100    /// Verify stored secret_key authenticates against Stripe (read-only)
1101    ///
1102    /// `POST /api/v1/admin/config/stripe/test`
1103    ///
1104    /// Required scopes: `admin`.
1105    pub async fn test_admin_stripe_config(&self) -> Result<serde_json::Map<String, serde_json::Value>> {
1106        self.client
1107            .request_json(Request {
1108                method: Method::POST,
1109                path: "/api/v1/admin/config/stripe/test".to_string(),
1110                query: NO_QUERY,
1111                body: NO_BODY,
1112                headers: Vec::new(),
1113                idempotent: true,
1114            })
1115            .await
1116    }
1117
1118    /// Update agent memory overrides
1119    ///
1120    /// `PUT /api/v1/admin/config/agent-memory`
1121    ///
1122    /// Required scopes: `admin`.
1123    pub async fn update_admin_agent_memory_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1124        self.client
1125            .request_json(Request {
1126                method: Method::PUT,
1127                path: "/api/v1/admin/config/agent-memory".to_string(),
1128                query: NO_QUERY,
1129                body: Some(body),
1130                headers: Vec::new(),
1131                idempotent: true,
1132            })
1133            .await
1134    }
1135
1136    /// Update auth runtime overrides
1137    ///
1138    /// `PUT /api/v1/admin/config/auth`
1139    ///
1140    /// Required scopes: `admin`.
1141    pub async fn update_admin_auth_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1142        self.client
1143            .request_json(Request {
1144                method: Method::PUT,
1145                path: "/api/v1/admin/config/auth".to_string(),
1146                query: NO_QUERY,
1147                body: Some(body),
1148                headers: Vec::new(),
1149                idempotent: true,
1150            })
1151            .await
1152    }
1153
1154    /// Update backpressure overrides
1155    ///
1156    /// `PUT /api/v1/admin/config/backpressure`
1157    ///
1158    /// Required scopes: `admin`.
1159    pub async fn update_admin_backpressure_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1160        self.client
1161            .request_json(Request {
1162                method: Method::PUT,
1163                path: "/api/v1/admin/config/backpressure".to_string(),
1164                query: NO_QUERY,
1165                body: Some(body),
1166                headers: Vec::new(),
1167                idempotent: true,
1168            })
1169            .await
1170    }
1171
1172    /// Update code-interpreter overrides
1173    ///
1174    /// `PUT /api/v1/admin/config/code-interpreter`
1175    ///
1176    /// Required scopes: `admin`.
1177    pub async fn update_admin_code_interpreter_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1178        self.client
1179            .request_json(Request {
1180                method: Method::PUT,
1181                path: "/api/v1/admin/config/code-interpreter".to_string(),
1182                query: NO_QUERY,
1183                body: Some(body),
1184                headers: Vec::new(),
1185                idempotent: true,
1186            })
1187            .await
1188    }
1189
1190    /// Replace the platform-wide disabled tool list
1191    ///
1192    /// **The body is a bare JSON ARRAY, not an object** — an outlier on a surface where every other
1193    /// write takes an object, and a client that wraps it in `{disabled_tools: \[…\]}` gets 400.
1194    ///
1195    /// Gated on a FRESH MFA challenge.
1196    ///
1197    /// WRITE SEMANTICS: replaces. The array given becomes the list. It must be NON-EMPTY and every
1198    /// element a non-empty string, so there is no way to disable nothing through this route —
1199    /// clearing the list is not expressible here.
1200    ///
1201    /// `PUT /api/v1/admin/config/disabled-tools`
1202    ///
1203    /// Required scopes: `admin`.
1204    pub async fn update_admin_disabled_tools(&self, body: &Vec<String>) -> Result<models::UpdateAdminDisabledToolsResponse> {
1205        self.client
1206            .request_json(Request {
1207                method: Method::PUT,
1208                path: "/api/v1/admin/config/disabled-tools".to_string(),
1209                query: NO_QUERY,
1210                body: Some(body),
1211                headers: Vec::new(),
1212                idempotent: true,
1213            })
1214            .await
1215    }
1216
1217    /// Update evaluation overrides
1218    ///
1219    /// `PUT /api/v1/admin/config/evaluation`
1220    ///
1221    /// Required scopes: `admin`.
1222    pub async fn update_admin_evaluation_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1223        self.client
1224            .request_json(Request {
1225                method: Method::PUT,
1226                path: "/api/v1/admin/config/evaluation".to_string(),
1227                query: NO_QUERY,
1228                body: Some(body),
1229                headers: Vec::new(),
1230                idempotent: true,
1231            })
1232            .await
1233    }
1234
1235    /// Set the stored founder identity
1236    ///
1237    /// Answers the same body the GET does.
1238    ///
1239    /// WRITE SEMANTICS: merges. Omitted fields keep their stored values. Unlike SMTP, an empty
1240    /// string IS accepted on every field here and means "leave unset" — deliberately, because the
1241    /// admin UI echoes current values back and a no-op save of an unset identity must not 422.
1242    ///
1243    /// `PUT /api/v1/admin/config/founder`
1244    ///
1245    /// Required scopes: `admin`.
1246    pub async fn update_admin_founder_config(&self, body: &models::UpdateAdminFounderConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1247        self.client
1248            .request_json(Request {
1249                method: Method::PUT,
1250                path: "/api/v1/admin/config/founder".to_string(),
1251                query: NO_QUERY,
1252                body: Some(body),
1253                headers: Vec::new(),
1254                idempotent: true,
1255            })
1256            .await
1257    }
1258
1259    /// Update guardrail config
1260    ///
1261    /// `PUT /api/v1/admin/config/guardrails`
1262    ///
1263    /// Required scopes: `admin`.
1264    pub async fn update_admin_guardrails(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1265        self.client
1266            .request_json(Request {
1267                method: Method::PUT,
1268                path: "/api/v1/admin/config/guardrails".to_string(),
1269                query: NO_QUERY,
1270                body: Some(body),
1271                headers: Vec::new(),
1272                idempotent: true,
1273            })
1274            .await
1275    }
1276
1277    /// Update idempotency overrides
1278    ///
1279    /// `PUT /api/v1/admin/config/idempotency`
1280    ///
1281    /// Required scopes: `admin`.
1282    pub async fn update_admin_idempotency_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1283        self.client
1284            .request_json(Request {
1285                method: Method::PUT,
1286                path: "/api/v1/admin/config/idempotency".to_string(),
1287                query: NO_QUERY,
1288                body: Some(body),
1289                headers: Vec::new(),
1290                idempotent: true,
1291            })
1292            .await
1293    }
1294
1295    /// Update integrations
1296    ///
1297    /// `PUT /api/v1/admin/config/integrations`
1298    ///
1299    /// Required scopes: `admin`.
1300    pub async fn update_admin_integrations(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1301        self.client
1302            .request_json(Request {
1303                method: Method::PUT,
1304                path: "/api/v1/admin/config/integrations".to_string(),
1305                query: NO_QUERY,
1306                body: Some(body),
1307                headers: Vec::new(),
1308                idempotent: true,
1309            })
1310            .await
1311    }
1312
1313    /// Update LLM adapter overrides
1314    ///
1315    /// `PUT /api/v1/admin/config/llm-adapters`
1316    ///
1317    /// Required scopes: `admin`.
1318    pub async fn update_admin_llm_adapters_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1319        self.client
1320            .request_json(Request {
1321                method: Method::PUT,
1322                path: "/api/v1/admin/config/llm-adapters".to_string(),
1323                query: NO_QUERY,
1324                body: Some(body),
1325                headers: Vec::new(),
1326                idempotent: true,
1327            })
1328            .await
1329    }
1330
1331    /// Update logging overrides
1332    ///
1333    /// `PUT /api/v1/admin/config/logging`
1334    ///
1335    /// Required scopes: `admin`.
1336    pub async fn update_admin_logging_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1337        self.client
1338            .request_json(Request {
1339                method: Method::PUT,
1340                path: "/api/v1/admin/config/logging".to_string(),
1341                query: NO_QUERY,
1342                body: Some(body),
1343                headers: Vec::new(),
1344                idempotent: true,
1345            })
1346            .await
1347    }
1348
1349    /// Update long-running overrides
1350    ///
1351    /// `PUT /api/v1/admin/config/long-running`
1352    ///
1353    /// Required scopes: `admin`.
1354    pub async fn update_admin_long_running_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1355        self.client
1356            .request_json(Request {
1357                method: Method::PUT,
1358                path: "/api/v1/admin/config/long-running".to_string(),
1359                query: NO_QUERY,
1360                body: Some(body),
1361                headers: Vec::new(),
1362                idempotent: true,
1363            })
1364            .await
1365    }
1366
1367    /// Update MCP overrides
1368    ///
1369    /// `PUT /api/v1/admin/config/mcp`
1370    ///
1371    /// Required scopes: `admin`.
1372    pub async fn update_admin_mcp_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1373        self.client
1374            .request_json(Request {
1375                method: Method::PUT,
1376                path: "/api/v1/admin/config/mcp".to_string(),
1377                query: NO_QUERY,
1378                body: Some(body),
1379                headers: Vec::new(),
1380                idempotent: true,
1381            })
1382            .await
1383    }
1384
1385    /// Update multimodal overrides
1386    ///
1387    /// `PUT /api/v1/admin/config/multimodal`
1388    ///
1389    /// Required scopes: `admin`.
1390    pub async fn update_admin_multimodal_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1391        self.client
1392            .request_json(Request {
1393                method: Method::PUT,
1394                path: "/api/v1/admin/config/multimodal".to_string(),
1395                query: NO_QUERY,
1396                body: Some(body),
1397                headers: Vec::new(),
1398                idempotent: true,
1399            })
1400            .await
1401    }
1402
1403    /// Set Apple identifiers and the return-to allowlist
1404    ///
1405    /// Answers the same body the GET does.
1406    ///
1407    /// WRITE SEMANTICS: merges. Omitted fields keep their stored values; a present
1408    /// `oauth_return_to_hosts` REPLACES the stored list rather than adding to it.
1409    ///
1410    /// `PUT /api/v1/admin/config/oauth-identity`
1411    ///
1412    /// Required scopes: `admin`.
1413    pub async fn update_admin_o_auth_identity_config(&self, body: &models::UpdateAdminOAuthIdentityConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1414        self.client
1415            .request_json(Request {
1416                method: Method::PUT,
1417                path: "/api/v1/admin/config/oauth-identity".to_string(),
1418                query: NO_QUERY,
1419                body: Some(body),
1420                headers: Vec::new(),
1421                idempotent: true,
1422            })
1423            .await
1424    }
1425
1426    /// Update persistence overrides
1427    ///
1428    /// `PUT /api/v1/admin/config/persistence`
1429    ///
1430    /// Required scopes: `admin`.
1431    pub async fn update_admin_persistence_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1432        self.client
1433            .request_json(Request {
1434                method: Method::PUT,
1435                path: "/api/v1/admin/config/persistence".to_string(),
1436                query: NO_QUERY,
1437                body: Some(body),
1438                headers: Vec::new(),
1439                idempotent: true,
1440            })
1441            .await
1442    }
1443
1444    /// Update plans
1445    ///
1446    /// `PUT /api/v1/admin/config/plans`
1447    ///
1448    /// Required scopes: `admin`.
1449    pub async fn update_admin_plans(&self, body: &models::UpdateAdminPlansRequest) -> Result<models::UpdateAdminPlansResponse> {
1450        self.client
1451            .request_json(Request {
1452                method: Method::PUT,
1453                path: "/api/v1/admin/config/plans".to_string(),
1454                query: NO_QUERY,
1455                body: Some(body),
1456                headers: Vec::new(),
1457                idempotent: true,
1458            })
1459            .await
1460    }
1461
1462    /// Open or close registration, and set signup defaults
1463    ///
1464    /// **Opening registration when it is currently CLOSED requires `confirm_open: true`.** Without
1465    /// it the answer is 400, and the message says so. This is not ceremony: on 2026-06-11 a
1466    /// long-lived admin tab running a stale bundle re-submitted its whole form four times in one
1467    /// day, each time carrying a stale `registration_open: true`, and silently re-opened doors an
1468    /// operator had ordered shut. An explicit confirm is something no stale form can send by
1469    /// accident. Closing, and a no-op re-save while already open, need no confirm.
1470    ///
1471    /// A second 400 refuses opening while required setup steps are outstanding, and names them.
1472    ///
1473    /// Answers the same body the GET does.
1474    ///
1475    /// WRITE SEMANTICS: merges. Omitted fields keep their stored values. `default_signup_plan` and
1476    /// `allowed_email_domains` are stored only when present; an empty `default_signup_plan` clears
1477    /// it back to the `free` default.
1478    ///
1479    /// `PUT /api/v1/admin/config/registration`
1480    ///
1481    /// Required scopes: `admin`.
1482    pub async fn update_admin_registration_config(&self, body: &models::UpdateAdminRegistrationConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1483        self.client
1484            .request_json(Request {
1485                method: Method::PUT,
1486                path: "/api/v1/admin/config/registration".to_string(),
1487                query: NO_QUERY,
1488                body: Some(body),
1489                headers: Vec::new(),
1490                idempotent: true,
1491            })
1492            .await
1493    }
1494
1495    /// Update retention overrides
1496    ///
1497    /// `PUT /api/v1/admin/config/retention`
1498    ///
1499    /// Required scopes: `admin`.
1500    pub async fn update_admin_retention_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1501        self.client
1502            .request_json(Request {
1503                method: Method::PUT,
1504                path: "/api/v1/admin/config/retention".to_string(),
1505                query: NO_QUERY,
1506                body: Some(body),
1507                headers: Vec::new(),
1508                idempotent: true,
1509            })
1510            .await
1511    }
1512
1513    /// Update run_command overrides
1514    ///
1515    /// `PUT /api/v1/admin/config/run-command`
1516    ///
1517    /// Required scopes: `admin`.
1518    pub async fn update_admin_run_command_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1519        self.client
1520            .request_json(Request {
1521                method: Method::PUT,
1522                path: "/api/v1/admin/config/run-command".to_string(),
1523                query: NO_QUERY,
1524                body: Some(body),
1525                headers: Vec::new(),
1526                idempotent: true,
1527            })
1528            .await
1529    }
1530
1531    /// Update server overrides
1532    ///
1533    /// `PUT /api/v1/admin/config/server`
1534    ///
1535    /// Required scopes: `admin`.
1536    pub async fn update_admin_server_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1537        self.client
1538            .request_json(Request {
1539                method: Method::PUT,
1540                path: "/api/v1/admin/config/server".to_string(),
1541                query: NO_QUERY,
1542                body: Some(body),
1543                headers: Vec::new(),
1544                idempotent: true,
1545            })
1546            .await
1547    }
1548
1549    /// Mark setup steps complete, or flip the registration gate
1550    ///
1551    /// WRITE SEMANTICS: mixed, and the mixed half is the point. `completed_steps` is a UNION — the
1552    /// steps given are ADDED to the stored list and never removed — so re-sending the same PATCH is
1553    /// idempotent and there is no way to un-complete a step through this route. `registration_open`
1554    /// is a plain overwrite.
1555    ///
1556    /// **Opening registration requires `confirm_open: true`** when it is currently closed, exactly
1557    /// as `PUT /api/v1/admin/config/registration` does. The guard lives in both places on purpose:
1558    /// without it here, the lower-level endpoint was a way around the confirm that the launch-day
1559    /// incident of 2026-06-11 put there.
1560    ///
1561    /// Opening also refuses with 400 while any required step is outstanding, naming them.
1562    ///
1563    /// `status` reaching `live` is a ONE-WAY latch. Once setup has completed, CLOSING registration
1564    /// is an operational mode — a pre-registration wave — and does NOT return the platform to
1565    /// `in_progress`. Before that was fixed, closing sent the super admin back into the setup
1566    /// wizard on every page, and the wizard's only exit was the very switch they had just turned
1567    /// off.
1568    ///
1569    /// The write is a compare-and-set retried up to six times; a persistently contended record
1570    /// answers **503** rather than overwriting a concurrent change.
1571    ///
1572    /// `PATCH /api/v1/admin/config/setup-state`
1573    ///
1574    /// Required scopes: `admin`.
1575    pub async fn update_admin_setup_state(&self, body: &models::UpdateAdminSetupStateRequest) -> Result<models::SetupStateResponse> {
1576        self.client
1577            .request_json(Request {
1578                method: Method::PATCH,
1579                path: "/api/v1/admin/config/setup-state".to_string(),
1580                query: NO_QUERY,
1581                body: Some(body),
1582                headers: Vec::new(),
1583                idempotent: true,
1584            })
1585            .await
1586    }
1587
1588    /// Update stored SMTP config
1589    ///
1590    /// Answers the same body the GET does, so a client does not re-read to see what took effect.
1591    ///
1592    /// WRITE SEMANTICS: merges. A field the body omits keeps its stored value. An empty string
1593    /// CLEARS, but only where the validator admits one: `password` and `from_name` accept `""`,
1594    /// while `host`, `user` and `from` are rejected with 422 before the merge is reached — `host`
1595    /// and `user` require at least one character and `from` must parse as an email. So a stored
1596    /// host cannot be blanked through this route, only overwritten.
1597    ///
1598    /// `password: ""` is the operator-initiated clear: it drops both the encrypted and plaintext
1599    /// fields so the next read falls back to the environment. A password is stored
1600    /// AES-GCM-encrypted when an encryption key is configured; without one it is stored in
1601    /// plaintext and the server logs a warning rather than refusing.
1602    ///
1603    /// `PUT /api/v1/admin/config/smtp`
1604    ///
1605    /// Required scopes: `admin`.
1606    pub async fn update_admin_smtp_config(&self, body: &models::UpdateAdminSmtpConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1607        self.client
1608            .request_json(Request {
1609                method: Method::PUT,
1610                path: "/api/v1/admin/config/smtp".to_string(),
1611                query: NO_QUERY,
1612                body: Some(body),
1613                headers: Vec::new(),
1614                idempotent: true,
1615            })
1616            .await
1617    }
1618
1619    /// Replace the SPEC-package map
1620    ///
1621    /// WRITE SEMANTICS: replaces. The map given becomes the whole map, so a package omitted from
1622    /// the body is DELETED. Two guards exist because of that.
1623    ///
1624    /// **A drop that would remove a package with a wired `stripe_price_id` is refused with 422**
1625    /// unless the caller opts in per id: `?confirm_drop=\<id\>\[,\<id\>\]`. Tenants may be
1626    /// subscribed against that price, so losing it silently is not a save, it is a billing
1627    /// incident. The refusal names every id it is protecting.
1628    ///
1629    /// **Each map KEY must equal its record's `package_id`**, or 422. The map is keyed by id
1630    /// everywhere downstream, so a key that disagrees with its record orphans the package at the
1631    /// next read.
1632    ///
1633    /// `updated_at` is stamped by the server on every record in the payload and is not read from
1634    /// the body.
1635    ///
1636    /// `PUT /api/v1/admin/config/spec-packages`
1637    ///
1638    /// Required scopes: `admin`.
1639    pub async fn update_admin_spec_packages(&self, body: &models::UpdateAdminSpecPackagesRequest, params: &UpdateAdminSpecPackagesParams) -> Result<serde_json::Map<String, serde_json::Value>> {
1640        self.client
1641            .request_json(Request {
1642                method: Method::PUT,
1643                path: "/api/v1/admin/config/spec-packages".to_string(),
1644                query: Some(params),
1645                body: Some(body),
1646                headers: Vec::new(),
1647                idempotent: true,
1648            })
1649            .await
1650    }
1651
1652    /// Update SSE overrides
1653    ///
1654    /// `PUT /api/v1/admin/config/sse`
1655    ///
1656    /// Required scopes: `admin`.
1657    pub async fn update_admin_sse_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1658        self.client
1659            .request_json(Request {
1660                method: Method::PUT,
1661                path: "/api/v1/admin/config/sse".to_string(),
1662                query: NO_QUERY,
1663                body: Some(body),
1664                headers: Vec::new(),
1665                idempotent: true,
1666            })
1667            .await
1668    }
1669
1670    /// Update Stripe keys/mode/price IDs; rebuilds BillingManager
1671    ///
1672    /// `PUT /api/v1/admin/config/stripe`
1673    ///
1674    /// Required scopes: `admin`.
1675    pub async fn update_admin_stripe_config(&self, body: &models::UpdateAdminStripeConfigRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1676        self.client
1677            .request_json(Request {
1678                method: Method::PUT,
1679                path: "/api/v1/admin/config/stripe".to_string(),
1680                query: NO_QUERY,
1681                body: Some(body),
1682                headers: Vec::new(),
1683                idempotent: true,
1684            })
1685            .await
1686    }
1687
1688    /// Replace the per-tool presentation overrides
1689    ///
1690    /// These affect PRESENTATION only. The runtime tool catalogue is code-defined, so an override
1691    /// changes what the catalogue page shows and nothing about what an agent can call — including
1692    /// `hidden`, which hides the row by default while the runtime still serves the tool. An
1693    /// operator reaching for `hidden` to switch a tool OFF wants `disabled-tools` instead.
1694    ///
1695    /// Gated on a FRESH MFA challenge.
1696    ///
1697    /// WRITE SEMANTICS: replaces. The map given becomes the whole map, so an id omitted from the
1698    /// body is deleted. Two further rules follow from that: an entry whose fields are all empty is
1699    /// DROPPED rather than stored — sending `{}` for an id is how the client deletes just that one
1700    /// — and `hidden` is stored only when literally `true`, so `hidden: false` deletes the flag
1701    /// rather than recording it.
1702    ///
1703    /// Every key is checked against the runtime's built-in tool ids: an unknown id is **422**,
1704    /// distinct from the 400 a malformed body gets. The outer object is strict — an unexpected
1705    /// top-level key is rejected, not stripped.
1706    ///
1707    /// `PUT /api/v1/admin/config/tool-overrides`
1708    ///
1709    /// Required scopes: `admin`.
1710    pub async fn update_admin_tool_overrides(&self, body: &models::UpdateAdminToolOverridesRequest) -> Result<models::UpdateAdminToolOverridesResponse> {
1711        self.client
1712            .request_json(Request {
1713                method: Method::PUT,
1714                path: "/api/v1/admin/config/tool-overrides".to_string(),
1715                query: NO_QUERY,
1716                body: Some(body),
1717                headers: Vec::new(),
1718                idempotent: true,
1719            })
1720            .await
1721    }
1722
1723    /// Update tool security overrides
1724    ///
1725    /// `PUT /api/v1/admin/config/tool-security`
1726    ///
1727    /// Required scopes: `admin`.
1728    pub async fn update_admin_tool_security_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1729        self.client
1730            .request_json(Request {
1731                method: Method::PUT,
1732                path: "/api/v1/admin/config/tool-security".to_string(),
1733                query: NO_QUERY,
1734                body: Some(body),
1735                headers: Vec::new(),
1736                idempotent: true,
1737            })
1738            .await
1739    }
1740
1741    /// Update webhook delivery overrides
1742    ///
1743    /// `PUT /api/v1/admin/config/webhooks`
1744    ///
1745    /// Required scopes: `admin`.
1746    pub async fn update_admin_webhooks_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1747        self.client
1748            .request_json(Request {
1749                method: Method::PUT,
1750                path: "/api/v1/admin/config/webhooks".to_string(),
1751                query: NO_QUERY,
1752                body: Some(body),
1753                headers: Vec::new(),
1754                idempotent: true,
1755            })
1756            .await
1757    }
1758
1759    /// Update worker pool overrides
1760    ///
1761    /// `PUT /api/v1/admin/config/worker-pool`
1762    ///
1763    /// Required scopes: `admin`.
1764    pub async fn update_admin_worker_pool_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1765        self.client
1766            .request_json(Request {
1767                method: Method::PUT,
1768                path: "/api/v1/admin/config/worker-pool".to_string(),
1769                query: NO_QUERY,
1770                body: Some(body),
1771                headers: Vec::new(),
1772                idempotent: true,
1773            })
1774            .await
1775    }
1776
1777    /// Update markup
1778    ///
1779    /// `PUT /api/v1/admin/config/markup`
1780    ///
1781    /// Required scopes: `admin`.
1782    pub async fn update_markup_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1783        self.client
1784            .request_json(Request {
1785                method: Method::PUT,
1786                path: "/api/v1/admin/config/markup".to_string(),
1787                query: NO_QUERY,
1788                body: Some(body),
1789                headers: Vec::new(),
1790                idempotent: true,
1791            })
1792            .await
1793    }
1794
1795    /// Update public_base_url and webhook_base_url
1796    ///
1797    /// `PUT /api/v1/admin/config/platform-urls`
1798    ///
1799    /// Required scopes: `admin`.
1800    pub async fn update_platform_urls(&self, body: &models::UpdatePlatformURLSRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1801        self.client
1802            .request_json(Request {
1803                method: Method::PUT,
1804                path: "/api/v1/admin/config/platform-urls".to_string(),
1805                query: NO_QUERY,
1806                body: Some(body),
1807                headers: Vec::new(),
1808                idempotent: true,
1809            })
1810            .await
1811    }
1812
1813    /// Update runtime
1814    ///
1815    /// `PUT /api/v1/admin/config/runtime`
1816    ///
1817    /// Required scopes: `admin`.
1818    pub async fn update_runtime_config(&self, body: &serde_json::Map<String, serde_json::Value>) -> Result<serde_json::Map<String, serde_json::Value>> {
1819        self.client
1820            .request_json(Request {
1821                method: Method::PUT,
1822                path: "/api/v1/admin/config/runtime".to_string(),
1823                query: NO_QUERY,
1824                body: Some(body),
1825                headers: Vec::new(),
1826                idempotent: true,
1827            })
1828            .await
1829    }
1830
1831    /// Update security policies
1832    ///
1833    /// `PUT /api/v1/admin/config/security-policies`
1834    ///
1835    /// Required scopes: `admin`.
1836    pub async fn update_security_policies(&self, body: &models::UpdateSecurityPoliciesRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1837        self.client
1838            .request_json(Request {
1839                method: Method::PUT,
1840                path: "/api/v1/admin/config/security-policies".to_string(),
1841                query: NO_QUERY,
1842                body: Some(body),
1843                headers: Vec::new(),
1844                idempotent: true,
1845            })
1846            .await
1847    }
1848
1849    /// Update webhooks policy
1850    ///
1851    /// `PUT /api/v1/admin/config/webhooks-policy`
1852    ///
1853    /// Required scopes: `admin`.
1854    pub async fn update_webhooks_policy(&self, body: &models::UpdateWebhooksPolicyRequest) -> Result<serde_json::Map<String, serde_json::Value>> {
1855        self.client
1856            .request_json(Request {
1857                method: Method::PUT,
1858                path: "/api/v1/admin/config/webhooks-policy".to_string(),
1859                query: NO_QUERY,
1860                body: Some(body),
1861                headers: Vec::new(),
1862                idempotent: true,
1863            })
1864            .await
1865    }
1866
1867    /// Create or replace one custom plan
1868    ///
1869    /// WRITE SEMANTICS: replaces. The stored record is rebuilt from this body; only `created_at`
1870    /// survives from the previous version. An omitted field does NOT keep its stored value — it
1871    /// takes the schema's default or disappears.
1872    ///
1873    /// **Two defaults make an omission destructive, and the dangerous one is `active`.** It is
1874    /// `default(true)`, so re-saving a DEACTIVATED plan without sending `active` silently
1875    /// reactivates it. `visibility` is `default("hidden")`, so re-saving a public plan without
1876    /// sending it hides the plan from every tenant. Neither reports anything: the answer is 200 and
1877    /// the record looks freshly written.
1878    ///
1879    /// Unknown keys are stripped rather than rejected, so a typo'd field name is accepted and
1880    /// dropped with a 200.
1881    ///
1882    /// A built-in plan id (`free`, `starter`, `pro`, `enterprise`) is **409**, pointing at `PUT
1883    /// /api/v1/admin/config/plans` — the route that does own those.
1884    ///
1885    /// `PUT /api/v1/admin/config/custom-plans/{planId}`
1886    ///
1887    /// Required scopes: `admin`.
1888    pub async fn upsert_custom_plan(&self, plan_id: &str, body: &models::CustomPlanInput) -> Result<models::UpsertCustomPlanResponse> {
1889        self.client
1890            .request_json(Request {
1891                method: Method::PUT,
1892                path: format!("/api/v1/admin/config/custom-plans/{}", encode_path(plan_id)),
1893                query: NO_QUERY,
1894                body: Some(body),
1895                headers: Vec::new(),
1896                idempotent: true,
1897            })
1898            .await
1899    }
1900
1901    /// Create or replace one promo code
1902    ///
1903    /// WRITE SEMANTICS: replaces. Only `uses` and `created_at` survive from the previous version;
1904    /// every other field comes from this body, and an omitted field is dropped.
1905    ///
1906    /// **`target_plan_id` is the omission that costs money.** It scopes the code to one plan, and
1907    /// the reward path returns early when it is set and does not match the plan being paid for.
1908    /// Replace a scoped code without resending it and the code becomes redeemable on EVERY plan —
1909    /// 200, no warning, and the stored row looks the same size as before. `active` behaves the same
1910    /// way as on custom plans: `default(true)`, so omitting it reactivates a deactivated code.
1911    ///
1912    /// `PUT /api/v1/admin/config/promo-codes/{code}`
1913    ///
1914    /// Required scopes: `admin`.
1915    pub async fn upsert_promo_code(&self, code: &str, body: &models::PromoCodeInput) -> Result<models::UpsertPromoCodeResponse> {
1916        self.client
1917            .request_json(Request {
1918                method: Method::PUT,
1919                path: format!("/api/v1/admin/config/promo-codes/{}", encode_path(code)),
1920                query: NO_QUERY,
1921                body: Some(body),
1922                headers: Vec::new(),
1923                idempotent: true,
1924            })
1925            .await
1926    }
1927}