diff --git a/assets/js/components/api-auth-input.ts b/assets/js/components/api-auth-input.ts
new file mode 100644
index 000000000..aa5f0b0e2
--- /dev/null
+++ b/assets/js/components/api-auth-input.ts
@@ -0,0 +1,128 @@
+/**
+ * API Auth Input Component
+ *
+ * Provides credential input fields for API operations.
+ * Stores credentials in sessionStorage for "Try it" requests.
+ */
+
+interface ComponentOptions {
+ component: HTMLElement;
+}
+
+interface AuthCredentials {
+ bearer?: string;
+ basic?: { username: string; password: string };
+ apiKey?: string;
+}
+
+const STORAGE_KEY = 'influxdb_api_credentials';
+
+/**
+ * Get stored credentials from sessionStorage
+ */
+function getCredentials(): AuthCredentials {
+ try {
+ const stored = sessionStorage.getItem(STORAGE_KEY);
+ return stored ? JSON.parse(stored) : {};
+ } catch {
+ return {};
+ }
+}
+
+/**
+ * Store credentials in sessionStorage
+ */
+function setCredentials(credentials: AuthCredentials): void {
+ sessionStorage.setItem(STORAGE_KEY, JSON.stringify(credentials));
+}
+
+/**
+ * Create the auth input form
+ */
+function createAuthForm(schemes: string[]): HTMLElement {
+ const form = document.createElement('div');
+ form.className = 'api-auth-form';
+ form.innerHTML = `
+
Authentication
+ Enter credentials to use with "Try it" requests.
+ ${
+ schemes.includes('bearer')
+ ? `
+
+
+
+
+ `
+ : ''
+ }
+ ${
+ schemes.includes('basic')
+ ? `
+
+
+
+
+
+
+
+
+ `
+ : ''
+ }
+
+ `;
+ return form;
+}
+
+/**
+ * Initialize the auth input component
+ */
+export default function ApiAuthInput({ component }: ComponentOptions): void {
+ const schemesAttr = component.dataset.schemes || 'bearer';
+ const schemes = schemesAttr.split(',').map((s) => s.trim().toLowerCase());
+
+ const form = createAuthForm(schemes);
+ component.appendChild(form);
+
+ // Load existing credentials
+ const credentials = getCredentials();
+ const bearerInput = form.querySelector('#auth-bearer');
+ const usernameInput = form.querySelector('#auth-username');
+ const passwordInput = form.querySelector('#auth-password');
+
+ if (bearerInput && credentials.bearer) {
+ bearerInput.value = credentials.bearer;
+ }
+ if (usernameInput && credentials.basic?.username) {
+ usernameInput.value = credentials.basic.username;
+ }
+ if (passwordInput && credentials.basic?.password) {
+ passwordInput.value = credentials.basic.password;
+ }
+
+ // Save button handler
+ const saveBtn = form.querySelector('.auth-save');
+ saveBtn?.addEventListener('click', () => {
+ const newCredentials: AuthCredentials = {};
+
+ if (bearerInput?.value) {
+ newCredentials.bearer = bearerInput.value;
+ }
+ if (usernameInput?.value || passwordInput?.value) {
+ newCredentials.basic = {
+ username: usernameInput?.value || '',
+ password: passwordInput?.value || '',
+ };
+ }
+
+ setCredentials(newCredentials);
+
+ // Notify RapiDoc of new credentials
+ const rapiDoc = document.querySelector('rapi-doc');
+ if (rapiDoc && 'setApiKey' in rapiDoc) {
+ (rapiDoc as any).setApiKey(newCredentials.bearer || '');
+ }
+
+ alert('Credentials saved for this session');
+ });
+}
diff --git a/assets/js/main.js b/assets/js/main.js
index 77fda067a..5cfb75098 100644
--- a/assets/js/main.js
+++ b/assets/js/main.js
@@ -46,6 +46,7 @@ import SidebarSearch from './components/sidebar-search.js';
import { SidebarToggle } from './sidebar-toggle.js';
import Theme from './theme.js';
import ThemeSwitch from './theme-switch.js';
+import ApiAuthInput from './components/api-auth-input.ts';
import ApiRapiDoc from './components/api-rapidoc.ts';
import ApiToc from './components/api-toc.ts';
import RapiDocMini from './components/rapidoc-mini.ts';
@@ -80,6 +81,7 @@ const componentRegistry = {
'sidebar-toggle': SidebarToggle,
theme: Theme,
'theme-switch': ThemeSwitch,
+ 'api-auth-input': ApiAuthInput,
'api-rapidoc': ApiRapiDoc,
'api-toc': ApiToc,
'rapidoc-mini': RapiDocMini,
diff --git a/assets/styles/layouts/_api-security-schemes.scss b/assets/styles/layouts/_api-security-schemes.scss
index 16380f425..ee0860d5c 100644
--- a/assets/styles/layouts/_api-security-schemes.scss
+++ b/assets/styles/layouts/_api-security-schemes.scss
@@ -70,3 +70,90 @@
}
}
}
+
+////////////////////////////////////////////////////////////////////////////////
+// API Auth Form - Custom credential input for operation pages
+////////////////////////////////////////////////////////////////////////////////
+
+.api-auth-form {
+ margin-bottom: 1.5rem;
+ padding: 1rem;
+ background: $g3-castle;
+ border: 1px solid $g5-pepper;
+ border-radius: 4px;
+
+ h4 {
+ margin: 0 0 0.5rem 0;
+ }
+
+ .auth-form-description {
+ margin: 0 0 1rem 0;
+ font-size: 0.9rem;
+ color: $g9-mountain;
+ }
+
+ .auth-field {
+ margin-bottom: 1rem;
+
+ label {
+ display: block;
+ margin-bottom: 0.25rem;
+ font-weight: 600;
+ font-size: 0.9rem;
+ }
+
+ input {
+ width: 100%;
+ padding: 0.5rem;
+ border: 1px solid $g5-pepper;
+ border-radius: 3px;
+ font-family: inherit;
+ }
+ }
+
+ .auth-save {
+ margin-top: 0.5rem;
+ }
+}
+
+// Dark theme overrides - using CSS selectors (no mixin in this codebase)
+[data-theme="dark"],
+html:has(link[title="dark-theme"]:not([disabled])) {
+ .api-security-schemes {
+ border-top-color: $grey25;
+
+ .security-scheme {
+ background: $grey15;
+ border-color: $grey25;
+ }
+
+ .scheme-details {
+ dt {
+ color: $g15-platinum;
+ }
+
+ dd code {
+ background: $grey20;
+ }
+ }
+
+ .scheme-description {
+ border-top-color: $grey25;
+ }
+ }
+
+ .api-auth-form {
+ background: $grey15;
+ border-color: $grey25;
+
+ .auth-form-description {
+ color: $g15-platinum;
+ }
+
+ .auth-field input {
+ background: $grey20;
+ border-color: $grey25;
+ color: $g20-white;
+ }
+ }
+}
diff --git a/layouts/partials/api/rapidoc-mini.html b/layouts/partials/api/rapidoc-mini.html
index 2d7251077..20831f8cd 100644
--- a/layouts/partials/api/rapidoc-mini.html
+++ b/layouts/partials/api/rapidoc-mini.html
@@ -22,6 +22,12 @@
{{ end }}
+{{/* Auth input component */}}
+
+
+
{{/* Component container - TypeScript handles initialization */}}