{{ .Title }}
+ {{ with .Description }} +{{ . }}
+ {{ end }} +diff --git a/.claude/agents/influxdb3-tech-writer.md b/.claude/agents/influxdb3-tech-writer.md index 395312141..a7ce4cf09 100644 --- a/.claude/agents/influxdb3-tech-writer.md +++ b/.claude/agents/influxdb3-tech-writer.md @@ -9,6 +9,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' ## Core Expertise Areas **InfluxDB 3 Products & Architecture:** + - **Self-hosted products:** - InfluxDB 3 Core (`influxdata/influxdb/influxdb3*` source code) - open source - InfluxDB 3 Enterprise - licensed @@ -29,6 +30,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' - `content/shared/` - Shared content across products, versions, and editions **APIs & Interfaces:** + - InfluxDB 3 HTTP APIs: - v1 compatibility API (InfluxQL write/query) - v2 compatibility API (Flux) @@ -42,6 +44,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' - Telegraf integration patterns and plugin ecosystem **Documentation Standards:** + - Google Developer Documentation Style guidelines - InfluxData documentation structure and conventions (from CLAUDE.md context) - Hugo shortcodes and frontmatter requirements @@ -51,6 +54,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' ## Your Responsibilities **Content Creation & Review:** + - Write technically accurate documentation that reflects actual product behavior - Create comprehensive API documentation with proper OpenAPI specifications - Develop clear, testable code examples with proper annotations @@ -59,6 +63,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' - Identify when content should be shared vs. product-specific **Technical Accuracy:** + - Verify code examples work with current product versions - Cross-reference implementation details with source code when needed - Validate API endpoints, parameters, and response formats @@ -71,6 +76,7 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' - Cloud: Managed features, quotas, billing **Style & Standards Compliance:** + - Apply Google Developer Documentation Style consistently - Use semantic line feeds and proper Markdown formatting - Implement appropriate shortcodes for product-specific content @@ -80,30 +86,25 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' ## Content Development Process -1. **Analyze Requirements:** +1. **Analyze Requirements:** - Understand the target audience, product version(s), and documentation type - Determine if content should be shared or product-specific - -2. **Research Implementation:** +2. **Research Implementation:** - Reference source code, APIs, and existing documentation for accuracy - Identify product-specific behaviors and differences - -3. **Structure Content:** +3. **Structure Content:** - Use appropriate frontmatter, headings, and shortcodes for the content type - Apply shared content pattern when content applies to multiple products - Use product-specific conditionals when needed - -4. **Create Examples:** +4. **Create Examples:** - Develop working, testable code examples with proper annotations - Include examples for relevant products and deployment models - -5. **Apply Standards:** +5. **Apply Standards:** - Ensure compliance with style guidelines and documentation conventions - Use docs CLI tools for content creation and validation - -6. **Cross-Reference:** +6. **Cross-Reference:** - Verify consistency with related documentation and product variants - - Add alt_links for cross-product navigation + - Add alt\_links for cross-product navigation - Link related concepts and procedures ## Quality Assurance @@ -114,11 +115,12 @@ You are an expert InfluxDB 3 technical writer with deep knowledge of InfluxData' - Use placeholder conventions consistently (UPPERCASE for user-replaceable values) - Ensure proper cross-linking between related concepts and procedures - Verify shared content works correctly across all target products -- Test cross-product navigation (alt_links) +- Test cross-product navigation (alt\_links) ## Product-Specific Considerations **When documenting, consider:** + - **Core vs Enterprise:** Feature availability (clustering, HA, RBAC) - **Self-hosted vs Cloud:** Configuration methods, authentication, quotas - **Clustered vs Dedicated:** Deployment model, scaling, management diff --git a/.claude/agents/ts-component-dev.md b/.claude/agents/ts-component-dev.md index 2f202d96e..107042460 100644 --- a/.claude/agents/ts-component-dev.md +++ b/.claude/agents/ts-component-dev.md @@ -197,7 +197,7 @@ assets/js/ │ ├── api-nav.ts # API navigation behavior │ ├── api-toc.ts # Table of contents │ ├── api-tabs.ts # Tab switching -│ └── api-scalar.ts # Scalar/RapiDoc integration +│ └── api-rapidoc.ts # RapiDoc integration └── utils/ ├── dom-helpers.ts # Shared DOM utilities └── debug-helpers.js # Debugging utilities diff --git a/.claude/skills/hugo-template-dev/SKILL.md b/.claude/skills/hugo-template-dev/SKILL.md index 2c2d7336a..b463ca1e8 100644 --- a/.claude/skills/hugo-template-dev/SKILL.md +++ b/.claude/skills/hugo-template-dev/SKILL.md @@ -353,6 +353,24 @@ The **only** acceptable inline scripts are minimal initialization that MUST run Everything else belongs in `assets/js/`. +### File Organization for Components + +``` +assets/ +├── js/ +│ ├── main.js # Entry point, component registry +│ ├── components/ +│ │ ├── api-nav.ts # API navigation behavior +│ │ ├── api-toc.ts # Table of contents +│ │ ├── api-tabs.ts # Tab switching (if needed beyond CSS) +│ │ └── api-rapidoc.ts # RapiDoc integration +│ └── utils/ +│ └── dom-helpers.ts # Shared DOM utilities +└── styles/ + └── layouts/ + └── _api-layout.scss # API-specific styles +``` + ### TypeScript Component Checklist When creating a new interactive feature: diff --git a/.claude/skills/vale-rule-config/SKILL.md b/.claude/skills/vale-rule-config/SKILL.md index 0ef5c04db..332b5115c 100644 --- a/.claude/skills/vale-rule-config/SKILL.md +++ b/.claude/skills/vale-rule-config/SKILL.md @@ -102,7 +102,6 @@ level: warning ### Critical: Vale Uses regexp2, Not RE2 - Vale uses the [regexp2](https://pkg.go.dev/github.com/dlclark/regexp2) library, **not** Go's standard `regexp` package (which uses RE2). This is a common source of confusion because Vale is written in Go. ### Supported Regex Features @@ -155,11 +154,13 @@ tokens: ### tokens vs raw **tokens:** + - Automatically wrapped in word boundaries - Converted to non-capturing groups - Good for simple patterns **raw:** + - Full control over the pattern - No automatic processing - Use for complex regex @@ -333,16 +334,19 @@ print(matches2) # Should be empty ### Common Issues **Pattern not matching:** + 1. Check if you need `nonword: true` for punctuation 2. Verify scope is appropriate (`sentence`, `heading`, etc.) 3. Test with `raw` instead of `tokens` for complex patterns **Too many false positives:** + 1. Add exceptions using negative lookahead/lookbehind 2. Adjust scope to be more specific 3. Consider using substitution rule with exceptions **Pattern works in Python but not Vale:** + - Unlikely if you're using PCRE features (Vale supports them) - Check for differences in whitespace handling - Try `raw` field for exact pattern control diff --git a/.gitignore b/.gitignore index 732fc4c94..f90d27f81 100644 --- a/.gitignore +++ b/.gitignore @@ -12,9 +12,22 @@ package-lock.json # Content generation /content/influxdb*/**/api/**/*.html +/content/influxdb*/**/api/**/*.md !api-docs/**/.config.yml /api-docs/redoc-static.html* /api-docs/_build/ + +# API documentation generation (generated by api-docs/scripts/) +/content/influxdb/*/api/** +/content/influxdb3/*/api/** +/content/influxdb3/*/reference/api/** +/content/enterprise_influxdb/*/api/** +/static/openapi +/data/article_data + +# Exception: hand-crafted API conceptual pages (not generated) +!/content/influxdb3/*/api/administration/ +!/content/influxdb3/*/api/administration/_index.md /helper-scripts/output/* /telegraf-build !telegraf-build/templates @@ -39,6 +52,8 @@ tmp # TypeScript build output **/dist/ +# Exception: include compiled API doc scripts for easier use +!api-docs/scripts/dist/ **/dist-lambda/ # User context files for AI assistant tools diff --git a/AGENTS.md b/AGENTS.md index bd27e9efa..9fc79161b 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,22 +1,36 @@ # InfluxData Documentation (docs-v2) -> **Shared project guidelines for all AI assistants** +> **For general AI assistants (Claude, ChatGPT, Gemini, etc.)** +> +> This guide provides comprehensive instructions for AI assistants helping with the InfluxData documentation repository. It focuses on content creation, writing workflows, and style guidelines. > > **Other instruction resources**: -> - [.github/copilot-instructions.md](.github/copilot-instructions.md) - GitHub Copilot (CLI tools, workflows, repo structure) -> - [CLAUDE.md](CLAUDE.md) - Claude with MCP (pointer file) +> +> - [.github/copilot-instructions.md](.github/copilot-instructions.md) - For GitHub Copilot (focused on coding and automation) +> - [CLAUDE.md](CLAUDE.md) - For Claude with MCP (minimal pointer) > - [.claude/](.claude/) - Claude MCP configuration (commands, agents, skills) > - [.github/instructions/](.github/instructions/) - File pattern-specific instructions -## Commands +## Project Overview -| Task | Command | Notes | -|------|---------|-------| -| Install | `CYPRESS_INSTALL_BINARY=0 yarn install` | ~4s | -| Build | `npx hugo --quiet` | ~75s — **NEVER CANCEL** | -| Dev server | `npx hugo server` | ~92s, port 1313 | -| Test code blocks | `yarn test:codeblocks:all` | 15-45m — **NEVER CANCEL** | -| Lint | `yarn lint` | ~1m | +This repository powers [docs.influxdata.com](https://docs.influxdata.com), a Hugo-based static documentation site covering InfluxDB 3, InfluxDB v2/v1, Telegraf, and related products. + +**Key Characteristics:** + +- **Scale**: 5,359+ pages +- **Build time**: \~75 seconds (NEVER cancel Hugo builds) +- **Tech stack**: Hugo, Node.js, Docker, Vale, Pytest, Cypress +- **Test time**: 15-45 minutes for full code block tests + +## Quick Commands + +| Task | Command | Time | +| -------------------- | --------------------------------------- | ------ | +| Install dependencies | `CYPRESS_INSTALL_BINARY=0 yarn install` | \~4s | +| Build site | `npx hugo --quiet` | \~75s | +| Dev server | `npx hugo server` | \~92s | +| Test code blocks | `yarn test:codeblocks:all` | 15-45m | +| Lint | `yarn lint` | \~1m | ## Repository Structure @@ -31,7 +45,7 @@ docs-v2/ │ └── example.md # Shortcode testing playground ├── layouts/ # Hugo templates and shortcodes ├── assets/ # JS, CSS, TypeScript -├── api-docs/ # InfluxDB OpenAPI specifications, API reference documentation generation scripts +├── api-docs/ # OpenAPI specifications ├── data/ # YAML/JSON data files ├── public/ # Build output (gitignored, ~529MB) └── .github/ @@ -40,18 +54,19 @@ docs-v2/ **Content Paths**: See [copilot-instructions.md](.github/copilot-instructions.md#content-organization) -## Documentation MCP Server - -A hosted MCP server provides semantic search over all InfluxDB documentation. -Use it to verify technical accuracy, check API syntax, and find related docs. - -See the [InfluxDB documentation MCP server guide](https://docs.influxdata.com/influxdb3/core/admin/mcp-server/) for setup instructions. - ## Common Workflows -### Creating/Editing Content +### Editing a page in your browser + +1. Navigate to the desired page on [docs.influxdata.com](https://docs.influxdata.com) +2. Click the "Edit this page" link at the bottom +3. Make changes in the GitHub web editor +4. Commit changes via a pull request + +### Creating/Editing Content Manually **Frontmatter** (page metadata): + ```yaml title: Page Title # Required - becomes h1 description: Brief desc # Required - for SEO @@ -63,15 +78,18 @@ weight: 1 # Required - sort order ``` **Shared Content** (avoid duplication): + ```yaml source: /shared/path/to/content.md ``` Shared content files (`/shared/path/to/content.md`): + - Don't store frontmatter - Can use `{{% show-in %}}`, `{{% hide-in %}}`, and the `version` keyword (`/influxdb3/version/content.md`) **Common Shortcodes**: + - Callouts: `> [!Note]`, `> [!Warning]`, `> [!Important]`, `> [!Tip]` - Tabs: `{{< tabs-wrapper >}}` + `{{% tabs %}}` + `{{% tab-content %}}` - Required: `{{< req >}}` or `{{< req type="key" >}}` @@ -82,6 +100,7 @@ Shared content files (`/shared/path/to/content.md`): ### Testing Changes **Always test before committing**: + ```bash # Verify server renders (check 200 status) curl -s -o /dev/null -w "%{http_code}" http://localhost:1313/influxdb3/core/ @@ -95,83 +114,140 @@ yarn test:links content/influxdb3/core/**/*.md **📖 Complete Reference**: [DOCS-TESTING.md](DOCS-TESTING.md) +### Committing Changes -## Constraints +**Commit Message Format**: -- **NEVER cancel** Hugo builds (~75s) or test runs (15-45m) — the site has 5,359+ pages -- Set timeouts: Hugo 180s+, tests 30m+ -- Use `python` not `py` for code block language identifiers (pytest won't collect `py` blocks) -- Shared content files (`content/shared/`) have no frontmatter — the consuming page provides it -- Product names and versions come from `data/products.yml` (single source of truth) -- Commit format: `type(scope): description` — see [DOCS-CONTRIBUTING.md](DOCS-CONTRIBUTING.md#commit-guidelines) -- Network-restricted environments: Cypress (`CYPRESS_INSTALL_BINARY=0`), Docker builds, and Alpine packages may fail +``` +type(scope): description -## Style Rules +Examples: +- fix(enterprise): correct Docker environment variable +- feat(influxdb3): add new plugin documentation +- docs(core): update configuration examples +``` -Follows [Google Developer Documentation Style Guide](https://developers.google.com/style) with these project-specific additions: +**Types**: `fix`, `feat`, `style`, `refactor`, `test`, `chore` -- **Semantic line feeds** — one sentence per line (better diffs) -- **No h1 in content** — `title` frontmatter auto-generates h1 -- Active voice, present tense, second person -- Long options in CLI examples (`--output` not `-o`) -- Code blocks within 80 characters +**Scopes**: `enterprise`, `influxdb3`, `core`, `cloud`, `telegraf`, etc. -## Content Structure +**Pre-commit hooks** run automatically (Vale, Prettier, tests). Skip with: -**Required frontmatter**: `title`, `description`, `menu`, `weight` -— see [DOCS-FRONTMATTER.md](DOCS-FRONTMATTER.md) +```bash +git commit -m "message" --no-verify +``` -**Shared content**: `source: /shared/path/to/content.md` -— shared files use `{{% show-in %}}` / `{{% hide-in %}}` for product-specific content +**📖 Complete Reference**: [DOCS-CONTRIBUTING.md](DOCS-CONTRIBUTING.md#commit-guidelines) -**Shortcodes**: Callouts use `> [!Note]` / `> [!Warning]` syntax -— see [DOCS-SHORTCODES.md](DOCS-SHORTCODES.md) and [content/example.md](content/example.md) +## Key Patterns -## Product Content Paths +### Content Organization -Canonical paths from `data/products.yml`: +- **Product versions**: Managed in `/data/products.yml` +- **Semantic line feeds**: One sentence per line for better diffs +- **Heading hierarchy**: Use h2-h6 only (h1 auto-generated from frontmatter) +- **Image naming**: `project/version-context-description.png` -| Product | Content Path | -|---------|-------------| -| InfluxDB 3 Core | `content/influxdb3/core/` | -| InfluxDB 3 Enterprise | `content/influxdb3/enterprise/` | -| InfluxDB 3 Explorer | `content/influxdb3/explorer/` | -| InfluxDB Cloud Serverless | `content/influxdb3/cloud-serverless/` | -| InfluxDB Cloud Dedicated | `content/influxdb3/cloud-dedicated/` | -| InfluxDB Clustered | `content/influxdb3/clustered/` | -| InfluxDB OSS v2 | `content/influxdb/v2/` | -| InfluxDB OSS v1 | `content/influxdb/v1/` | -| InfluxDB Cloud (TSM) | `content/influxdb/cloud/` | -| InfluxDB Enterprise v1 | `content/enterprise_influxdb/` | -| Telegraf | `content/telegraf/` | -| Chronograf | `content/chronograf/` | -| Kapacitor | `content/kapacitor/` | -| Flux | `content/flux/` | -| Shared content | `content/shared/` | +### Code Examples -## Doc Review Pipeline +**Testable code blocks** (pytest): -Automated PR review for documentation changes. -See [.github/LABEL_GUIDE.md](.github/LABEL_GUIDE.md) for the label taxonomy. +```python +print("Hello, world!") +``` -| Resource | Path | -|----------|------| -| Label guide | [.github/LABEL_GUIDE.md](.github/LABEL_GUIDE.md) | -| Triage agent | [.claude/agents/doc-triage-agent.md](.claude/agents/doc-triage-agent.md) | -| Content review instructions | [.github/instructions/content-review.instructions.md](.github/instructions/content-review.instructions.md) | -| Review agent (local) | [.claude/agents/doc-review-agent.md](.claude/agents/doc-review-agent.md) | -| Auto-label workflow | [.github/workflows/auto-label.yml](.github/workflows/auto-label.yml) | -| Doc review workflow | [.github/workflows/doc-review.yml](.github/workflows/doc-review.yml) | + -## Reference +``` +Hello, world! +``` -| Document | Purpose | -|----------|---------| -| [DOCS-CONTRIBUTING.md](DOCS-CONTRIBUTING.md) | Style guidelines, commit format, contribution workflow | -| [DOCS-TESTING.md](DOCS-TESTING.md) | Code block testing, link validation, Vale linting | -| [DOCS-SHORTCODES.md](DOCS-SHORTCODES.md) | Complete shortcode reference | -| [DOCS-FRONTMATTER.md](DOCS-FRONTMATTER.md) | Complete frontmatter field reference | -| [api-docs/README.md](api-docs/README.md) | API documentation workflow | -| [content/example.md](content/example.md) | Live shortcode examples | -| [.github/copilot-instructions.md](.github/copilot-instructions.md) | CLI tools, repo structure, workflows | -| [.github/LABEL_GUIDE.md](.github/LABEL_GUIDE.md) | Label taxonomy and review pipeline | +**Language identifiers**: Use `python` not `py`, `bash` not `sh` (for pytest collection) + +### API Documentation + +- **Location**: `/api-docs/` directory +- **Format**: OpenAPI 3.0 YAML +- **Generation**: Uses Redoc + custom processing +- **📖 Workflow**: [api-docs/README.md](api-docs/README.md) + +### JavaScript/TypeScript + +- **Entry point**: `assets/js/main.js` +- **Pattern**: Component-based with `data-component` attributes +- **Debugging**: Source maps or debug helpers available +- **📖 Details**: [DOCS-CONTRIBUTING.md](DOCS-CONTRIBUTING.md#javascript-in-the-documentation-ui) + +## Important Constraints + +### Performance + +- **NEVER cancel Hugo builds** - they take \~75s normally +- **NEVER cancel test runs** - code block tests take 15-45 minutes +- **Set timeouts**: Hugo (180s+), tests (30+ minutes) + +### Style Guidelines + +- Use Google Developer Documentation style +- Active voice, present tense, second person for instructions +- No emojis unless explicitly requested +- Use long options in CLI examples (`--option` vs `-o`) +- Format code blocks within 80 characters + +### Network Restrictions + +Some operations may fail in restricted environments: + +- Docker builds requiring external repos +- `docker compose up local-dev` (Alpine packages) +- Cypress installation (use `CYPRESS_INSTALL_BINARY=0`) + +## Documentation References + +| Document | Purpose | +| ------------------------------------------------------------------ | ------------------------------------------------ | +| [DOCS-CONTRIBUTING.md](DOCS-CONTRIBUTING.md) | Contribution workflow, style guidelines | +| [DOCS-TESTING.md](DOCS-TESTING.md) | Testing procedures (code blocks, links, linting) | +| [DOCS-SHORTCODES.md](DOCS-SHORTCODES.md) | Complete shortcode reference | +| [DOCS-FRONTMATTER.md](DOCS-FRONTMATTER.md) | Complete frontmatter field reference | +| [.github/copilot-instructions.md](.github/copilot-instructions.md) | Primary AI assistant instructions | +| [api-docs/README.md](api-docs/README.md) | API documentation workflow | +| [content/example.md](content/example.md) | Live shortcode examples for testing | + +## Specialized Topics + +### Working with Specific Products + +| Product | Content Path | Special Notes | +| ------------------------ | ----------------------------------------------------------------------------- | --------------------------------------- | +| InfluxDB 3 Core | `/content/influxdb3/core/` | Latest architecture | +| InfluxDB 3 Enterprise | `/content/influxdb3/enterprise/` | Core + licensed features, clustered | +| InfluxDB Cloud Dedicated | `/content/influxdb3/cloud-dedicated/`, `/content/influxdb3/cloud-serverless/` | Managed and distributed | +| InfluxDB Clustered | `/content/influxdb3/clustered/` | Self-managed and distributed | +| InfluxDB Cloud | `/content/influxdb/cloud/` | Legacy but active | +| InfluxDB v2 | `/content/influxdb/v2/` | Legacy but active | +| InfluxDB Enterprise v1 | `/content/enterprise_influxdb/v1/` | Legacy but active enterprise, clustered | + +### Advanced Tasks + +- **Vale configuration**: `.ci/vale/styles/` for custom rules +- **Link checking**: Uses custom `link-checker` binary +- **Docker testing**: `compose.yaml` defines test services +- **Lefthook**: Git hooks configuration in `lefthook.yml` + +## Troubleshooting + +| Issue | Solution | +| ------------------------ | ------------------------------------------------------ | +| Pytest collected 0 items | Use `python` not `py` for code block language | +| Hugo build errors | Check `/config/_default/` configuration | +| Link validation slow | Test specific files: `yarn test:links content/file.md` | +| Vale errors | Check `.ci/vale/styles/config/vocabularies` | + +## Critical Reminders + +1. **Be a critical thinking partner** - Challenge assumptions, identify issues +2. **Test before committing** - Run relevant tests locally +3. **Reference, don't duplicate** - Link to detailed docs instead of copying +4. **Respect build times** - Don't cancel long-running operations +5. **Follow conventions** - Use established patterns for consistency diff --git a/DOCS-CONTRIBUTING.md b/DOCS-CONTRIBUTING.md index 7f0971553..5fcd6db1a 100644 --- a/DOCS-CONTRIBUTING.md +++ b/DOCS-CONTRIBUTING.md @@ -1,6 +1,7 @@ # Contributing to InfluxData Documentation + ## Quick Start Ready to contribute? @@ -14,7 +15,7 @@ Ready to contribute? For detailed setup and reference information, see the sections below. ---- +*** ## Legal & Getting Started @@ -27,18 +28,19 @@ What constitutes a "substantial" change is at the discretion of InfluxData docum [Sign the InfluxData CLA](https://www.influxdata.com/legal/cla/) -_**Note:** Typo and broken link fixes are greatly appreciated and do not require signing the CLA._ +***Note:** Typo and broken link fixes are greatly appreciated and do not require signing the CLA.* -_If you're new to contributing or you're looking for an easy update, see [`docs-v2` good-first-issues](https://github.com/influxdata/docs-v2/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue)._ +*If you're new to contributing or you're looking for an easy update, see [`docs-v2` good-first-issues](https://github.com/influxdata/docs-v2/issues?q=is%3Aissue+is%3Aopen+label%3Agood-first-issue).* ### Fork and clone InfluxData Documentation Repository [Fork this repository](https://help.github.com/articles/fork-a-repo/) and [clone it](https://help.github.com/articles/cloning-a-repository/) to your local machine. ---- +*** + ## Development Environment Setup ### Prerequisites @@ -76,9 +78,9 @@ dev dependencies used in pre-commit hooks for linting, syntax-checking, and test Dev dependencies include: - [Lefthook](https://github.com/evilmartians/lefthook): configures and -manages git pre-commit and pre-push hooks for linting and testing Markdown content. + manages git pre-commit and pre-push hooks for linting and testing Markdown content. - [prettier](https://prettier.io/docs/en/): formats code, including Markdown, according to style rules for consistency -- [Cypress]: e2e testing for UI elements and URLs in content +- \[Cypress]: e2e testing for UI elements and URLs in content ### Install Vale (style linting) @@ -114,11 +116,11 @@ docs-v2 contains a `./.vscode/settings.json` that configures the following exten - Vale: shows linter errors and suggestions in the editor. - YAML Schemas: validates frontmatter attributes. ---- +*** -## Making Changes +## Making Changes ### Style Guidelines @@ -130,7 +132,7 @@ Content follows Google Developer Documentation Style Guide and YouTube API docum Most docs-v2 documentation content uses [Markdown](https://en.wikipedia.org/wiki/Markdown). -_Some parts of the documentation, such as `./api-docs`, contain Markdown within YAML and rely on additional tooling._ +*Some parts of the documentation, such as `./api-docs`, contain Markdown within YAML and rely on additional tooling.* #### Semantic line feeds @@ -270,6 +272,7 @@ Documentation audit tools should: 4. Support both single-line and multi-line exclusion lists + ### Common Shortcodes Reference #### Callouts (notes and warnings) @@ -327,7 +330,7 @@ For the complete shortcodes reference with all available shortcodes and usage ex Test shortcodes with working examples in **[content/example.md](content/example.md)**. ---- +*** ### InfluxDB API documentation @@ -338,11 +341,10 @@ InfluxDB API documentation when documentation is deployed. For more information about editing and generating InfluxDB API documentation, see the [API Documentation README](https://github.com/influxdata/docs-v2/tree/master/api-docs#readme). ---- +*** ## Testing & Quality Assurance - Pre-commit hooks run automatically when you commit changes, testing your staged files with Vale, Prettier, Cypress, and Pytest. To skip hooks if needed: ```sh @@ -364,13 +366,14 @@ yarn test:links content/influxdb3/core/**/*.md For comprehensive testing information, including code block testing, link validation, style linting, and advanced testing procedures, see **[DOCS-TESTING.md](DOCS-TESTING.md)**. - ---- +*** + ## Submission Process + ### Commit Guidelines When creating commits, follow these guidelines: @@ -383,6 +386,7 @@ When creating commits, follow these guidelines: - For multiple issues, use comma separation: `closes influxdata/DAR#517, closes influxdata/DAR#518` **Examples:** + ``` fix(enterprise): correct Docker environment variable name for license email fix(influxdb3): correct Docker environment variable and compose examples for monolith @@ -394,7 +398,7 @@ chore(ci): update Vale configuration Push your changes up to your forked repository, then [create a new pull request](https://help.github.com/articles/creating-a-pull-request/). ---- +*** ## Reference Documentation @@ -404,6 +408,7 @@ For detailed reference documentation, see: - **[DOCS-SHORTCODES.md](DOCS-SHORTCODES.md)** - Complete shortcodes reference with usage examples for all available shortcodes + ### Advanced Configuration #### Vale style linting configuration @@ -434,6 +439,7 @@ To add accepted/rejected terms for specific products, configure a style for the To learn more about configuration and rules, see [Vale configuration](https://vale.sh/docs/topics/config). + #### JavaScript in the documentation UI The InfluxData documentation UI uses TypeScript and JavaScript with ES6+ syntax and @@ -450,13 +456,14 @@ If you're adding UI functionality that requires JavaScript, follow these steps: ```html
- ``` + ``` 2. Following the component pattern, create a single-purpose JavaScript module (`assets/js/components/my-component.js`) that exports a single function that receives the component element and initializes it. + 3. In `assets/js/main.js`, import the module and register the component to ensure - the component is initialized on page load. + the component is initialized on page load. ##### Debugging JavaScript @@ -470,7 +477,7 @@ To debug JavaScript code used in the InfluxData documentation UI, choose one of 1. In VS Code, select Run > Start Debugging. 2. Select the "Debug Docs (source maps)" configuration. 3. Click the play button to start the debugger. -5. Set breakpoints in the JavaScript source files--files in the +4. Set breakpoints in the JavaScript source files--files in the `assets/js/ns-hugo-imp:` namespace-- in the VS Code editor or in the Chrome Developer Tools Sources panel: @@ -484,8 +491,9 @@ To debug JavaScript code used in the InfluxData documentation UI, choose one of 1. In your JavaScript module, import debug helpers from `assets/js/utils/debug-helpers.js`. These helpers provide breakpoints and console logging as a workaround or alternative for using source maps and the Chrome DevTools debugger. + 2. Insert debug statements by calling the helper functions in your code--for example: - + ```js import { debugLog, debugBreak, debugInspect } from './utils/debug-helpers.js'; @@ -512,4 +520,4 @@ Your system uses the configuration in `launch.json` to launch the site in Chrome and attach the debugger to the Developer Tools console. Make sure to remove the debug statements before merging your changes. -The debug helpers are designed to be used in development and should not be used in production. \ No newline at end of file +The debug helpers are designed to be used in development and should not be used in production. diff --git a/DOCS-TESTING.md b/DOCS-TESTING.md index 17506fc04..95bf9ba94 100644 --- a/DOCS-TESTING.md +++ b/DOCS-TESTING.md @@ -11,13 +11,13 @@ This guide covers all testing procedures for the InfluxData documentation, inclu ## Test Types Overview -| Test Type | Purpose | Command | -| ----------------------- | ----------------------------------- | ---------------------------- | -| **Code blocks** | Validate shell/Python code examples | `yarn test:codeblocks:all` | -| **Link validation** | Check internal/external links | `yarn test:links` | -| **Style linting** | Enforce writing standards | `.ci/vale/vale.sh` | -| **Markdown generation** | Generate LLM-friendly Markdown | `yarn build:md` | -| **E2E tests** | UI and functionality testing | `yarn test:e2e` | +| Test Type | Purpose | Command | +| ----------------------- | ----------------------------------- | -------------------------- | +| **Code blocks** | Validate shell/Python code examples | `yarn test:codeblocks:all` | +| **Link validation** | Check internal/external links | `yarn test:links` | +| **Style linting** | Enforce writing standards | `.ci/vale/vale.sh` | +| **Markdown generation** | Generate LLM-friendly Markdown | `yarn build:md` | +| **E2E tests** | UI and functionality testing | `yarn test:e2e` | ## Code Block Testing diff --git a/PLAN.md b/PLAN.md new file mode 100644 index 000000000..fca5b5330 --- /dev/null +++ b/PLAN.md @@ -0,0 +1,58 @@ +--- +branch: feat-api-uplift +repo: docs-v2 +created: 2025-12-02T15:28:32Z +status: in-progress +--- + +# feat-api-uplift + +## Overview + +Replace the current API reference documentation implementation (RapiDoc web components) with Hugo-native templates. + +## Phase 1: Core Infrastructure (completed) + +### Build process + +- `yarn build:api` parses OpenAPI specs into Hugo data +- Generates Hugo pages with frontmatter for Algolia search integration +- Static JSON chunks for faster page loads + +### OpenAPI tag cleanup + +- Removed unused tags from OpenAPI specs +- Updated tags to be consistent and descriptive + +### Hugo-native POC + +- Implemented Hugo-native templates in `layouts/partials/api/hugo-native/` +- Tested with InfluxDB 3 Core product + +## Phase 2: Migration to Hugo-Native (in progress) + +**Plan**: @docs/plans/2026-02-13-hugo-native-api-migration.md + +### Task Order + +1. ✅ **Promote Hugo-native templates** - Move from POC to production +2. ✅ **Remove RapiDoc templates** - Delete templates and partials +3. ✅ **Remove RapiDoc JavaScript** - Delete components +4. ✅ **Remove operation pages** - Delete individual operation page generation +5. ✅ **Update Cypress tests** - Simplify tests for static HTML +6. ✅ **Clean up styles** - Remove RapiDoc CSS and dead auth modal code +7. ✅ **Fix generation script cleanup** - Added `--clean` (default) and `--dry-run` flags +8. ✅ **Add inline code samples** - curl examples and Ask AI links per operation +9. ✅ **Refine API styling** - Theme-aware code blocks, font normalization, layout width, TOC border +10. **Apply Cache Data tag split** - Enterprise spec update (planned) +11. **Migrate remaining products** - Apply to all InfluxDB products (planned) + +## Related Files + +- Branch: `feat-api-uplift` +- Plan: `plans/2026-02-13-hugo-native-api-migration.md` + +## Notes + +- Use Chrome devtools and Cypress to debug +- No individual operation pages - operations accessed only via tag pages diff --git a/PLATFORM_REFERENCE.md b/PLATFORM_REFERENCE.md index c4e5f5d67..374eb6be9 100644 --- a/PLATFORM_REFERENCE.md +++ b/PLATFORM_REFERENCE.md @@ -1,65 +1,79 @@ + Use the following information to help determine which InfluxDB version and product the user is asking about: InfluxDB OSS v2: - - Documentation: https://docs.influxdata.com/influxdb/v2/ - - Query languages: InfluxQL and Flux - - Clients: Telegraf, influx CLI, v1/v2 client libraries + +- Documentation:No operations on this page.
'; + } + + let html = ' element but we override the default code background
+ // to prevent inconsistent "progress bar" appearance from varying text lengths
+ .api-path {
+ font-family: $code;
+ font-size: 0.9rem;
+ color: $article-heading;
+ word-break: break-all;
+ flex: 1;
+ min-width: 0; // Allow text to shrink and wrap
+ background: none; // Override default code background
+ padding: 0; // Remove default code padding
+ }
+
+ // Operation summary text
+ .api-operation-summary {
+ font-size: 0.875rem;
+ color: rgba($article-text, 0.8);
+ flex-shrink: 0;
+ }
+}
+
+// Responsive: Stack operation cards vertically on small screens
+@include media(small) {
+ .api-operation-card {
+ flex-direction: column;
+ align-items: stretch;
+ gap: 0.5rem;
+
+ .api-method {
+ align-self: flex-start;
+ margin-top: 0;
+ }
+
+ .api-path {
+ font-size: 0.85rem;
+ line-height: 1.4;
+ }
+
+ .api-operation-summary {
+ font-size: 0.8rem;
+ line-height: 1.5;
+ }
+ }
+}
+
+// Overview/Description section
+.api-description {
+ margin: 2rem 0;
+ color: $article-text !important; // Override any inherited black color
+
+ h2 {
+ margin-bottom: 1rem;
+ }
+
+ // Ensure description text is visible and readable
+ p, ul, ol, pre, code {
+ color: $article-text !important;
+ opacity: 1;
+ }
+
+ // Also ensure direct text nodes use correct color
+ & > * {
+ color: $article-text !important;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////// API Navigation in Sidebar ///////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// API navigation wrapper - controls visibility
+// Hidden by default, revealed via JS (localStorage) or on API pages
+.api-nav-wrapper {
+ display: none; // Hidden by default
+
+ &.is-revealed {
+ display: block; // Revealed via JS
+ }
+
+ // Always show on API pages (server-rendered with .api-reference class)
+ .api-reference & {
+ display: block;
+ }
+}
+
+// API navigation section added to the existing Hugo sidebar
+.api-nav {
+ margin-top: 2rem;
+ padding-top: 1rem;
+ border-top: 1px solid $nav-border;
+
+ &-header {
+ font-size: 0.85rem;
+ font-weight: $bold;
+ text-transform: uppercase;
+ letter-spacing: 0.06rem;
+ color: rgba($article-heading, 0.6);
+ margin: 0 0 1rem;
+ padding-left: 1.5rem;
+ }
+
+ // API nav groups (collapsible sections)
+ &-group {
+ margin-bottom: 0.5rem;
+
+ &-header {
+ display: flex;
+ align-items: center;
+ padding: 0.5rem 0 0.5rem 1.5rem;
+ font-weight: $medium;
+ color: $nav-category;
+ cursor: pointer;
+ transition: color 0.2s;
+ // Button reset for dark mode compatibility
+ background: none;
+ border: none;
+ width: 100%;
+ text-align: left;
+ font-size: 1.2rem; // Match sidebar .nav-category > a (19.2px)
+ font-family: inherit;
+ text-decoration: none; // For anchor version
+
+ &:hover {
+ color: $nav-category-hover;
+ }
+
+ &.is-active {
+ color: $nav-active;
+ }
+
+ // Collapse/expand indicator (for button headers)
+ &::before {
+ content: "";
+ display: inline-block;
+ width: 0;
+ height: 0;
+ margin-right: 0.5rem;
+ border-left: 5px solid $nav-border;
+ border-top: 4px solid transparent;
+ border-bottom: 4px solid transparent;
+ transition: transform 0.2s;
+ flex-shrink: 0;
+ }
+
+ &.is-open::before {
+ transform: rotate(90deg);
+ }
+ }
+
+ // For anchor headers, keep the ::before arrow (same as button)
+ // No special handling needed - anchor headers look the same as button headers
+ a#{&}-header {
+ // Same styling as button, arrow works via ::before
+ }
+
+ &-items {
+ list-style: none;
+ padding-left: 2.5rem;
+ margin: 0;
+ max-height: 0;
+ overflow: hidden;
+ transition: max-height 0.3s ease-out;
+ background: $body-bg; // Match sidebar background
+
+ &.is-open {
+ max-height: 2000px; // Large enough to show all operations
+ }
+ }
+ }
+
+ // Individual API nav items
+ &-item {
+ margin: 0.25rem 0;
+ position: relative;
+
+ a {
+ display: flex;
+ align-items: center;
+ padding: 0.35rem 0;
+ color: $nav-item;
+ text-decoration: none;
+ font-size: 0.95rem;
+ transition: color 0.2s;
+
+ &:hover {
+ color: $nav-item-hover;
+ }
+ }
+
+ &.is-active a {
+ color: $nav-active;
+ font-weight: $medium;
+ }
+
+ // HTTP method badge (legacy class)
+ .method-badge {
+ display: inline-block;
+ font-size: 0.65rem;
+ font-weight: $bold;
+ text-transform: uppercase;
+ padding: 0.15rem 0.35rem;
+ margin-right: 0.5rem;
+ border-radius: 3px;
+ min-width: 2.5rem;
+ text-align: center;
+
+ &.get { background-color: $gr-rainforest; color: #fff; }
+ &.post { background-color: $b-ocean; color: #fff; }
+ &.put { background-color: $br-galaxy; color: #fff; }
+ &.patch { background-color: $y-thunder; color: rgba($g5-pepper, 0.75); }
+ &.delete { background-color: $r-curacao; color: #fff; }
+ }
+
+ // Tag items that link to tag pages
+ &.api-nav-tag {
+ > a {
+ font-weight: $medium;
+ }
+
+ // Nested operations list under tag
+ .api-nav-operations {
+ list-style: none;
+ margin: 0.25rem 0 0.5rem;
+ padding-left: 0.75rem;
+
+ .api-nav-operation {
+ margin: 0.15rem 0;
+
+ a {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ font-size: 0.85rem;
+ padding: 0.25rem 0;
+ }
+ }
+ }
+ }
+
+ // Operation items with method badges
+ &.api-nav-operation,
+ .api-nav-operation {
+ .api-method {
+ display: inline-block;
+ font-size: 0.55rem;
+ font-weight: $bold;
+ text-transform: uppercase;
+ padding: 0.1rem 0.25rem;
+ border-radius: 3px;
+ min-width: 2rem;
+ text-align: center;
+ flex-shrink: 0;
+
+ &--get { background-color: $b-pool; color: #fff; } // #00A3FF - bright brand blue
+ &--post { background-color: $gr-rainforest; color: #fff; } // #34BB55 - bright brand green
+ &--put { background-color: $y-pineapple; color: #fff; } // #FFB94A - bright yellow (distinct from red)
+ &--patch { background-color: $br-new-purple; color: #fff; } // #9b2aff - distinctive brand purple
+ &--delete { background-color: $r-curacao; color: #fff; } // #F95F53 - bright brand red
+ }
+
+ .api-path {
+ font-family: $code;
+ font-size: 0.85rem;
+ word-break: break-all;
+ color: inherit;
+ }
+ }
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// API Header with Actions ////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// Header row with title and download button
+.article--header-row {
+ display: flex;
+ justify-content: space-between;
+ align-items: flex-start;
+ gap: 1rem;
+ flex-wrap: wrap;
+}
+
+.article--header-text {
+ flex: 1 1 100%; // Take full width, allowing download button to wrap
+ min-width: 0;
+}
+
+// Summary paragraph in header - ensure full width
+.article--summary {
+ max-width: none;
+ width: 100%;
+}
+
+// Download OpenAPI spec button
+.api-spec-actions {
+ flex-shrink: 0;
+}
+
+.api-spec-download {
+ display: inline-flex;
+ align-items: center;
+ gap: 0.5rem;
+ padding: 0.5rem 1rem;
+ background-color: $g20-white;
+ color: $article-text;
+ text-decoration: none;
+ border-radius: $radius;
+ font-size: 0.875rem;
+ font-weight: $medium;
+ transition: background-color 0.2s, color 0.2s;
+ border: 1px solid $nav-border;
+ white-space: nowrap;
+
+ &:hover {
+ background-color: $r-curacao;
+ color: $g20-white;
+ border-color: $r-curacao;
+ }
+
+ svg {
+ flex-shrink: 0;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////// API Tabs ////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// API-specific tab wrapper (uses api-tabs-wrapper to avoid conflict with
+// tabbed-content.js which handles .tabs-wrapper elements)
+.api-tabs-wrapper {
+ margin: 1.5rem 0 1rem;
+}
+
+// API tab navigation bar
+.api-tabs-nav {
+ display: flex;
+ flex-wrap: wrap;
+ gap: 2px;
+
+ a {
+ flex-grow: 1;
+ position: relative;
+ font-size: 1rem;
+ font-weight: $medium;
+ padding: 0.65rem 1.25rem;
+ display: inline-block;
+ white-space: nowrap;
+ text-align: center;
+ color: $article-tab-text !important;
+ border-radius: $radius;
+ background-color: $article-tab-bg;
+ text-decoration: none;
+ transition: background-color 0.2s, color 0.2s;
+ z-index: 1;
+
+ &::after {
+ content: '';
+ position: absolute;
+ display: block;
+ top: 0;
+ right: 0;
+ width: 100%;
+ height: 100%;
+ border-radius: $radius;
+ @include gradient($article-btn-gradient);
+ opacity: 0;
+ transition: opacity 0.2s;
+ z-index: -1;
+ }
+
+ &:hover {
+ color: $article-tab-active-text !important;
+ &::after {
+ opacity: 1;
+ }
+ }
+
+ &.is-active {
+ color: $article-tab-active-text !important;
+ &::after {
+ opacity: 1;
+ @include gradient($article-btn-gradient);
+ }
+ }
+ }
+}
+
+// Tab panels container
+.api-tab-panels {
+ // Tab content visibility (follows existing pattern)
+ .tab-content:not(:first-of-type) {
+ display: none;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////// Authentication Tab Content //////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+.api-auth-content {
+ max-width: 800px;
+}
+
+.api-auth-card {
+ background: $article-bg;
+ border: 1px solid $nav-border;
+ border-radius: $radius;
+ padding: 1.5rem;
+ margin-bottom: 1.5rem;
+
+ h3 {
+ margin-top: 0;
+ margin-bottom: 0.5rem;
+ }
+
+ h4 {
+ margin-top: 1rem;
+ margin-bottom: 0.5rem;
+ font-size: 0.9rem;
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+ color: rgba($article-text, 0.6);
+ }
+
+ pre {
+ margin: 0.5rem 0;
+ padding: 1rem;
+ background: $article-code-bg;
+ border-radius: $radius;
+ overflow-x: auto;
+ }
+
+ code {
+ font-family: $code;
+ font-size: 0.875rem;
+ }
+}
+
+.api-auth-badge .badge {
+ display: inline-block;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.75rem;
+ font-weight: $bold;
+ text-transform: uppercase;
+ border-radius: $radius;
+
+ &.recommended {
+ background: $gr-rainforest;
+ color: $g20-white;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+//////////////////////////// Server Tab Content ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+.api-server-panel {
+ max-width: 600px;
+
+ h2 {
+ margin-top: 0;
+ }
+}
+
+.server-url-config {
+ display: flex;
+ gap: 0.5rem;
+ align-items: flex-end;
+ margin: 1rem 0;
+ flex-wrap: wrap;
+
+ label {
+ width: 100%;
+ font-weight: $medium;
+ margin-bottom: 0.25rem;
+ }
+
+ input {
+ flex: 1;
+ min-width: 200px;
+ padding: 0.5rem;
+ border: 1px solid $nav-border;
+ border-radius: $radius;
+ font-family: $code;
+ background: $article-bg;
+ color: $article-text;
+ }
+
+ button {
+ padding: 0.5rem 1rem;
+ background: $r-curacao;
+ color: $g20-white;
+ border: none;
+ border-radius: $radius;
+ cursor: pointer;
+ font-weight: $medium;
+
+ &:hover {
+ background: darken($r-curacao, 10%);
+ }
+ }
+}
+
+.server-info {
+ margin-top: 1.5rem;
+
+ ul {
+ list-style: disc;
+ padding-left: 1.5rem;
+ }
+
+ li {
+ margin: 0.5rem 0;
+ }
+
+ code {
+ background: $article-code-bg;
+ padding: 0.2rem 0.4rem;
+ border-radius: 3px;
+ font-family: $code;
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////// MEDIA QUERIES ////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// Tablet: Hide TOC, keep sidebar
+@include media(large) {
+ .content-wrapper.api-content {
+ flex-direction: column;
+ width: 75%; // Reset to default when TOC is hidden
+ }
+
+ .api-toc {
+ display: none;
+ }
+
+ .api-main {
+ padding-right: 0;
+ }
+}
+
+// Mobile: Standard Hugo sidebar behavior
+@include media(medium) {
+ .content-wrapper.api-content {
+ flex-direction: column;
+ }
+
+ .api-toc {
+ display: none;
+ }
+
+ .api-main {
+ padding-right: 0;
+ }
+
+ // Collapse API nav in mobile view
+ .api-nav {
+ margin-top: 1rem;
+ padding-top: 0.5rem;
+
+ &-group-items {
+ max-height: none; // Show all items by default in mobile
+ }
+ }
+}
+
+// Large screens: Wider TOC
+@include media(xlarge) {
+ .api-toc {
+ width: 240px;
+ }
+}
+
+// Compressed layout: narrower TOC, drop border to reduce visual clutter
+// TOC is hidden at ≤1280px (large breakpoint), so this targets the
+// narrow window where the TOC is visible but space is tight.
+@media (min-width: 1281px) and (max-width: 1535px) {
+ .api-toc {
+ width: 180px;
+ border-left: none;
+ }
+}
diff --git a/assets/styles/layouts/_api-operations.scss b/assets/styles/layouts/_api-operations.scss
new file mode 100644
index 000000000..12ccc3653
--- /dev/null
+++ b/assets/styles/layouts/_api-operations.scss
@@ -0,0 +1,540 @@
+// API Operations Styles
+// Renders OpenAPI operations, parameters, schemas, and responses
+
+// Variables
+$api-border-radius: 6px;
+$api-spacing-sm: 0.5rem;
+$api-spacing-md: 1rem;
+$api-spacing-lg: 1.5rem;
+$api-spacing-xl: 2rem;
+
+// Method colors
+$method-get: #00A3FF;
+$method-post: #34BB55;
+$method-put: #FFB94A;
+$method-delete: #D63031;
+$method-patch: #9b2aff;
+
+// Status code colors — intentionally distinct from method colors
+$status-success: #34BB55;
+$status-redirect: #FFB94A;
+$status-client-error: #E17055;
+$status-server-error: #9b2aff;
+
+// ============================================
+// Operation Block
+// ============================================
+
+.api-hugo-native {
+ width: 100%;
+}
+
+.api-operation {
+ margin-bottom: $api-spacing-xl;
+ padding-top: $api-spacing-xl;
+ border-top: 2px solid $nav-border;
+
+ // Keep inline code proportional to surrounding text
+ code {
+ font-size: inherit;
+ }
+
+ &:first-child {
+ border-top: none;
+ padding-top: 0;
+ }
+
+ &:target {
+ animation: highlight-operation 1.5s ease-out;
+ }
+}
+
+@keyframes highlight-operation {
+ 0% {
+ outline: 2px solid rgba($method-get, 0.4);
+ outline-offset: 8px;
+ }
+ 100% {
+ outline-color: transparent;
+ }
+}
+
+// Operation Header
+.api-operation-header {
+ margin-bottom: $api-spacing-md;
+}
+
+.api-operation-endpoint {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: $api-spacing-md;
+ padding-bottom: $api-spacing-md;
+ border-bottom: 1px solid $nav-border;
+}
+
+.api-method {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.75rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ border-radius: 4px;
+ color: #fff;
+
+ &--get { background-color: $method-get; }
+ &--post { background-color: $method-post; }
+ &--put { background-color: $method-put; }
+ &--delete { background-color: $method-delete; }
+ &--patch { background-color: $method-patch; }
+}
+
+.api-path {
+ font-family: $code;
+ font-size: 0.95rem;
+ color: $article-text;
+ background: $article-code-bg;
+ padding: 0.25rem 0.5rem;
+ border-radius: 4px;
+}
+
+.api-operation-summary {
+ margin: 0;
+ font-size: 1.25rem;
+ font-weight: 600;
+ color: $article-heading;
+}
+
+.api-operation-description {
+ margin: $api-spacing-md 0;
+ color: $article-text;
+ line-height: 1.6;
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+}
+
+// ============================================
+// Section Titles
+// ============================================
+
+.api-section-title {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin: $api-spacing-lg 0 $api-spacing-md;
+ padding-bottom: $api-spacing-sm;
+ font-size: 1rem;
+ font-weight: 600;
+ color: $article-heading;
+ border-bottom: 1px solid $nav-border;
+}
+
+// ============================================
+// Parameters Section
+// ============================================
+
+.api-parameters {
+ margin: $api-spacing-lg 0;
+}
+
+.api-param-group {
+ margin-bottom: $api-spacing-md;
+}
+
+.api-param-group-title {
+ margin: $api-spacing-sm 0;
+ font-size: 0.85rem;
+ font-weight: 500;
+ color: rgba($article-text, 0.6);
+ text-transform: uppercase;
+ letter-spacing: 0.05em;
+}
+
+.api-param-list {
+ // Flat list — no outer border, rows separated by dividers
+}
+
+.api-param-row {
+ padding: $api-spacing-md 0;
+ border-bottom: 1px solid $nav-border;
+
+ &:last-child {
+ border-bottom: none;
+ }
+}
+
+.api-param-name-line {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: 0.25rem;
+}
+
+.api-param-name {
+ font-family: $code;
+ font-size: 0.9rem;
+ font-weight: 600;
+ color: $article-heading;
+}
+
+.api-param-type {
+ font-size: 0.8rem;
+ color: rgba($article-text, 0.6);
+}
+
+.api-param-description {
+ margin-top: 0.25rem;
+ color: $article-text;
+ line-height: 1.5;
+
+ p {
+ margin: 0;
+ }
+}
+
+.api-param-enum,
+.api-param-default {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+}
+
+.api-param-enum-label,
+.api-param-default-label {
+ color: rgba($article-text, 0.6);
+}
+
+.api-param-enum-value,
+.api-param-default-value {
+ font-family: $code;
+ font-size: 0.8rem;
+ background: $article-code-bg;
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+}
+
+// ============================================
+// Badges
+// ============================================
+
+.api-badge {
+ display: inline-flex;
+ align-items: center;
+ padding: 0.125rem 0.375rem;
+ font-size: 0.7rem;
+ font-weight: 600;
+ text-transform: uppercase;
+ letter-spacing: 0.03em;
+ border-radius: 3px;
+
+ &--required {
+ background: rgba($method-delete, 0.1);
+ color: $method-delete;
+ }
+}
+
+// ============================================
+// Request Body Section
+// ============================================
+
+.api-request-body {
+ margin: $api-spacing-lg 0;
+}
+
+.api-request-body-description {
+ margin: $api-spacing-sm 0;
+ color: $article-text;
+
+ p:last-child {
+ margin-bottom: 0;
+ }
+}
+
+.api-content-type {
+ margin: $api-spacing-sm 0;
+ font-size: 0.85rem;
+
+ code {
+ font-family: $code;
+ background: $article-code-bg;
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+ }
+}
+
+.api-content-type-label {
+ color: rgba($article-text, 0.6);
+}
+
+// ============================================
+// Schema Section
+// ============================================
+
+.api-schema {
+ margin: $api-spacing-md 0;
+
+ &--nested {
+ margin-left: $api-spacing-lg;
+ padding-left: $api-spacing-md;
+ border-left: 2px solid $nav-border;
+ }
+}
+
+.api-schema-properties {
+ // Flat list — no outer border, rows separated by dividers
+}
+
+.api-schema-property {
+ padding: $api-spacing-md 0;
+ border-bottom: 1px solid $nav-border;
+
+ &:last-child {
+ border-bottom: none;
+ }
+
+ &--required {
+ .api-schema-property-name {
+ &::after {
+ content: '*';
+ color: $method-delete;
+ margin-left: 0.25rem;
+ }
+ }
+ }
+}
+
+.api-schema-property-header {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+ margin-bottom: 0.25rem;
+}
+
+.api-schema-property-name {
+ font-family: $code;
+ font-size: 0.9rem;
+ font-weight: 600;
+ color: $article-heading;
+}
+
+.api-schema-property-type {
+ font-size: 0.8rem;
+ color: rgba($article-text, 0.6);
+}
+
+.api-schema-property-description {
+ margin-top: 0.25rem;
+ color: $article-text;
+ line-height: 1.5;
+
+ p {
+ margin: 0;
+ }
+}
+
+.api-schema-property-enum,
+.api-schema-property-default,
+.api-schema-property-example {
+ margin-top: 0.5rem;
+ font-size: 0.85rem;
+}
+
+.api-enum-label,
+.api-default-label,
+.api-example-label {
+ color: rgba($article-text, 0.6);
+}
+
+.api-enum-value,
+.api-default-value,
+.api-example-value {
+ font-family: $code;
+ font-size: 0.8rem;
+ background: $article-code-bg;
+ padding: 0.125rem 0.375rem;
+ border-radius: 3px;
+}
+
+// Schema Example Block
+.api-schema-example {
+ margin-top: $api-spacing-md;
+ border: 1px solid rgba(0, 0, 0, 0.1);
+ border-radius: $api-border-radius;
+ overflow: hidden;
+
+ .dark-theme & {
+ border-color: rgba(255, 255, 255, 0.1);
+ }
+}
+
+.api-schema-example-title {
+ display: block;
+ margin: 0;
+ padding: $api-spacing-sm $api-spacing-md;
+ font-size: 0.85rem;
+ font-weight: 600;
+ background: rgba(0, 0, 0, 0.03);
+ border-bottom: 1px solid rgba(0, 0, 0, 0.1);
+
+ .dark-theme & {
+ background: rgba(255, 255, 255, 0.03);
+ border-bottom-color: rgba(255, 255, 255, 0.1);
+ }
+}
+
+pre.api-schema-example-code {
+ margin: 0;
+ padding: $api-spacing-sm $api-spacing-md;
+ background: $article-code-bg;
+ overflow-x: auto;
+
+ code {
+ font-family: $code;
+ font-size: 0.85rem;
+ }
+}
+
+// ============================================
+// Responses Section
+// ============================================
+
+.api-responses {
+ margin: $api-spacing-lg 0;
+}
+
+.api-response-list {
+ display: flex;
+ flex-direction: column;
+ gap: $api-spacing-sm;
+}
+
+.api-response {
+ padding: $api-spacing-sm 0;
+}
+
+.api-response-header {
+ display: flex;
+ align-items: center;
+ gap: $api-spacing-sm;
+}
+
+.api-response-status {
+ display: inline-flex;
+ align-items: center;
+ justify-content: center;
+ min-width: 3rem;
+ padding: 0.25rem 0.5rem;
+ font-size: 0.8rem;
+ font-weight: 600;
+ border-radius: 4px;
+ color: #fff;
+
+ &--success { background-color: $status-success; }
+ &--redirect { background-color: $status-redirect; }
+ &--client-error { background-color: $status-client-error; }
+ &--server-error { background-color: $status-server-error; }
+ &--info { background-color: rgba($article-text, 0.6); }
+}
+
+.api-response-description {
+ color: $article-text;
+}
+
+.api-response-body {
+ margin-top: $api-spacing-sm;
+ margin-left: $api-spacing-lg;
+ padding: $api-spacing-sm 0 $api-spacing-sm $api-spacing-md;
+ border-left: 2px solid rgba($article-text, 0.1);
+}
+
+// ============================================
+// Tag Overview
+// ============================================
+
+.api-tag-overview {
+ margin-bottom: $api-spacing-xl;
+ padding-bottom: $api-spacing-lg;
+ border-bottom: 1px solid $nav-border;
+}
+
+.api-tag-description {
+ color: $article-text;
+ line-height: 1.7;
+
+ h4, h5 {
+ margin-top: $api-spacing-lg;
+ margin-bottom: $api-spacing-sm;
+ color: $article-heading;
+ }
+
+ ul, ol {
+ padding-left: $api-spacing-lg;
+ }
+
+ a {
+ color: $article-link;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+}
+
+// ============================================
+// Related Guides Section
+// ============================================
+
+.api-related-guides {
+ margin-top: $api-spacing-xl;
+ padding-top: $api-spacing-lg;
+ border-top: 1px solid $nav-border;
+}
+
+.api-related-title {
+ margin: 0 0 $api-spacing-md;
+ font-size: 1rem;
+ font-weight: 600;
+ color: $article-heading;
+}
+
+.api-related-list {
+ margin: 0;
+ padding: 0;
+ list-style: none;
+
+ li {
+ margin-bottom: $api-spacing-sm;
+ }
+
+ a {
+ color: $article-link;
+ text-decoration: none;
+
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+}
+
+// ============================================
+// Responsive Adjustments
+// ============================================
+
+@media (max-width: 768px) {
+ .api-operation-endpoint {
+ flex-wrap: wrap;
+ }
+
+ .api-path {
+ font-size: 0.85rem;
+ word-break: break-all;
+ }
+
+ .api-param-name-line,
+ .api-schema-property-header {
+ flex-wrap: wrap;
+ }
+}
diff --git a/assets/styles/layouts/_api-overrides.scss b/assets/styles/layouts/_api-overrides.scss
index bc220588f..00a7b1286 100644
--- a/assets/styles/layouts/_api-overrides.scss
+++ b/assets/styles/layouts/_api-overrides.scss
@@ -1,9 +1,16 @@
+////////////////////////////////////////////////////////////////////////////////
+// API Documentation Style Overrides
+//
+// Provides loading spinner and reusable HTTP method badge colors.
+// Used by Hugo-native API templates for consistent styling.
+////////////////////////////////////////////////////////////////////////////////
+
@import "tools/color-palette";
@import "tools/fonts";
// Fonts
$proxima: 'Proxima Nova', sans-serif;
-$code: 'IBM Plex Mono', monospace;;
+$code: 'IBM Plex Mono', monospace;
// Font weights
$medium: 500;
@@ -22,7 +29,7 @@ $bold: 700;
}
@keyframes spinner {
- to {transform: rotate(360deg);}
+ to { transform: rotate(360deg); }
}
.spinner:before {
@@ -41,256 +48,15 @@ $bold: 700;
animation: spinner .6s linear infinite;
}
-//////////////////////////////// InfluxDB Header ///////////////////////////////
-
-#influx-header {
- font-family: $proxima;
- padding: 10px ;
- display: flex;
- align-items: center;
- justify-content: space-between;
- background-color: $g2-kevlar;
- a {
- text-decoration: none;
- &.back {
- color: $g20-white;
- transition: color .2s;
- &:hover {
- color: $b-pool;
- }
- &:before {
- content: "\e919";
- font-family: 'icomoon-v2';
- margin-right: .65rem;
- }
- }
- &.btn {
- padding: .5rem .75rem .5rem .65rem;
- font-size: .85rem;
- font-weight: 500;
- color: $g15-platinum;
- background: $g5-pepper;
- border-radius: 4.5px;
- transition: all .2s;
- &:before {
- content: "\e934";
- display: inline-block;
- font-size: .95rem;
- margin-right: .5rem;
- font-family: 'icomoon-v2';
- }
- &:hover {
- color: $g20-white;
- background: $b-pool;
- }
- }
- }
-}
-
-// Header Media Queries
-
-@media (max-width: 600px) {
- #influx-header span.version {display: none;}
-}
-
+////////////////////////////////////////////////////////////////////////////////
+/////////////////////////// HTTP Method Badge Colors ///////////////////////////
////////////////////////////////////////////////////////////////////////////////
-.cjtbAK {
- h1,h2,h3,h4,h5,h6,
- p,li,th,td {
- font-family: $proxima !important;
- }
-}
-
-#redoc {
- h1,h2,h3 {
- font-weight: $medium !important;
- }
-}
-
-// Section title padding
-.dluJDj {
- padding: 20px 0;
-}
-
-// Page h1
-.dTJWQH {
- color: $g7-graphite;
- font-size: 2rem;
-}
-
-// Download button
-.jIdpVJ {
- background: $b-dodger;
- color: $g20-white;
- border: none;
- border-radius: 3px;
- font-family: $proxima;
- font-size: .85rem;
- font-weight: $medium;
- transition: background-color .2s;
- &:hover {
- background-color: $b-pool;
- }
-}
-
-// Tag h1s
-.WxWXp {
- color: $g7-graphite;
- font-size: 1.75rem;
-}
-
-// Summaru h2s and table headers
-.ioYTqA, .bxcHYI, .hoUoen {
- color: $g7-graphite;
-}
-
-// h3s
-.espozG {
- color: $g8-storm;
-}
-
-// Links
-.bnFPhO a { color: $b-dodger;
- &:visited {color: $b-dodger;}
-}
-
-.redoc-json {
- font-family: $code !important;
-}
-
-// Inline Code
-.flfxUM code,
-.gDsWLk code,
-.kTVySD {
- font-family: $code !important;
- color: $cp-marguerite;
- background: $cp-titan;
- border-color: $cp-titan;
-}
-
-// Required tags
-.jsTAxL {
- color: $r-curacao;
-}
-
-///////////////////////////// RESPONSE COLOR BLOCKS ////////////////////////////
-
-// Green
-.hLVzSF, .fDvFMp {
- background-color: rgba($gr-honeydew, .2);
- color: $gr-emerald;
-}
-
-// Red
-.byLrBg {
- background-color: rgba($r-curacao, .1);
- color: $r-curacao;
-}
-
-
-
-/////////////////////////////////// LEFT NAV ///////////////////////////////////
-
-// Left nav background
-.gZdDsM {
- background-color: $g19-ghost;
-}
-
-.gpbcFk:hover, .sc-eTuwsz.active {
- background-color: $g17-whisper;
-}
-
-// List item text
-.SmuWE, .gcUzvG, .bbViyS, .sc-hrWEMg label {
- font-family: $proxima !important;
-}
-
-.fyUykq {
- font-weight: $medium;
-}
-
-// Request method tags
-.cFwMcp {
- &.post { background-color: $b-ocean; }
- &.get { background-color: $gr-rainforest; }
- &.put { background-color: $br-galaxy; }
- &.patch { background-color: $y-thunder; color: rgba($g5-pepper, .75);}
- &.delete { background-color: $r-curacao; }
-}
-
-// Active nav section
-.gcUzvG, .iNzLCk:hover {
- color: $br-magenta;
-}
-
-/////////////////////////////// RIGHT CODE COLUMN //////////////////////////////
-
-// Right column backgrounds
-.dtUibw, .fLUKgj {
- background-color: $g2-kevlar;
- h3,h4,h5,h6 {
- font-family: $proxima !important;
- font-weight: $medium !important;
- }
-}
-
-// Code backgrounds
-.irpqyy > .react-tabs__tab-panel {
- background-color: $g0-obsidian;
-}
-.dHLKeu, .fVaxnA {
- padding-left: 10px;
- background-color: $g0-obsidian;
-}
-
-// Response code tabs
-.irpqyy > ul > li {
- background-color: $g0-obsidian;
- border-radius: 3px;
- &.react-tabs__tab--selected{ color: $br-pulsar;}
- &.tab-error { color: $r-fire; }
- &.tab-success { color: $gr-viridian; }
-}
-
-// Request methods
-.bNYCAJ,
-.jBjYbV,
-.hOczRB,
-.fRsrDc,
-.hPskZd {
- font-family: $proxima;
- font-weight: $medium;
- letter-spacing: .04em;
- border-radius: 3px;
-}
-.bNYCAJ { background-color: $b-ocean; } /* Post */
-.jBjYbV { background-color: $gr-viridian; } /* Get */
-.hOczRB { background-color: $br-galaxy; } /* Put */
-.fRsrDc { background-color: $y-thunder; color: $g5-pepper; } /* Patch */
-.hPskZd { background-color: $r-curacao; } /* Delete */
-
-// Content type block
-.gzAoUb {
- background-color: $g2-kevlar;
- font-family: $proxima;
-}
-.iENVAs { font-family: $code; }
-.dpMbau { font-family: $proxima; }
-
-// Code controls
-.fCJmC {
- font-family: $proxima;
- span { border-radius: 3px; }
-}
-
-// Code blocks
-.kZHJcC { font-family: $code; }
-.jCgylq {
- .token.string {
- color: $gr-honeydew;
- & + a { color: $b-pool; }
- }
- .token.boolean { color: #f955b0; }
-}
+// Reusable method badge colors (used by _api-layout.scss .method-badge)
+// These follow standard REST API color conventions
+$method-get: $gr-rainforest;
+$method-post: $b-ocean;
+$method-put: $br-galaxy;
+$method-patch: $y-thunder;
+$method-delete: $r-curacao;
diff --git a/assets/styles/layouts/_api-security-schemes.scss b/assets/styles/layouts/_api-security-schemes.scss
new file mode 100644
index 000000000..3723786b0
--- /dev/null
+++ b/assets/styles/layouts/_api-security-schemes.scss
@@ -0,0 +1,92 @@
+////////////////////////////////////////////////////////////////////////////////
+// API Security Schemes Styling
+//
+// Styles for security schemes sections displayed on conceptual API pages
+// (like Authentication). These sections are rendered from OpenAPI spec
+// securitySchemes using Hugo templates.
+////////////////////////////////////////////////////////////////////////////////
+
+.api-security-schemes {
+ margin-top: 2rem;
+ padding-top: 2rem;
+ border-top: 1px solid $g5-pepper;
+
+ h2 {
+ margin-bottom: 1.5rem;
+ }
+
+ .security-scheme {
+ margin-bottom: 2rem;
+
+ h3 {
+ margin: 0 0 1rem 0;
+ font-size: 1.1rem;
+ color: $article-heading;
+ }
+ }
+
+ .scheme-details {
+ margin-bottom: 1rem;
+
+ dl {
+ display: grid;
+ grid-template-columns: auto 1fr;
+ gap: 0.5rem 1rem;
+ margin: 0;
+ }
+
+ dt {
+ font-weight: 600;
+ color: $g9-mountain;
+ }
+
+ dd {
+ margin: 0;
+
+ code {
+ background: $article-code-bg;
+ color: $article-code;
+ padding: 0.2em 0.5em;
+ border-radius: 3px;
+ font-size: 0.9em;
+ }
+ }
+ }
+
+ .scheme-description {
+ margin-top: 1rem;
+ padding-top: 1rem;
+ border-top: 1px solid $g5-pepper;
+
+ p:first-child {
+ margin-top: 0;
+ }
+
+ pre {
+ margin: 1rem 0;
+ }
+ }
+}
+
+// Dark theme overrides for security schemes
+[data-theme="dark"],
+html:has(link[title="dark-theme"]:not([disabled])) {
+ .api-security-schemes {
+ border-top-color: $grey25;
+
+ .security-scheme {
+ // Removed background and border - now using plain styling
+ }
+
+ .scheme-details {
+ dt {
+ color: $g15-platinum;
+ }
+ }
+
+ .scheme-description {
+ border-top-color: $grey25;
+ }
+ }
+}
+
diff --git a/assets/styles/layouts/_sidebar.scss b/assets/styles/layouts/_sidebar.scss
index 30eef2b4e..9d2bb6aa6 100644
--- a/assets/styles/layouts/_sidebar.scss
+++ b/assets/styles/layouts/_sidebar.scss
@@ -255,6 +255,66 @@
}
}
}
+
+ // API operation items within Hugo menu
+ .api-operation {
+ a {
+ display: flex;
+ align-items: center;
+ gap: 0.4rem;
+ }
+
+ // Path-based operation display (All endpoints list)
+ &--path .api-path {
+ font-family: $proxima;
+ font-size: 0.9rem;
+ color: inherit;
+ word-break: break-all;
+ }
+ }
+
+ .api-method {
+ font-size: 0.6rem;
+ font-weight: 700;
+ padding: 0.15rem 0.35rem;
+ border-radius: 3px;
+ text-transform: uppercase;
+ flex-shrink: 0;
+ line-height: 1;
+ border: 2px solid;
+ background-color: transparent;
+
+ // Using lighter InfluxData brand colors - bordered style for readability
+ &--get { border-color: $b-pool; color: $b-pool; } // #00A3FF - bright brand blue
+ &--post { border-color: $gr-rainforest; color: $gr-rainforest; } // #34BB55 - bright brand green
+ &--put { border-color: $y-pineapple; color: $y-pineapple; } // #FFB94A - bright yellow (distinct from red)
+ &--delete { border-color: $r-curacao; color: $r-curacao; } // #F95F53 - bright brand red
+ &--patch { border-color: $br-new-purple; color: $br-new-purple; } // #9b2aff - distinctive brand purple
+ }
+
+ // Compatibility version badge (v1 or v2)
+ .api-compat-badge {
+ font-size: 0.55rem;
+ font-weight: 600;
+ padding: 0.1rem 0.3rem;
+ border-radius: 3px;
+ text-transform: uppercase;
+ flex-shrink: 0;
+ line-height: 1;
+ margin-left: auto;
+ opacity: 0.8;
+ cursor: help;
+
+ &--v1 { background: #8b5cf6; color: white; } // Purple for v1
+ &--v2 { background: #06b6d4; color: white; } // Cyan for v2
+ }
+
+ // Non-link group labels (for multi-tag groups)
+ .nav-group-label {
+ color: $nav-item;
+ font-weight: $medium;
+ display: inline-block;
+ }
}
.feature-board-badge {
diff --git a/assets/styles/styles-default.scss b/assets/styles/styles-default.scss
index 8852a240c..310f91773 100644
--- a/assets/styles/styles-default.scss
+++ b/assets/styles/styles-default.scss
@@ -32,7 +32,11 @@
"layouts/v1-overrides",
"layouts/notifications",
"layouts/code-controls",
- "layouts/v3-wayfinding";
+ "layouts/v3-wayfinding",
+ "layouts/api-layout",
+ "layouts/api-security-schemes",
+ "layouts/api-operations",
+ "layouts/api-code-samples";
// Import Components
@import "components/influxdb-version-detector",
diff --git a/content/influxdb/cloud/reference/api/_index.md b/content/influxdb/cloud/reference/api/_index.md
deleted file mode 100644
index 16e3bdfbf..000000000
--- a/content/influxdb/cloud/reference/api/_index.md
+++ /dev/null
@@ -1,17 +0,0 @@
----
-title: InfluxDB HTTP API
-description: >
- The InfluxDB HTTP API provides a programmatic interface for interactions with InfluxDB, such as writing and querying data,
- and managing resources within an InfluxDB instance.
- Access the InfluxDB API using the `/api/v2/` endpoint.
-menu:
- influxdb_cloud:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 3
-influxdb/cloud/tags: [api]
-source: /shared/influxdb-v2/reference/api/_index.md
----
-
-
diff --git a/content/influxdb/v2/reference/api/_index.md b/content/influxdb/v2/reference/api/_index.md
deleted file mode 100644
index 47e1ea5fa..000000000
--- a/content/influxdb/v2/reference/api/_index.md
+++ /dev/null
@@ -1,22 +0,0 @@
----
-title: InfluxDB HTTP API
-description: >
- The InfluxDB HTTP API provides a programmatic interface for interactions with InfluxDB, such as writing and querying data,
- and managing resources within an InfluxDB instance.
- Access the InfluxDB API using the `/api/v2/` or InfluxDB v1 endpoints.
-menu:
- influxdb_v2:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 3
-influxdb/v2/tags: [api]
-aliases:
- - /influxdb/v2/concepts/api/
-related:
- - /influxdb/v2/api-guide/api_intro/
- - /influxdb/v2/api-guide/influxdb-1x/
-source: /shared/influxdb-v2/reference/api/_index.md
----
-
-
diff --git a/content/influxdb3/cloud-dedicated/management-api/_index.md b/content/influxdb3/cloud-dedicated/management-api/_index.md
new file mode 100644
index 000000000..77eeafad5
--- /dev/null
+++ b/content/influxdb3/cloud-dedicated/management-api/_index.md
@@ -0,0 +1,27 @@
+---
+title: InfluxDB HTTP API
+description: >-
+ Use the InfluxDB HTTP API to write data, query data, and manage databases,
+ tables, and tokens.
+weight: 104
+type: api
+articleDataKey: influxdb3-cloud-dedicated
+articleSection: management-api
+menu:
+ influxdb3_cloud_dedicated:
+ name: InfluxDB HTTP API
+ identifier: api-reference-influxdb3-cloud-dedicated-management-api
+ parent: Reference
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
+
+Use the {{% product-name %}} HTTP API to write data, query data, and manage databases, tables, and tokens.
+
+{{< children >}}
diff --git a/content/influxdb3/cloud-dedicated/management-api/all-endpoints/_index.md b/content/influxdb3/cloud-dedicated/management-api/all-endpoints/_index.md
new file mode 100644
index 000000000..51f5f9695
--- /dev/null
+++ b/content/influxdb3/cloud-dedicated/management-api/all-endpoints/_index.md
@@ -0,0 +1,25 @@
+---
+title: All endpoints
+description: View all API endpoints sorted by path.
+type: api
+layout: all-endpoints
+weight: 999
+isAllEndpoints: true
+articleDataKey: influxdb3-cloud-dedicated
+articleSection: management-api
+menu:
+ influxdb3_cloud_dedicated:
+ name: All endpoints
+ identifier: all-endpoints-influxdb3-cloud-dedicated-management-api
+ parent: InfluxDB HTTP API
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
+
+All {{% product-name %}} API endpoints, sorted by path.
diff --git a/content/influxdb3/cloud-dedicated/reference/api/_index.md b/content/influxdb3/cloud-dedicated/reference/api/_index.md
deleted file mode 100644
index 806c248ae..000000000
--- a/content/influxdb3/cloud-dedicated/reference/api/_index.md
+++ /dev/null
@@ -1,41 +0,0 @@
----
-title: InfluxDB HTTP API
-description: >
- The InfluxDB HTTP API provides a programmatic interface for interactions with
- InfluxDB, such as writing and querying data, and managing an InfluxDB cluster.
- Access the InfluxDB API using the `/api/v2/write`, InfluxDB v1, or
- Management API endpoints for InfluxDB Cloud Dedicated.
-menu:
- influxdb3_cloud_dedicated:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 105
-influxdb3/cloud-dedicated/tags: [api]
----
-
-The InfluxDB HTTP API provides a programmatic interface for interactions with
-{{% product-name %}}, such as writing and querying data, and managing an InfluxDB cluster.
-
-Access the InfluxDB HTTP API using the `/api/v2/` endpoint, InfluxDB v1 endpoints, or
-Management API endpoints for {{% product-name %}}.
-
-## InfluxDB v2 Compatibility API reference documentation
-
-InfluxDB v2 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v2-compatible
-endpoints that work with {{% product-name %}} and with InfluxDB 2.x client
-libraries and third-party integrations.
-
-## InfluxDB v1 Compatibility API reference documentation
-
-InfluxDB v1 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v1-compatible `/write` and `/query` endpoints that work with {{% product-name %}} and with InfluxDB 1.x client libraries and third-party integrations.
-
-## InfluxDB Management API reference documentation
-
-InfluxDB Management API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB Management API endpoints.
-The Management API lets cluster administrators manage resources such as databases, partitioning templates, and database tokens.
diff --git a/content/influxdb3/cloud-serverless/api/_index.md b/content/influxdb3/cloud-serverless/api/_index.md
new file mode 100644
index 000000000..f48f914af
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/_index.md
@@ -0,0 +1,27 @@
+---
+title: InfluxDB HTTP API
+description: >-
+ Use the InfluxDB HTTP API to write data, query data, and manage databases,
+ tables, and tokens.
+weight: 104
+type: api
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+menu:
+ influxdb3_cloud_serverless:
+ name: InfluxDB HTTP API
+ identifier: api-reference-influxdb3-cloud-serverless-api
+ parent: Reference
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
+
+Use the {{% product-name %}} HTTP API to write data, query data, and manage databases, tables, and tokens.
+
+{{< children >}}
diff --git a/content/influxdb3/cloud-serverless/api/api-compatibility/_index.md b/content/influxdb3/cloud-serverless/api/api-compatibility/_index.md
new file mode 100644
index 000000000..5c313717d
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/api-compatibility/_index.md
@@ -0,0 +1,28 @@
+---
+title: API compatibility
+description: >-
+ Overview of the InfluxDB v1 and v2 compatible write and query endpoints
+ available in InfluxDB 3 Cloud Serverless.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-api-compatibility.yaml
+weight: 100
+tag: API compatibility
+isConceptual: true
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Overview of the InfluxDB v1 and v2 compatible write and query endpoints
+ available in InfluxDB 3 Cloud Serverless.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/authentication/_index.md b/content/influxdb3/cloud-serverless/api/authentication/_index.md
new file mode 100644
index 000000000..d1150c2c0
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/authentication/_index.md
@@ -0,0 +1,39 @@
+---
+title: Authentication
+description: >-
+ Use one of the following schemes to authenticate to the InfluxDB 3 Cloud
+ Serverless API:
+
+
+ - Token authentication
+
+ - Basic authentication
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-authentication.yaml
+weight: 100
+tag: Authentication
+isConceptual: true
+menuGroup: Concepts
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Use one of the following schemes to authenticate to the InfluxDB 3 Cloud
+ Serverless API:
+
+
+ - Token authentication
+
+ - Basic authentication
+showSecuritySchemes: true
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/authorizations-api-tokens/_index.md b/content/influxdb3/cloud-serverless/api/authorizations-api-tokens/_index.md
new file mode 100644
index 000000000..b8cbff1a7
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/authorizations-api-tokens/_index.md
@@ -0,0 +1,61 @@
+---
+title: Authorizations (API tokens)
+description: >-
+ Create and manage API token authorizations that grant read and write
+ permissions to InfluxDB 3 Cloud Serverless organization resources.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-authorizations-api-tokens.yaml
+weight: 100
+tag: Authorizations (API tokens)
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetAuthorizations
+ method: GET
+ path: /api/v2/authorizations
+ summary: List authorizations
+ tags:
+ - Authorizations (API tokens)
+ - operationId: PostAuthorizations
+ method: POST
+ path: /api/v2/authorizations
+ summary: Create an authorization
+ tags:
+ - Authorizations (API tokens)
+ - operationId: GetAuthorizationsID
+ method: GET
+ path: /api/v2/authorizations/{authID}
+ summary: Retrieve an authorization
+ tags:
+ - Authorizations (API tokens)
+ - operationId: PatchAuthorizationsID
+ method: PATCH
+ path: /api/v2/authorizations/{authID}
+ summary: Update an API token to be active or inactive
+ tags:
+ - Authorizations (API tokens)
+ - operationId: DeleteAuthorizationsID
+ method: DELETE
+ path: /api/v2/authorizations/{authID}
+ summary: Delete an authorization
+ tags:
+ - Authorizations (API tokens)
+related:
+ - title: Manage API tokens
+ href: /influxdb3/cloud-serverless/security/tokens/
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/bucket-schemas/_index.md b/content/influxdb3/cloud-serverless/api/bucket-schemas/_index.md
new file mode 100644
index 000000000..753f5c99c
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/bucket-schemas/_index.md
@@ -0,0 +1,53 @@
+---
+title: Bucket Schemas
+description: >-
+ Manage explicit schemas for InfluxDB 3 Cloud Serverless buckets to enforce
+ column names and data types.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-bucket-schemas.yaml
+weight: 100
+tag: Bucket Schemas
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: getMeasurementSchemas
+ method: GET
+ path: /api/v2/buckets/{bucketID}/schema/measurements
+ summary: List measurement schemas of a bucket
+ tags:
+ - Bucket Schemas
+ - operationId: createMeasurementSchema
+ method: POST
+ path: /api/v2/buckets/{bucketID}/schema/measurements
+ summary: Create a measurement schema for a bucket
+ tags:
+ - Bucket Schemas
+ - operationId: getMeasurementSchema
+ method: GET
+ path: /api/v2/buckets/{bucketID}/schema/measurements/{measurementID}
+ summary: Retrieve a measurement schema
+ tags:
+ - Bucket Schemas
+ - operationId: updateMeasurementSchema
+ method: PATCH
+ path: /api/v2/buckets/{bucketID}/schema/measurements/{measurementID}
+ summary: Update a measurement schema
+ tags:
+ - Bucket Schemas
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/buckets/_index.md b/content/influxdb3/cloud-serverless/api/buckets/_index.md
new file mode 100644
index 000000000..1d5abc98b
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/buckets/_index.md
@@ -0,0 +1,115 @@
+---
+title: Buckets
+description: >-
+ Create and manage named storage locations (buckets) in InfluxDB 3 Cloud
+ Serverless, each with a configurable retention period.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-buckets.yaml
+weight: 100
+tag: Buckets
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetBuckets
+ method: GET
+ path: /api/v2/buckets
+ summary: List buckets
+ tags:
+ - Buckets
+ - operationId: PostBuckets
+ method: POST
+ path: /api/v2/buckets
+ summary: Create a bucket
+ tags:
+ - Buckets
+ - operationId: GetBucketsID
+ method: GET
+ path: /api/v2/buckets/{bucketID}
+ summary: Retrieve a bucket
+ tags:
+ - Buckets
+ - operationId: PatchBucketsID
+ method: PATCH
+ path: /api/v2/buckets/{bucketID}
+ summary: Update a bucket
+ tags:
+ - Buckets
+ - operationId: DeleteBucketsID
+ method: DELETE
+ path: /api/v2/buckets/{bucketID}
+ summary: Delete a bucket
+ tags:
+ - Buckets
+ - operationId: GetBucketsIDLabels
+ method: GET
+ path: /api/v2/buckets/{bucketID}/labels
+ summary: List all labels for a bucket
+ tags:
+ - Buckets
+ - operationId: PostBucketsIDLabels
+ method: POST
+ path: /api/v2/buckets/{bucketID}/labels
+ summary: Add a label to a bucket
+ tags:
+ - Buckets
+ - operationId: DeleteBucketsIDLabelsID
+ method: DELETE
+ path: /api/v2/buckets/{bucketID}/labels/{labelID}
+ summary: Delete a label from a bucket
+ tags:
+ - Buckets
+ - operationId: GetBucketsIDMembers
+ method: GET
+ path: /api/v2/buckets/{bucketID}/members
+ summary: List all users with member privileges for a bucket
+ tags:
+ - Buckets
+ - operationId: PostBucketsIDMembers
+ method: POST
+ path: /api/v2/buckets/{bucketID}/members
+ summary: Add a member to a bucket
+ tags:
+ - Buckets
+ - operationId: DeleteBucketsIDMembersID
+ method: DELETE
+ path: /api/v2/buckets/{bucketID}/members/{userID}
+ summary: Remove a member from a bucket
+ tags:
+ - Buckets
+ - operationId: GetBucketsIDOwners
+ method: GET
+ path: /api/v2/buckets/{bucketID}/owners
+ summary: List all owners of a bucket
+ tags:
+ - Buckets
+ - operationId: PostBucketsIDOwners
+ method: POST
+ path: /api/v2/buckets/{bucketID}/owners
+ summary: Add an owner to a bucket
+ tags:
+ - Buckets
+ - operationId: DeleteBucketsIDOwnersID
+ method: DELETE
+ path: /api/v2/buckets/{bucketID}/owners/{userID}
+ summary: Remove an owner from a bucket
+ tags:
+ - Buckets
+related:
+ - title: Manage buckets
+ href: /influxdb3/cloud-serverless/admin/buckets/
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/common-parameters/_index.md b/content/influxdb3/cloud-serverless/api/common-parameters/_index.md
new file mode 100644
index 000000000..5749a0b06
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/common-parameters/_index.md
@@ -0,0 +1,28 @@
+---
+title: Common parameters
+description: >-
+ Common query parameters used by InfluxDB 3 Cloud Serverless API endpoints,
+ including `bucket`, `bucketID`, `org`, and `orgID`.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-common-parameters.yaml
+weight: 100
+tag: Common parameters
+isConceptual: true
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Common query parameters used by InfluxDB 3 Cloud Serverless API endpoints,
+ including `bucket`, `bucketID`, `org`, and `orgID`.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/dbrps/_index.md b/content/influxdb3/cloud-serverless/api/dbrps/_index.md
new file mode 100644
index 000000000..2dc2ab20e
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/dbrps/_index.md
@@ -0,0 +1,60 @@
+---
+title: DBRPs
+description: >-
+ Manage database and retention policy (DBRP) mappings that route InfluxDB
+ v1-compatible requests to InfluxDB 3 Cloud Serverless buckets.
+type: api
+layout: list
+staticFilePath: /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-dbrps.yaml
+weight: 100
+tag: DBRPs
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetDBRPs
+ method: GET
+ path: /api/v2/dbrps
+ summary: List database retention policy mappings
+ tags:
+ - DBRPs
+ - operationId: PostDBRP
+ method: POST
+ path: /api/v2/dbrps
+ summary: Add a database retention policy mapping
+ tags:
+ - DBRPs
+ - operationId: GetDBRPsID
+ method: GET
+ path: /api/v2/dbrps/{dbrpID}
+ summary: Retrieve a database retention policy mapping
+ tags:
+ - DBRPs
+ - operationId: PatchDBRPID
+ method: PATCH
+ path: /api/v2/dbrps/{dbrpID}
+ summary: Update a database retention policy mapping
+ tags:
+ - DBRPs
+ - operationId: DeleteDBRPID
+ method: DELETE
+ path: /api/v2/dbrps/{dbrpID}
+ summary: Delete a database retention policy
+ tags:
+ - DBRPs
+related:
+ - title: Database and retention policy mapping
+ href: /influxdb3/cloud-serverless/reference/api/influxdb-1x/dbrp/
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/delete/_index.md b/content/influxdb3/cloud-serverless/api/delete/_index.md
new file mode 100644
index 000000000..1aa8ba24d
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/delete/_index.md
@@ -0,0 +1,35 @@
+---
+title: Delete
+description: >-
+ Delete time series data from an InfluxDB 3 Cloud Serverless bucket by
+ specifying a time range and optional predicate.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-delete.yaml
+weight: 100
+tag: Delete
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: PostDelete
+ method: POST
+ path: /api/v2/delete
+ summary: Delete data
+ tags:
+ - Delete
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/headers/_index.md b/content/influxdb3/cloud-serverless/api/headers/_index.md
new file mode 100644
index 000000000..ff8391fb9
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/headers/_index.md
@@ -0,0 +1,30 @@
+---
+title: Headers
+description: >-
+ Standard HTTP request headers used by InfluxDB 3 Cloud Serverless API
+ endpoints, including `Accept`, `Authorization`, `Content-Length`, and
+ `Content-Type`.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-headers.yaml
+weight: 100
+tag: Headers
+isConceptual: true
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Standard HTTP request headers used by InfluxDB 3 Cloud Serverless API
+ endpoints, including `Accept`, `Authorization`, `Content-Length`, and
+ `Content-Type`.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/invokable-scripts/_index.md b/content/influxdb3/cloud-serverless/api/invokable-scripts/_index.md
new file mode 100644
index 000000000..edcd703a6
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/invokable-scripts/_index.md
@@ -0,0 +1,71 @@
+---
+title: Invokable Scripts
+description: >-
+ Store, manage, and execute custom Flux scripts in InfluxDB 3 Cloud Serverless.
+ Scripts accept runtime parameters and can be invoked via dedicated endpoints.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-invokable-scripts.yaml
+weight: 100
+tag: Invokable Scripts
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetScripts
+ method: GET
+ path: /api/v2/scripts
+ summary: List scripts
+ tags:
+ - Invokable Scripts
+ - operationId: PostScripts
+ method: POST
+ path: /api/v2/scripts
+ summary: Create a script
+ tags:
+ - Invokable Scripts
+ - operationId: GetScriptsID
+ method: GET
+ path: /api/v2/scripts/{scriptID}
+ summary: Retrieve a script
+ tags:
+ - Invokable Scripts
+ - operationId: PatchScriptsID
+ method: PATCH
+ path: /api/v2/scripts/{scriptID}
+ summary: Update a script
+ tags:
+ - Invokable Scripts
+ - operationId: DeleteScriptsID
+ method: DELETE
+ path: /api/v2/scripts/{scriptID}
+ summary: Delete a script
+ tags:
+ - Invokable Scripts
+ - operationId: PostScriptsIDInvoke
+ method: POST
+ path: /api/v2/scripts/{scriptID}/invoke
+ summary: Invoke a script
+ tags:
+ - Invokable Scripts
+ - operationId: GetScriptsIDParams
+ method: GET
+ path: /api/v2/scripts/{scriptID}/params
+ summary: Find script parameters.
+ tags:
+ - Invokable Scripts
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/limits/_index.md b/content/influxdb3/cloud-serverless/api/limits/_index.md
new file mode 100644
index 000000000..1b7473edd
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/limits/_index.md
@@ -0,0 +1,35 @@
+---
+title: Limits
+description: >-
+ Retrieve rate limits and usage quotas for an InfluxDB 3 Cloud Serverless
+ organization.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-limits.yaml
+weight: 100
+tag: Limits
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetOrgLimitsID
+ method: GET
+ path: /api/v2/orgs/{orgID}/limits
+ summary: Retrieve limits for an organization
+ tags:
+ - Limits
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/organizations/_index.md b/content/influxdb3/cloud-serverless/api/organizations/_index.md
new file mode 100644
index 000000000..f272615b0
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/organizations/_index.md
@@ -0,0 +1,97 @@
+---
+title: Organizations
+description: >-
+ View and manage InfluxDB 3 Cloud Serverless organizations, which are
+ workspaces that group users, buckets, and resources.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-organizations.yaml
+weight: 100
+tag: Organizations
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetOrgs
+ method: GET
+ path: /api/v2/orgs
+ summary: List organizations
+ tags:
+ - Organizations
+ - operationId: PostOrgs
+ method: POST
+ path: /api/v2/orgs
+ summary: Create an organization
+ tags:
+ - Organizations
+ - operationId: GetOrgsID
+ method: GET
+ path: /api/v2/orgs/{orgID}
+ summary: Retrieve an organization
+ tags:
+ - Organizations
+ - operationId: PatchOrgsID
+ method: PATCH
+ path: /api/v2/orgs/{orgID}
+ summary: Update an organization
+ tags:
+ - Organizations
+ - operationId: DeleteOrgsID
+ method: DELETE
+ path: /api/v2/orgs/{orgID}
+ summary: Delete an organization
+ tags:
+ - Organizations
+ - operationId: GetOrgsIDMembers
+ method: GET
+ path: /api/v2/orgs/{orgID}/members
+ summary: List all members of an organization
+ tags:
+ - Organizations
+ - operationId: PostOrgsIDMembers
+ method: POST
+ path: /api/v2/orgs/{orgID}/members
+ summary: Add a member to an organization
+ tags:
+ - Organizations
+ - operationId: DeleteOrgsIDMembersID
+ method: DELETE
+ path: /api/v2/orgs/{orgID}/members/{userID}
+ summary: Remove a member from an organization
+ tags:
+ - Organizations
+ - operationId: GetOrgsIDOwners
+ method: GET
+ path: /api/v2/orgs/{orgID}/owners
+ summary: List all owners of an organization
+ tags:
+ - Organizations
+ - operationId: PostOrgsIDOwners
+ method: POST
+ path: /api/v2/orgs/{orgID}/owners
+ summary: Add an owner to an organization
+ tags:
+ - Organizations
+ - operationId: DeleteOrgsIDOwnersID
+ method: DELETE
+ path: /api/v2/orgs/{orgID}/owners/{userID}
+ summary: Remove an owner from an organization
+ tags:
+ - Organizations
+related:
+ - title: View and manage organizations
+ href: /influxdb3/cloud-serverless/admin/
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/pagination/_index.md b/content/influxdb3/cloud-serverless/api/pagination/_index.md
new file mode 100644
index 000000000..90aff698a
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/pagination/_index.md
@@ -0,0 +1,28 @@
+---
+title: Pagination
+description: >-
+ Query parameters for paginating results from list operations in the InfluxDB 3
+ Cloud Serverless API.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-pagination.yaml
+weight: 100
+tag: Pagination
+isConceptual: true
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Query parameters for paginating results from list operations in the InfluxDB 3
+ Cloud Serverless API.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/quick-start/_index.md b/content/influxdb3/cloud-serverless/api/quick-start/_index.md
new file mode 100644
index 000000000..380c3dadf
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/quick-start/_index.md
@@ -0,0 +1,28 @@
+---
+title: Quick start
+description: >-
+ Get started writing and querying data with the InfluxDB 3 Cloud Serverless
+ API.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-quick-start.yaml
+weight: 1
+tag: Quick start
+isConceptual: true
+menuGroup: Concepts
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Get started writing and querying data with the InfluxDB 3 Cloud Serverless
+ API.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/resources/_index.md b/content/influxdb3/cloud-serverless/api/resources/_index.md
new file mode 100644
index 000000000..1754e198b
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/resources/_index.md
@@ -0,0 +1,35 @@
+---
+title: Resources
+description: >-
+ Retrieve a list of top-level resource types available in the InfluxDB 3 Cloud
+ Serverless API.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-resources.yaml
+weight: 100
+tag: Resources
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetResources
+ method: GET
+ path: /api/v2/resources
+ summary: List all known resources
+ tags:
+ - Resources
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/response-codes/_index.md b/content/influxdb3/cloud-serverless/api/response-codes/_index.md
new file mode 100644
index 000000000..8c5fb7411
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/response-codes/_index.md
@@ -0,0 +1,28 @@
+---
+title: Response codes
+description: >-
+ Standard HTTP status codes returned by InfluxDB 3 Cloud Serverless API
+ endpoints and their meanings.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-response-codes.yaml
+weight: 100
+tag: Response codes
+isConceptual: true
+menuGroup: Concepts
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Standard HTTP status codes returned by InfluxDB 3 Cloud Serverless API
+ endpoints and their meanings.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/routes/_index.md b/content/influxdb3/cloud-serverless/api/routes/_index.md
new file mode 100644
index 000000000..9ae68ce76
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/routes/_index.md
@@ -0,0 +1,33 @@
+---
+title: Routes
+description: Retrieve top-level routes for the InfluxDB 3 Cloud Serverless API.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-routes.yaml
+weight: 100
+tag: Routes
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetRoutes
+ method: GET
+ path: /api/v2
+ summary: List all top level routes
+ tags:
+ - Routes
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/secrets/_index.md b/content/influxdb3/cloud-serverless/api/secrets/_index.md
new file mode 100644
index 000000000..f5e4b0a93
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/secrets/_index.md
@@ -0,0 +1,53 @@
+---
+title: Secrets
+description: >-
+ Create and manage secrets (key-value pairs) for use in InfluxDB 3 Cloud
+ Serverless Flux scripts and tasks.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-secrets.yaml
+weight: 100
+tag: Secrets
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetOrgsIDSecrets
+ method: GET
+ path: /api/v2/orgs/{orgID}/secrets
+ summary: List all secret keys for an organization
+ tags:
+ - Secrets
+ - operationId: PatchOrgsIDSecrets
+ method: PATCH
+ path: /api/v2/orgs/{orgID}/secrets
+ summary: Update secrets in an organization
+ tags:
+ - Secrets
+ - operationId: DeleteOrgsIDSecretsID
+ method: DELETE
+ path: /api/v2/orgs/{orgID}/secrets/{secretID}
+ summary: Delete a secret from an organization
+ tags:
+ - Secrets
+ - operationId: PostOrgsIDSecrets
+ method: POST
+ path: /api/v2/orgs/{orgID}/secrets/delete
+ summary: Delete secrets from an organization
+ tags:
+ - Secrets
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/security-and-access-endpoints/_index.md b/content/influxdb3/cloud-serverless/api/security-and-access-endpoints/_index.md
new file mode 100644
index 000000000..132a5da69
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/security-and-access-endpoints/_index.md
@@ -0,0 +1,59 @@
+---
+title: Security and access endpoints
+description: >-
+ Endpoints for managing authentication and access control in InfluxDB 3 Cloud
+ Serverless.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-security-and-access-endpoints.yaml
+weight: 100
+tag: Security and access endpoints
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetAuthorizations
+ method: GET
+ path: /api/v2/authorizations
+ summary: List authorizations
+ tags:
+ - Security and access endpoints
+ - operationId: PostAuthorizations
+ method: POST
+ path: /api/v2/authorizations
+ summary: Create an authorization
+ tags:
+ - Security and access endpoints
+ - operationId: GetAuthorizationsID
+ method: GET
+ path: /api/v2/authorizations/{authID}
+ summary: Retrieve an authorization
+ tags:
+ - Security and access endpoints
+ - operationId: PatchAuthorizationsID
+ method: PATCH
+ path: /api/v2/authorizations/{authID}
+ summary: Update an API token to be active or inactive
+ tags:
+ - Security and access endpoints
+ - operationId: DeleteAuthorizationsID
+ method: DELETE
+ path: /api/v2/authorizations/{authID}
+ summary: Delete an authorization
+ tags:
+ - Security and access endpoints
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/supported-operations/_index.md b/content/influxdb3/cloud-serverless/api/supported-operations/_index.md
new file mode 100644
index 000000000..7d4b6902a
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/supported-operations/_index.md
@@ -0,0 +1,28 @@
+---
+title: Supported operations
+description: >-
+ Overview of the common CRUD operations supported by the InfluxDB 3 Cloud
+ Serverless API.
+type: api
+layout: single
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-supported-operations.yaml
+weight: 100
+tag: Supported operations
+isConceptual: true
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+tagDescription: >-
+ Overview of the common CRUD operations supported by the InfluxDB 3 Cloud
+ Serverless API.
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/system-information-endpoints/_index.md b/content/influxdb3/cloud-serverless/api/system-information-endpoints/_index.md
new file mode 100644
index 000000000..592a9c0f1
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/system-information-endpoints/_index.md
@@ -0,0 +1,41 @@
+---
+title: System information endpoints
+description: >-
+ Endpoints for retrieving system-level information about the InfluxDB 3 Cloud
+ Serverless instance.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-system-information-endpoints.yaml
+weight: 100
+tag: System information endpoints
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetRoutes
+ method: GET
+ path: /api/v2
+ summary: List all top level routes
+ tags:
+ - System information endpoints
+ - operationId: GetResources
+ method: GET
+ path: /api/v2/resources
+ summary: List all known resources
+ tags:
+ - System information endpoints
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/tasks/_index.md b/content/influxdb3/cloud-serverless/api/tasks/_index.md
new file mode 100644
index 000000000..9ecd19ba0
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/tasks/_index.md
@@ -0,0 +1,154 @@
+---
+title: Tasks
+description: >-
+ Schedule and manage Flux tasks that process and transform data on a recurring
+ basis in InfluxDB 3 Cloud Serverless.
+type: api
+layout: list
+staticFilePath: /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-tasks.yaml
+weight: 100
+tag: Tasks
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetTasks
+ method: GET
+ path: /api/v2/tasks
+ summary: List all tasks
+ tags:
+ - Tasks
+ - operationId: PostTasks
+ method: POST
+ path: /api/v2/tasks
+ summary: Create a task
+ tags:
+ - Tasks
+ - operationId: GetTasksID
+ method: GET
+ path: /api/v2/tasks/{taskID}
+ summary: Retrieve a task
+ tags:
+ - Tasks
+ - operationId: PatchTasksID
+ method: PATCH
+ path: /api/v2/tasks/{taskID}
+ summary: Update a task
+ tags:
+ - Tasks
+ - operationId: DeleteTasksID
+ method: DELETE
+ path: /api/v2/tasks/{taskID}
+ summary: Delete a task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDLabels
+ method: GET
+ path: /api/v2/tasks/{taskID}/labels
+ summary: List labels for a task
+ tags:
+ - Tasks
+ - operationId: PostTasksIDLabels
+ method: POST
+ path: /api/v2/tasks/{taskID}/labels
+ summary: Add a label to a task
+ tags:
+ - Tasks
+ - operationId: DeleteTasksIDLabelsID
+ method: DELETE
+ path: /api/v2/tasks/{taskID}/labels/{labelID}
+ summary: Delete a label from a task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDLogs
+ method: GET
+ path: /api/v2/tasks/{taskID}/logs
+ summary: Retrieve all logs for a task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDMembers
+ method: GET
+ path: /api/v2/tasks/{taskID}/members
+ summary: List all task members
+ tags:
+ - Tasks
+ - operationId: PostTasksIDMembers
+ method: POST
+ path: /api/v2/tasks/{taskID}/members
+ summary: Add a member to a task
+ tags:
+ - Tasks
+ - operationId: DeleteTasksIDMembersID
+ method: DELETE
+ path: /api/v2/tasks/{taskID}/members/{userID}
+ summary: Remove a member from a task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDOwners
+ method: GET
+ path: /api/v2/tasks/{taskID}/owners
+ summary: List all owners of a task
+ tags:
+ - Tasks
+ - operationId: PostTasksIDOwners
+ method: POST
+ path: /api/v2/tasks/{taskID}/owners
+ summary: Add an owner for a task
+ tags:
+ - Tasks
+ - operationId: DeleteTasksIDOwnersID
+ method: DELETE
+ path: /api/v2/tasks/{taskID}/owners/{userID}
+ summary: Remove an owner from a task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDRuns
+ method: GET
+ path: /api/v2/tasks/{taskID}/runs
+ summary: List runs for a task
+ tags:
+ - Tasks
+ - operationId: PostTasksIDRuns
+ method: POST
+ path: /api/v2/tasks/{taskID}/runs
+ summary: Start a task run, overriding the schedule
+ tags:
+ - Tasks
+ - operationId: GetTasksIDRunsID
+ method: GET
+ path: /api/v2/tasks/{taskID}/runs/{runID}
+ summary: Retrieve a run for a task.
+ tags:
+ - Tasks
+ - operationId: DeleteTasksIDRunsID
+ method: DELETE
+ path: /api/v2/tasks/{taskID}/runs/{runID}
+ summary: Cancel a running task
+ tags:
+ - Tasks
+ - operationId: GetTasksIDRunsIDLogs
+ method: GET
+ path: /api/v2/tasks/{taskID}/runs/{runID}/logs
+ summary: Retrieve all logs for a run
+ tags:
+ - Tasks
+ - operationId: PostTasksIDRunsIDRetry
+ method: POST
+ path: /api/v2/tasks/{taskID}/runs/{runID}/retry
+ summary: Retry a task run
+ tags:
+ - Tasks
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/telegrafs/_index.md b/content/influxdb3/cloud-serverless/api/telegrafs/_index.md
new file mode 100644
index 000000000..68835158b
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/telegrafs/_index.md
@@ -0,0 +1,113 @@
+---
+title: Telegrafs
+description: >-
+ Create and manage Telegraf agent configurations that collect and write data to
+ InfluxDB 3 Cloud Serverless.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-telegrafs.yaml
+weight: 100
+tag: Telegrafs
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetTelegrafs
+ method: GET
+ path: /api/v2/telegrafs
+ summary: List all Telegraf configurations
+ tags:
+ - Telegrafs
+ - operationId: PostTelegrafs
+ method: POST
+ path: /api/v2/telegrafs
+ summary: Create a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: GetTelegrafsID
+ method: GET
+ path: /api/v2/telegrafs/{telegrafID}
+ summary: Retrieve a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: PutTelegrafsID
+ method: PUT
+ path: /api/v2/telegrafs/{telegrafID}
+ summary: Update a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: DeleteTelegrafsID
+ method: DELETE
+ path: /api/v2/telegrafs/{telegrafID}
+ summary: Delete a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: GetTelegrafsIDLabels
+ method: GET
+ path: /api/v2/telegrafs/{telegrafID}/labels
+ summary: List all labels for a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: PostTelegrafsIDLabels
+ method: POST
+ path: /api/v2/telegrafs/{telegrafID}/labels
+ summary: Add a label to a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: DeleteTelegrafsIDLabelsID
+ method: DELETE
+ path: /api/v2/telegrafs/{telegrafID}/labels/{labelID}
+ summary: Delete a label from a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: GetTelegrafsIDMembers
+ method: GET
+ path: /api/v2/telegrafs/{telegrafID}/members
+ summary: List all users with member privileges for a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: PostTelegrafsIDMembers
+ method: POST
+ path: /api/v2/telegrafs/{telegrafID}/members
+ summary: Add a member to a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: DeleteTelegrafsIDMembersID
+ method: DELETE
+ path: /api/v2/telegrafs/{telegrafID}/members/{userID}
+ summary: Remove a member from a Telegraf config
+ tags:
+ - Telegrafs
+ - operationId: GetTelegrafsIDOwners
+ method: GET
+ path: /api/v2/telegrafs/{telegrafID}/owners
+ summary: List all owners of a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: PostTelegrafsIDOwners
+ method: POST
+ path: /api/v2/telegrafs/{telegrafID}/owners
+ summary: Add an owner to a Telegraf configuration
+ tags:
+ - Telegrafs
+ - operationId: DeleteTelegrafsIDOwnersID
+ method: DELETE
+ path: /api/v2/telegrafs/{telegrafID}/owners/{userID}
+ summary: Remove an owner from a Telegraf config
+ tags:
+ - Telegrafs
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/templates/_index.md b/content/influxdb3/cloud-serverless/api/templates/_index.md
new file mode 100644
index 000000000..cfb0cb003
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/templates/_index.md
@@ -0,0 +1,77 @@
+---
+title: Templates
+description: >-
+ Export and apply InfluxDB templates, and manage template stacks for InfluxDB 3
+ Cloud Serverless.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-templates.yaml
+weight: 100
+tag: Templates
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: ListStacks
+ method: GET
+ path: /api/v2/stacks
+ summary: List installed stacks
+ tags:
+ - Templates
+ - operationId: CreateStack
+ method: POST
+ path: /api/v2/stacks
+ summary: Create a stack
+ tags:
+ - Templates
+ - operationId: ReadStack
+ method: GET
+ path: /api/v2/stacks/{stack_id}
+ summary: Retrieve a stack
+ tags:
+ - Templates
+ - operationId: UpdateStack
+ method: PATCH
+ path: /api/v2/stacks/{stack_id}
+ summary: Update a stack
+ tags:
+ - Templates
+ - operationId: DeleteStack
+ method: DELETE
+ path: /api/v2/stacks/{stack_id}
+ summary: Delete a stack and associated resources
+ tags:
+ - Templates
+ - operationId: UninstallStack
+ method: POST
+ path: /api/v2/stacks/{stack_id}/uninstall
+ summary: Uninstall a stack
+ tags:
+ - Templates
+ - operationId: ApplyTemplate
+ method: POST
+ path: /api/v2/templates/apply
+ summary: Apply or dry-run a template
+ tags:
+ - Templates
+ - operationId: ExportTemplate
+ method: POST
+ path: /api/v2/templates/export
+ summary: Export a new template
+ tags:
+ - Templates
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/usage/_index.md b/content/influxdb3/cloud-serverless/api/usage/_index.md
new file mode 100644
index 000000000..c8f9761d3
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/usage/_index.md
@@ -0,0 +1,34 @@
+---
+title: Usage
+description: >-
+ Retrieve usage metrics and cardinality data for an InfluxDB 3 Cloud Serverless
+ organization.
+type: api
+layout: list
+staticFilePath: /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-usage.yaml
+weight: 100
+tag: Usage
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetOrgUsageID
+ method: GET
+ path: /api/v2/orgs/{orgID}/usage
+ summary: Retrieve usage for an organization
+ tags:
+ - Usage
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/api/variables/_index.md b/content/influxdb3/cloud-serverless/api/variables/_index.md
new file mode 100644
index 000000000..173b93959
--- /dev/null
+++ b/content/influxdb3/cloud-serverless/api/variables/_index.md
@@ -0,0 +1,81 @@
+---
+title: Variables
+description: Create and manage variables for use in InfluxDB 3 Cloud Serverless dashboards.
+type: api
+layout: list
+staticFilePath: >-
+ /openapi/influxdb3-cloud-serverless/tags/influxdb3-cloud-serverless-variables.yaml
+weight: 100
+tag: Variables
+isConceptual: false
+menuGroup: Other
+specDownloadPath: /openapi/influxdb3-cloud-serverless.yml
+articleDataKey: influxdb3-cloud-serverless
+articleSection: api
+operations:
+ - operationId: GetVariables
+ method: GET
+ path: /api/v2/variables
+ summary: List all variables
+ tags:
+ - Variables
+ - operationId: PostVariables
+ method: POST
+ path: /api/v2/variables
+ summary: Create a variable
+ tags:
+ - Variables
+ - operationId: GetVariablesID
+ method: GET
+ path: /api/v2/variables/{variableID}
+ summary: Retrieve a variable
+ tags:
+ - Variables
+ - operationId: PutVariablesID
+ method: PUT
+ path: /api/v2/variables/{variableID}
+ summary: Replace a variable
+ tags:
+ - Variables
+ - operationId: PatchVariablesID
+ method: PATCH
+ path: /api/v2/variables/{variableID}
+ summary: Update a variable
+ tags:
+ - Variables
+ - operationId: DeleteVariablesID
+ method: DELETE
+ path: /api/v2/variables/{variableID}
+ summary: Delete a variable
+ tags:
+ - Variables
+ - operationId: GetVariablesIDLabels
+ method: GET
+ path: /api/v2/variables/{variableID}/labels
+ summary: List all labels for a variable
+ tags:
+ - Variables
+ - operationId: PostVariablesIDLabels
+ method: POST
+ path: /api/v2/variables/{variableID}/labels
+ summary: Add a label to a variable
+ tags:
+ - Variables
+ - operationId: DeleteVariablesIDLabelsID
+ method: DELETE
+ path: /api/v2/variables/{variableID}/labels/{labelID}
+ summary: Delete a label from a variable
+ tags:
+ - Variables
+related:
+ - title: InfluxDB 3 API client libraries
+ href: /influxdb3/cloud-serverless/reference/client-libraries/v3/
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
diff --git a/content/influxdb3/cloud-serverless/reference/api/_index.md b/content/influxdb3/cloud-serverless/reference/api/_index.md
deleted file mode 100644
index a895050e5..000000000
--- a/content/influxdb3/cloud-serverless/reference/api/_index.md
+++ /dev/null
@@ -1,31 +0,0 @@
----
-title: InfluxDB HTTP API
-description: >
- The InfluxDB HTTP API provides a programmatic interface for interactions with InfluxDB.
- Access the InfluxDB API using the `/api/v2/write` or InfluxDB v1 endpoints.
-menu:
- influxdb3_cloud_serverless:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 104
-influxdb3/cloud-serverless/tags: [api]
----
-
-The InfluxDB HTTP API provides a programmatic interface for interactions with
-{{% product-name %}}, such as writing and querying data.
-
-Access the InfluxDB HTTP API using the `/api/v2/` or InfluxDB v1 endpoints.
-
-## InfluxDB v2 Compatibility API reference documentation
-
-InfluxDB v2 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v2-compatible
-endpoints that work with {{% product-name %}} and with InfluxDB 2.x client
-libraries and third-party integrations.
-
-## InfluxDB v1 Compatibility API reference documentation
-
-InfluxDB v1 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v1-compatible `/write` and `/query` endpoints that work with {{% product-name %}} and with InfluxDB 1.x client libraries and third-party integrations.
diff --git a/content/influxdb3/clustered/management-api/_index.md b/content/influxdb3/clustered/management-api/_index.md
new file mode 100644
index 000000000..6966ade7b
--- /dev/null
+++ b/content/influxdb3/clustered/management-api/_index.md
@@ -0,0 +1,27 @@
+---
+title: InfluxDB HTTP API
+description: >-
+ Use the InfluxDB HTTP API to write data, query data, and manage databases,
+ tables, and tokens.
+weight: 104
+type: api
+articleDataKey: influxdb3-clustered
+articleSection: management-api
+menu:
+ influxdb3_clustered:
+ name: InfluxDB HTTP API
+ identifier: api-reference-influxdb3-clustered-management-api
+ parent: Reference
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
+
+Use the {{% product-name %}} HTTP API to write data, query data, and manage databases, tables, and tokens.
+
+{{< children >}}
diff --git a/content/influxdb3/clustered/management-api/all-endpoints/_index.md b/content/influxdb3/clustered/management-api/all-endpoints/_index.md
new file mode 100644
index 000000000..d475b9d7f
--- /dev/null
+++ b/content/influxdb3/clustered/management-api/all-endpoints/_index.md
@@ -0,0 +1,25 @@
+---
+title: All endpoints
+description: View all API endpoints sorted by path.
+type: api
+layout: all-endpoints
+weight: 999
+isAllEndpoints: true
+articleDataKey: influxdb3-clustered
+articleSection: management-api
+menu:
+ influxdb3_clustered:
+ name: All endpoints
+ identifier: all-endpoints-influxdb3-clustered-management-api
+ parent: InfluxDB HTTP API
+alt_links:
+ core: /influxdb3/core/api/
+ enterprise: /influxdb3/enterprise/api/
+ cloud-serverless: /influxdb3/cloud-serverless/api/
+ cloud-dedicated: /influxdb3/cloud-dedicated/api/
+ clustered: /influxdb3/clustered/api/
+ v2: /influxdb/v2/api/
+ cloud: /influxdb/cloud/api/
+---
+
+All {{% product-name %}} API endpoints, sorted by path.
diff --git a/content/influxdb3/clustered/reference/api/_index.md b/content/influxdb3/clustered/reference/api/_index.md
deleted file mode 100644
index 3259b1437..000000000
--- a/content/influxdb3/clustered/reference/api/_index.md
+++ /dev/null
@@ -1,32 +0,0 @@
----
-title: InfluxDB HTTP API
-description: >
- The InfluxDB HTTP API provides a programmatic interface for interactions with
- InfluxDB, such as writing and querying data.
- Access the InfluxDB API using the `/api/v2/write` or InfluxDB v1 endpoints.
-menu:
- influxdb3_clustered:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 127
-influxdb3/clustered/tags: [api]
----
-
-The InfluxDB HTTP API provides a programmatic interface for interactions with
-{{% product-name %}}, such as writing and querying data.
-
-Access the InfluxDB HTTP API using the `/api/v2/` or InfluxDB v1 endpoints.
-
-## InfluxDB v2 Compatibility API reference documentation
-
-InfluxDB v2 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v2-compatible
-endpoints that work with {{% product-name %}} and with InfluxDB 2.x client
-libraries and third-party integrations.
-
-## InfluxDB v1 Compatibility API reference documentation
-
-InfluxDB v1 API for {{% product-name %}}
-
-The API reference describes requests and responses for InfluxDB v1-compatible `/write` and `/query` endpoints that work with {{% product-name %}} and with InfluxDB 1.x client libraries and third-party integrations.
diff --git a/content/influxdb3/core/reference/api/_index.md b/content/influxdb3/core/reference/api/_index.md
index 6a2200b1e..13724ba97 100644
--- a/content/influxdb3/core/reference/api/_index.md
+++ b/content/influxdb3/core/reference/api/_index.md
@@ -1,20 +1,12 @@
---
title: InfluxDB HTTP API
description: >
- The InfluxDB HTTP API for {{% product-name %}} provides a programmatic interface
- for interactions with InfluxDB,
- including writing, querying, and processing data, and managing an InfluxDB 3
- instance.
-menu:
- influxdb3_core:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 104
-influxdb3/core/tags: [api]
-source: /shared/influxdb3-api-reference/_index.md
+ The InfluxDB HTTP API for InfluxDB 3 Core provides a programmatic interface
+ for interactions with InfluxDB.
+# Redirect to the new location
+aliases:
+ - /influxdb3/core/reference/api/
+redirect: /influxdb3/core/api/
---
-
+This page has moved to [InfluxDB HTTP API](/influxdb3/core/api/).
diff --git a/content/influxdb3/enterprise/reference/api/_index.md b/content/influxdb3/enterprise/reference/api/_index.md
index ea78867f6..a5a831de4 100644
--- a/content/influxdb3/enterprise/reference/api/_index.md
+++ b/content/influxdb3/enterprise/reference/api/_index.md
@@ -1,20 +1,10 @@
---
title: InfluxDB HTTP API
description: >
- The InfluxDB HTTP API for {{% product-name %}} provides a programmatic interface
- for interactions with InfluxDB,
- including writing, querying, and processing data, and managing an InfluxDB 3
- instance.
-menu:
- influxdb3_enterprise:
- parent: Reference
- name: InfluxDB HTTP API
-weight: 104
-influxdb3/enterprise/tags: [api]
-source: /shared/influxdb3-api-reference/_index.md
+ The InfluxDB HTTP API for InfluxDB 3 Enterprise provides a programmatic interface
+ for interactions with InfluxDB.
+# Redirect to the new location
+redirect: /influxdb3/enterprise/api/
---
-
+This page has moved to [InfluxDB HTTP API](/influxdb3/enterprise/api/).
diff --git a/cypress/e2e/content/api-reference.cy.js b/cypress/e2e/content/api-reference.cy.js
index ceeaffeff..a0d50ff78 100644
--- a/cypress/e2e/content/api-reference.cy.js
+++ b/cypress/e2e/content/api-reference.cy.js
@@ -1,78 +1,76 @@
///
+
+/**
+ * API Reference Documentation E2E Tests
+ *
+ * Tests:
+ * 1. API reference pages (link validation, content structure)
+ * 2. 3-column layout with TOC (for InfluxDB 3 Core/Enterprise)
+ * 3. Hugo-native tag page rendering
+ * 4. Related links from OpenAPI x-related → frontmatter → rendered HTML
+ *
+ * Run with:
+ * node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/api-reference.cy.js" content/influxdb3/core/reference/api/_index.md
+ */
+
const fakeGoogleTagManager = {
trackingOptIn: () => {},
- trackingOptOut: () => {}
-}
+ trackingOptOut: () => {},
+};
describe('API reference content', () => {
+ // API section index pages (generated from article data)
const subjects = [
- '/influxdb/cloud/api/',
- '/influxdb/cloud/api/v1/',
- '/influxdb/cloud/api/v1-compatibility/',
- '/influxdb/cloud/api/v2/',
-
- '/influxdb/v2/api/',
- '/influxdb/v2/api/v1/',
- '/influxdb/v2/api/v1-compatibility/',
- '/influxdb/v2/api/v2/',
-
- '/influxdb3/cloud-dedicated/api/',
- '/influxdb3/cloud-dedicated/api/management/',
- '/influxdb3/cloud-dedicated/api/v1/',
- '/influxdb3/cloud-dedicated/api/v1-compatibility/',
- '/influxdb3/cloud-dedicated/api/v2/',
-
- '/influxdb3/cloud-serverless/api/',
- '/influxdb3/cloud-serverless/api/v1/',
- '/influxdb3/cloud-serverless/api/v1-compatibility/',
- '/influxdb3/cloud-serverless/api/v2/',
-
- '/influxdb3/clustered/api/',
- // TODO '/influxdb3/clustered/api/management/',
- '/influxdb3/clustered/api/v1/',
- '/influxdb3/clustered/api/v1-compatibility/',
- '/influxdb3/clustered/api/v2/',
-
'/influxdb3/core/api/',
'/influxdb3/enterprise/api/',
+ '/influxdb3/cloud-dedicated/api/',
+ '/influxdb3/cloud-serverless/api/',
+ '/influxdb3/clustered/api/',
+ '/influxdb/cloud/api/',
+ '/influxdb/v2/api/',
];
-
subjects.forEach((subject) => {
describe(subject, () => {
beforeEach(() => {
- // Intercept and modify the page HTML before it loads
- cy.intercept('GET', '**', (req) => {
- req.continue((res) => {
- if (res.headers['content-type']?.includes('text/html')) {
- // Modify the Kapa widget script attributes
- // Avoid socket errors from fpjs in tests by disabling fingerprinting
- res.body = res.body.replace(
- /data-user-analytics-fingerprint-enabled="true"/,
- 'data-user-analytics-fingerprint-enabled="false"'
- );
- }
- });
- });
+ // Intercept and modify the page HTML before it loads
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ // Modify the Kapa widget script attributes
+ // Avoid socket errors from fpjs in tests by disabling fingerprinting
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
cy.visit(subject);
-
window.fcdsc = fakeGoogleTagManager;
cy.stub(window.fcdsc, 'trackingOptIn').as('trackingOptIn');
cy.stub(window.fcdsc, 'trackingOptOut').as('trackingOptOut');
});
it(`has API info`, function () {
- cy.get('script[data-user-analytics-fingerprint-enabled=false]').should('have.length', 1);
+ cy.get('script[data-user-analytics-fingerprint-enabled=false]').should(
+ 'have.length',
+ 1
+ );
cy.get('h1').first().should('have.length', 1);
- cy.get('[data-role$=description]').should('have.length', 1);
+ // Check for description element (either article--description class or data-role attribute)
+ cy.get('.article--description, [data-role$=description]').should(
+ 'have.length.at.least',
+ 1
+ );
});
it('links back to the version home page', function () {
- cy.get('a.back').contains('Docs')
- .should('have.length', 1)
- .click();
+ cy.get('a.back').contains('Docs').should('have.length', 1).click();
// Path should be the first two segments and trailing slash in $subject
- cy.location('pathname')
- .should('eq', subject.replace(/^(\/[^/]+\/[^/]+\/).*/, '$1'));
+ cy.location('pathname').should(
+ 'eq',
+ subject.replace(/^(\/[^/]+\/[^/]+\/).*/, '$1')
+ );
cy.get('h1').should('have.length', 1);
});
it('contains valid internal links', function () {
@@ -88,8 +86,7 @@ describe('API reference content', () => {
// cy.request doesn't show in your browser's Developer Tools
// because the request comes from Node, not from the browser.
cy.request($a.attr('href')).its('status').should('eq', 200);
- });
-
+ });
});
});
it('contains valid external links', function () {
@@ -109,3 +106,449 @@ describe('API reference content', () => {
});
});
});
+
+/**
+ * API Reference Layout Tests
+ * Tests layout for InfluxDB 3 Core/Enterprise API documentation
+ */
+describe('API reference layout', () => {
+ const layoutSubjects = [
+ '/influxdb3/core/api/write-data/',
+ '/influxdb3/enterprise/api/write-data/',
+ ];
+
+ layoutSubjects.forEach((subject) => {
+ describe(`${subject} layout`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(subject);
+ });
+
+ describe('Layout Structure', () => {
+ it('displays sidebar', () => {
+ cy.get('.sidebar').should('be.visible');
+ });
+
+ it('displays API content area', () => {
+ cy.get('.api-content, .content-wrapper, .article--content').should(
+ 'exist'
+ );
+ });
+
+ it('displays TOC on page', () => {
+ cy.get('.api-toc').should('exist');
+ });
+ });
+
+ describe('Hugo-native renderer', () => {
+ it('renders API operations container', () => {
+ cy.get('.api-hugo-native, .api-operations-section').should('exist');
+ });
+
+ it('renders operation elements', () => {
+ cy.get('.api-operation').should('have.length.at.least', 1);
+ });
+
+ it('operation has method badge and path', () => {
+ cy.get('.api-operation')
+ .first()
+ .within(() => {
+ cy.get('.api-method').should('exist');
+ cy.get('.api-path').should('exist');
+ });
+ });
+ });
+ });
+ });
+});
+
+/**
+ * API Tag Page Tests
+ * Tests Hugo-native tag pages render operations correctly
+ */
+describe('API tag pages', () => {
+ const tagPages = [
+ '/influxdb3/core/api/write-data/',
+ '/influxdb3/core/api/query-data/',
+ '/influxdb3/enterprise/api/write-data/',
+ ];
+
+ tagPages.forEach((page) => {
+ describe(`Tag page ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('displays page title', () => {
+ cy.get('h1').should('exist');
+ });
+
+ it('renders operations section', () => {
+ cy.get('.api-operations, .api-operations-section').should('exist');
+ });
+
+ it('operations have proper structure', () => {
+ cy.get('.api-operation')
+ .first()
+ .within(() => {
+ // Check for operation header with method and path
+ cy.get('.api-operation-header, .api-operation-endpoint').should(
+ 'exist'
+ );
+ cy.get('.api-method').should('exist');
+ cy.get('.api-path').should('exist');
+ });
+ });
+
+ it('TOC contains operation links', () => {
+ cy.get('.api-toc-nav').should('exist');
+ cy.get('.api-toc-link').should('have.length.at.least', 1);
+ });
+
+ it('TOC links have method badges', () => {
+ cy.get('.api-toc-link .api-method').should('have.length.at.least', 1);
+ });
+ });
+ });
+});
+
+/**
+ * API Section Page Structure Tests
+ * Tests that API section pages show only tags (immediate children)
+ */
+describe('API section page structure', () => {
+ const sectionPages = ['/influxdb3/core/api/', '/influxdb3/enterprise/api/'];
+
+ sectionPages.forEach((page) => {
+ describe(`Section page ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('displays page title', () => {
+ cy.get('h1').should('contain', 'InfluxDB HTTP API');
+ });
+
+ it('shows tag pages as children', () => {
+ cy.get('.children-links h3 a').should('have.length.at.least', 5);
+ });
+
+ it('does not show individual operations in content area', () => {
+ // Operations cards should not appear in the main content
+ cy.get('.article--content .api-operation-card').should('not.exist');
+ });
+
+ it('has All endpoints link in navigation', () => {
+ cy.get('.sidebar a').contains('All endpoints').should('exist');
+ });
+ });
+ });
+});
+
+/**
+ * All Endpoints Page Tests
+ * Tests the "All endpoints" page shows all operations
+ */
+describe('All endpoints page', () => {
+ const allEndpointsPages = [
+ '/influxdb3/core/api/all-endpoints/',
+ '/influxdb3/enterprise/api/all-endpoints/',
+ ];
+
+ allEndpointsPages.forEach((page) => {
+ describe(`All endpoints ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('displays page title "All endpoints"', () => {
+ cy.get('h1').should('contain', 'All endpoints');
+ });
+
+ it('shows v3 API section', () => {
+ cy.get('#v3-api').should('exist');
+ });
+
+ it('displays operation cards', () => {
+ cy.get('.api-operation-card').should('have.length.at.least', 10);
+ });
+
+ it('operation cards have method badges', () => {
+ cy.get('.api-operation-card .api-method').should(
+ 'have.length.at.least',
+ 10
+ );
+ });
+
+ it('operation cards have path codes', () => {
+ cy.get('.api-operation-card .api-path').should(
+ 'have.length.at.least',
+ 10
+ );
+ });
+
+ it('operation cards link to tag pages with operation anchors', () => {
+ cy.get('.api-operation-card')
+ .first()
+ .should('have.attr', 'href')
+ .and('match', /\/api\/.*\/#operation\//);
+ });
+
+ it('is accessible from navigation', () => {
+ // Navigate back to section page
+ cy.get('.sidebar a').contains('InfluxDB HTTP API').click();
+ // Then navigate to All endpoints
+ cy.get('.sidebar a').contains('All endpoints').click();
+ cy.url().should('include', '/all-endpoints/');
+ });
+ });
+ });
+});
+
+/**
+ * API Download Button Tests
+ * Tests that each tag page has a download button linking to the correct spec
+ */
+describe('API spec download buttons', () => {
+ const downloadTests = [
+ {
+ page: '/influxdb3/core/api/write-data/',
+ specPath: '/openapi/influxdb3-core.yml',
+ },
+ {
+ page: '/influxdb3/enterprise/api/write-data/',
+ specPath: '/openapi/influxdb3-enterprise.yml',
+ },
+ ];
+
+ downloadTests.forEach(({ page, specPath }) => {
+ describe(`Download button on ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('has a download button', () => {
+ cy.get('.api-spec-download').should('exist');
+ });
+
+ it(`download button links to ${specPath}`, () => {
+ cy.get('.api-spec-download')
+ .should('have.attr', 'href', specPath)
+ .and('have.attr', 'download');
+ });
+ });
+ });
+});
+
+/**
+ * API Code Sample Tests
+ * Tests that inline curl examples render correctly on tag pages
+ */
+describe('API code samples', () => {
+ const tagPages = [
+ '/influxdb3/core/api/write-data/',
+ '/influxdb3/enterprise/api/write-data/',
+ ];
+
+ tagPages.forEach((page) => {
+ describe(`Code samples on ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('each operation has a code sample', () => {
+ cy.get('.api-operation').each(($op) => {
+ cy.wrap($op).find('.api-code-sample').should('have.length', 1);
+ });
+ });
+
+ it('code samples have header and code block', () => {
+ cy.get('.api-code-sample')
+ .first()
+ .within(() => {
+ cy.get('.api-code-sample-header').should(
+ 'contain',
+ 'Example request'
+ );
+ cy.get('.api-code-block code').should('exist');
+ });
+ });
+
+ it('code block contains a curl command', () => {
+ cy.get('.api-code-block code')
+ .first()
+ .invoke('text')
+ .should('match', /curl --request (GET|POST|PUT|PATCH|DELETE)/);
+ });
+
+ it('curl command includes Authorization header', () => {
+ cy.get('.api-code-block code')
+ .first()
+ .invoke('text')
+ .should('include', 'Authorization: Bearer INFLUX_TOKEN');
+ });
+
+ it('POST operations include request body in curl', () => {
+ cy.get('.api-operation[data-method="post"]')
+ .first()
+ .find('.api-code-block code')
+ .invoke('text')
+ .should('include', '--data-raw');
+ });
+
+ it('code samples have Ask AI links', () => {
+ cy.get('.api-code-sample .api-code-ask-ai')
+ .first()
+ .should('have.attr', 'data-query')
+ .and('not.be.empty');
+ });
+ });
+ });
+});
+
+/**
+ * API Client Library Related Link Tests
+ * Tests that InfluxDB 3 tag pages include client library related links
+ */
+describe('API client library related links', () => {
+ const influxdb3Pages = [
+ '/influxdb3/core/api/write-data/',
+ '/influxdb3/enterprise/api/write-data/',
+ ];
+
+ influxdb3Pages.forEach((page) => {
+ describe(`Client library link on ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('includes InfluxDB 3 API client libraries in related links', () => {
+ cy.get('.related ul li a')
+ .filter(':contains("InfluxDB 3 API client libraries")')
+ .should('have.length', 1)
+ .and('have.attr', 'href')
+ .and('match', /\/influxdb3\/\w+\/reference\/client-libraries\/v3\//);
+ });
+ });
+ });
+});
+
+/**
+ * API Related Links Tests
+ * Tests that x-related from OpenAPI specs renders as related links on tag pages
+ */
+describe('API related links', () => {
+ const pagesWithRelated = ['/influxdb3/core/api/write-data/'];
+
+ pagesWithRelated.forEach((page) => {
+ describe(`Related links on ${page}`, () => {
+ beforeEach(() => {
+ cy.intercept('GET', '**', (req) => {
+ req.continue((res) => {
+ if (res.headers['content-type']?.includes('text/html')) {
+ res.body = res.body.replace(
+ /data-user-analytics-fingerprint-enabled="true"/,
+ 'data-user-analytics-fingerprint-enabled="false"'
+ );
+ }
+ });
+ });
+ cy.visit(page);
+ });
+
+ it('displays a related section', () => {
+ cy.get('.related').should('exist');
+ cy.get('.related h4#related').should('contain', 'Related');
+ });
+
+ it('renders related links from x-related as anchor elements', () => {
+ cy.get('.related ul li a').should('have.length.at.least', 2);
+ });
+
+ it('related links have title text and valid href', () => {
+ cy.get('.related ul li a').each(($a) => {
+ // Each link has non-empty text
+ cy.wrap($a).invoke('text').should('not.be.empty');
+ // Each link has an href starting with /
+ cy.wrap($a).should('have.attr', 'href').and('match', /^\//);
+ });
+ });
+
+ it('related links resolve to valid pages', () => {
+ cy.get('.related ul li a').each(($a) => {
+ const href = $a.attr('href');
+ cy.request(href).its('status').should('eq', 200);
+ });
+ });
+ });
+ });
+});
diff --git a/data/products.yml b/data/products.yml
index ec212bc84..406df0398 100644
--- a/data/products.yml
+++ b/data/products.yml
@@ -2,8 +2,8 @@ influxdb3_core:
name: InfluxDB 3 Core
altname: InfluxDB 3 Core
namespace: influxdb3
- content_path: influxdb3/core
- label_group: v3-monolith
+ api_path: /influxdb3/core/api/
+ alt_link_key: core
menu_category: self-managed
versions: [core]
list_order: 2
@@ -40,13 +40,13 @@ influxdb3_enterprise:
name: InfluxDB 3 Enterprise
altname: InfluxDB 3 Enterprise
namespace: influxdb3
- content_path: influxdb3/enterprise
- label_group: v3-monolith
+ api_path: /influxdb3/enterprise/api/
+ alt_link_key: enterprise
menu_category: self-managed
versions: [enterprise]
list_order: 2
latest: enterprise
- latest_patch: 3.8.4
+ latest_patch: 3.8.3
placeholder_host: localhost:8181
limits:
database: 100
@@ -78,8 +78,6 @@ influxdb3_explorer:
name: InfluxDB 3 Explorer
altname: Explorer
namespace: influxdb3_explorer
- content_path: influxdb3/explorer
- label_group: explorer
menu_category: tools
list_order: 1
latest: explorer
@@ -96,8 +94,8 @@ influxdb3_cloud_serverless:
name: InfluxDB Cloud Serverless
altname: InfluxDB Cloud
namespace: influxdb
- content_path: influxdb3/cloud-serverless
- label_group: v3-distributed
+ api_path: /influxdb3/cloud-serverless/api/
+ alt_link_key: cloud-serverless
menu_category: managed
versions: [cloud-serverless]
list_order: 2
@@ -131,8 +129,8 @@ influxdb3_cloud_dedicated:
name: InfluxDB Cloud Dedicated
altname: InfluxDB Cloud
namespace: influxdb
- content_path: influxdb3/cloud-dedicated
- label_group: v3-distributed
+ api_path: /influxdb3/cloud-dedicated/api/
+ alt_link_key: cloud-dedicated
menu_category: managed
versions: [cloud-dedicated]
list_order: 3
@@ -164,8 +162,8 @@ influxdb3_clustered:
name: InfluxDB Clustered
altname: InfluxDB Clustered
namespace: influxdb
- content_path: influxdb3/clustered
- label_group: v3-distributed
+ api_path: /influxdb3/clustered/api/
+ alt_link_key: clustered
menu_category: self-managed
versions: [clustered]
list_order: 3
@@ -200,12 +198,8 @@ influxdb:
name__v1: InfluxDB OSS v1
altname: InfluxDB OSS
namespace: influxdb
- content_path:
- v2: influxdb/v2
- v1: influxdb/v1
- label_group:
- v2: v2
- v1: v1
+ api_path: /influxdb/v2/api/
+ alt_link_key: v2
succeeded_by: influxdb3_core
menu_category: self-managed
list_order: 1
@@ -216,7 +210,7 @@ influxdb:
latest: v2.8
latest_patches:
v2: 2.8.0
- v1: 1.12.3
+ v1: 1.12.2
latest_cli:
v2: 2.7.5
detector_config:
@@ -251,8 +245,8 @@ influxdb_cloud:
name__vcloud: InfluxDB Cloud (TSM)
altname: InfluxDB Cloud
namespace: influxdb
- content_path: influxdb/cloud
- label_group: v2-cloud
+ api_path: /influxdb/cloud/api/
+ alt_link_key: cloud
menu_category: managed
versions: [cloud]
list_order: 1
@@ -282,14 +276,12 @@ influxdb_cloud:
telegraf:
name: Telegraf
namespace: telegraf
- content_path: telegraf
- label_group: telegraf
menu_category: other
list_order: 6
versions: [v1]
- latest: v1.38
+ latest: v1.37
latest_patches:
- v1: 1.38.0
+ v1: 1.37.3
ai_sample_questions:
- How do I configure Telegraf for InfluxDB 3?
- How do I write a custom Telegraf plugin?
@@ -308,8 +300,6 @@ telegraf_controller:
chronograf:
name: Chronograf
namespace: chronograf
- content_path: chronograf
- label_group: chronograf
menu_category: other
list_order: 7
versions: [v1]
@@ -325,8 +315,6 @@ chronograf:
kapacitor:
name: Kapacitor
namespace: kapacitor
- content_path: kapacitor
- label_group: kapacitor
menu_category: other
list_order: 7
versions: [v1]
@@ -342,8 +330,6 @@ kapacitor:
enterprise_influxdb:
name: 'InfluxDB Enterprise v1'
namespace: enterprise_influxdb
- content_path: enterprise_influxdb
- label_group: v1-enterprise
menu_category: self-managed
list_order: 5
versions: [v1]
@@ -398,8 +384,6 @@ influxdb_cloud1:
flux:
name: Flux
namespace: flux
- content_path: flux
- label_group: flux
menu_category: languages
list_order: 8
versions: [v0]
diff --git a/docs/plans/2025-02-06-clustered-cloud-dedicated-api-structure-design.md b/docs/plans/2025-02-06-clustered-cloud-dedicated-api-structure-design.md
new file mode 100644
index 000000000..4ed939b6a
--- /dev/null
+++ b/docs/plans/2025-02-06-clustered-cloud-dedicated-api-structure-design.md
@@ -0,0 +1,154 @@
+# Clustered & Cloud Dedicated API Documentation Structure Design
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Unified API documentation for Clustered and Cloud Dedicated with separate downloadable specs for Data API and Management API.
+
+**Architecture:** Single nav menu combining tags from both API specs, with dual download buttons on landing page and context-aware buttons on tag pages.
+
+**Tech Stack:** Hugo templates, OpenAPI specs, existing API doc generator
+
+***
+
+## Context
+
+Clustered and Cloud Dedicated have two distinct API planes:
+
+- **Data API** - Write and Query endpoints using database tokens
+- **Management API** - Databases, Tables, Tokens endpoints using management tokens
+
+## Design Decisions
+
+### Navigation Structure
+
+Single `/api/` section with combined nav:
+
+```
+InfluxDB HTTP API
+├── Quick start (conceptual)
+├── Authentication (conceptual, covers both token types)
+├── API compatibility (conceptual)
+├── Common parameters (conceptual)
+├── Headers (conceptual)
+├── Response codes (conceptual)
+├── Database tokens (Management API)
+├── Databases (Management API)
+├── Tables (Management API)
+├── Ping (Data API)
+├── Query data (Data API)
+├── Write data (Data API)
+└── All endpoints (combined)
+```
+
+### Download Buttons
+
+**Landing page:** Two buttons side-by-side
+
+- "Download Data API Spec" → `/openapi/influxdb-{product}-v2-data-api.yml`
+- "Download Management API Spec" → `/openapi/influxdb-{product}-management-api.yml`
+
+**Tag pages:** Context-aware single button based on `staticFilePath`
+
+### Authentication Page
+
+Single unified page covering:
+
+- Token types table (Management vs Database)
+- Authentication schemes table (Bearer, Token, Basic, Query string)
+- Which endpoints use which token type
+- Security schemes from OpenAPI spec
+
+### OpenAPI Spec Organization
+
+**`v2/ref.yml` (Data API):**
+
+- Contains all conceptual tags (Quick start, Authentication, etc.)
+- Contains Data API operation tags (Ping, Query data, Write data)
+
+**`management/openapi.yml`:**
+
+- NO CHANGES to source file
+- Contains only operation tags (Database tokens, Databases, Tables)
+
+Generator combines both specs into unified `articles.yml`.
+
+### Cleanup Required
+
+Remove old pages:
+
+- `/content/influxdb3/clustered/api/v2/_index.html`
+- `/content/influxdb3/cloud-dedicated/api/v2/_index.html`
+- `/content/influxdb3/*/api/admin-authentication-management-operations/`
+- `/content/influxdb3/*/api/management-authentication-admin-operations/`
+
+***
+
+## Implementation Tasks
+
+### Task 1: Update Authentication tag in Data API specs
+
+Update `api-docs/influxdb3/clustered/v2/ref.yml` and `api-docs/influxdb3/cloud-dedicated/v2/ref.yml`:
+
+- Revise Authentication tag description to cover both token types
+- Include table of token types and which endpoints use them
+- Keep `showSecuritySchemes: true` for security scheme rendering
+
+### Task 2: Update Quick start tag in Data API specs
+
+Update Quick start in both v2/ref.yml files:
+
+- Cover both Data and Management API getting started flow
+- Show management token creation, then database/token setup, then write/query
+
+### Task 3: Add dual download buttons to API landing page
+
+Modify `layouts/api/list.html` or create partial:
+
+- Detect Clustered/Cloud Dedicated products
+- Show two download buttons on section index pages
+- Style buttons side-by-side
+
+### Task 4: Update tag page download button logic
+
+Modify `layouts/api/single.html` and/or `layouts/api/list.html`:
+
+- Detect API type from `staticFilePath` (contains `management-api` or `v2-data-api`)
+- Show appropriate download button for the API
+
+### Task 5: Remove old v2 HTML pages
+
+Delete:
+
+- `content/influxdb3/clustered/api/v2/`
+- `content/influxdb3/cloud-dedicated/api/v2/`
+
+### Task 6: Remove old authentication directories
+
+Delete leftover directories:
+
+- `content/influxdb3/clustered/api/admin-authentication-management-operations/`
+- `content/influxdb3/clustered/api/management-authentication-admin-operations/`
+- `content/influxdb3/cloud-dedicated/api/admin-authentication-management-operations/`
+- `content/influxdb3/cloud-dedicated/api/management-authentication-admin-operations/`
+
+### Task 7: Regenerate API docs and verify
+
+Run `yarn build:api-docs` and verify:
+
+- Nav shows combined tags from both APIs
+- Authentication page has unified content
+- Download buttons work correctly
+- Old pages are gone
+
+***
+
+## Success Criteria
+
+- [ ] Single Authentication page covers both token types clearly
+- [ ] Landing page shows two download buttons for Clustered/Cloud Dedicated
+- [ ] Tag pages show context-appropriate download button
+- [ ] Nav combines tags from both API specs
+- [ ] Old v2 HTML pages removed
+- [ ] Old duplicate authentication directories removed
+- [ ] `yarn build:api-docs` succeeds
+- [ ] Hugo builds without errors
diff --git a/docs/plans/2026-01-07-api-reference-rapidoc-migration.md b/docs/plans/2026-01-07-api-reference-rapidoc-migration.md
new file mode 100644
index 000000000..9d22a8da0
--- /dev/null
+++ b/docs/plans/2026-01-07-api-reference-rapidoc-migration.md
@@ -0,0 +1,184 @@
+# API Reference RapiDoc Migration Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Migrate all InfluxDB products from Redoc-based API reference to the new RapiDoc-based UI that's already working for influxdb3-core and influxdb3-enterprise.
+
+**Architecture:** The new API reference uses RapiDoc Mini to render OpenAPI specs. The generation script (`api-docs/scripts/generate-openapi-articles.ts`) processes OpenAPI specs and creates Hugo content pages with frontmatter that references spec files. Hugo layouts (`layouts/api/` and `layouts/api-operation/`) render these pages using the RapiDoc component.
+
+**Tech Stack:** TypeScript (generation scripts), Hugo templates, RapiDoc web component, OpenAPI 3.0 specs
+
+***
+
+## Overview
+
+### Products to Migrate
+
+| Product | Status | Spec Location | Target Content Path |
+| ----------------------- | ------- | ----------------------------------------------------------- | ----------------------------------------- |
+| influxdb3-core | ✅ Done | `api-docs/influxdb3/core/v3/ref.yml` | `content/influxdb3/core/api/` |
+| influxdb3-enterprise | ✅ Done | `api-docs/influxdb3/enterprise/v3/ref.yml` | `content/influxdb3/enterprise/api/` |
+| cloud-dedicated | Partial | `api-docs/influxdb3/cloud-dedicated/management/openapi.yml` | `content/influxdb3/cloud-dedicated/api/` |
+| cloud-serverless | Partial | `api-docs/influxdb3/cloud-serverless/v2/ref.yml` | `content/influxdb3/cloud-serverless/api/` |
+| clustered | Partial | `api-docs/influxdb3/clustered/management/openapi.yml` | `content/influxdb3/clustered/api/` |
+| cloud-v2 | Partial | `api-docs/influxdb/cloud/v2/ref.yml` | `content/influxdb/cloud/api/` |
+| oss-v2 | Partial | `api-docs/influxdb/v2/v2/ref.yml` | `content/influxdb/v2/api/` |
+| oss-v1 | Partial | `api-docs/influxdb/v1/v1/ref.yml` | `content/influxdb/v1/api/` |
+| enterprise\_influxdb-v1 | Partial | `api-docs/enterprise_influxdb/v1/v1/ref.yml` | `content/enterprise_influxdb/v1/api/` |
+
+### Key Files
+
+- **Generation script:** `api-docs/scripts/generate-openapi-articles.ts`
+- **Core conversion:** `api-docs/scripts/openapi-paths-to-hugo-data/index.ts`
+- **Hugo layouts:** `layouts/api/`, `layouts/api-operation/`
+- **RapiDoc component:** `assets/js/components/rapidoc-mini.ts`
+- **Styles:** `assets/styles/layouts/_api-layout.scss`
+
+***
+
+**API Tag Page Consolidation Complete**
+
+The API documentation structure has been refactored from individual operation pages to consolidated tag pages:
+
+1. **Before**: Each API operation had its own page (e.g., `/api/v3/configure/distinct_cache/`)
+2. **After**: All operations for a tag are rendered inline on the tag page (e.g., `/api/cache-data/#post-/api/v3/configure/distinct_cache`)
+
+**Key implementation details:**
+
+- Server-side TOC generated from frontmatter `operations` array using Hugo templates
+- `safeURL` filter prevents Hugo from URL-encoding anchor slashes
+- JavaScript `api-toc.ts` detects pre-rendered TOC and preserves it
+- RapiDoc's `scrollToPath()` method handles TOC click navigation to shadow DOM elements
+- `goto-path` attribute initializes RapiDoc to scroll to operation from URL hash on page load
+- `update-route="true"` enables RapiDoc to update URL hash as user navigates
+
+See [API tag pages design](2026-01-21-api-tag-pages-design.md) for link anchor patterns and route information.
+
+## Fix all InfluxDB products
+
+These products already have generated content but may need spec adjustments and testing.
+
+### Task 1.1: Verify API Generation
+
+**Files:**
+
+- Check: `content/influxdb3/cloud-dedicated/api/_index.md`
+- Check: `api-docs/influxdb3/cloud-dedicated/management/openapi.yml`
+- Verify: `static/openapi/influxdb3-cloud-dedicated/`
+
+**Step 1: Check existing generated content**
+
+```bash
+ls -la content/influxdb3/cloud-dedicated/api/
+cat content/influxdb3/cloud-dedicated/api/_index.md
+```
+
+Expected: Should see `_index.md` and subdirectories for each tag.
+
+**Step 2: Verify OpenAPI spec exists and is valid**
+
+```bash
+head -50 api-docs/influxdb3/cloud-dedicated/management/openapi.yml
+```
+
+Expected: Valid OpenAPI 3.x spec with `openapi:`, `info:`, `paths:` sections.
+
+**Step 3: Run generation**
+
+```bash
+yarn build:api-docs
+```
+
+Or for just this product:
+
+```bash
+node api-docs/scripts/dist/generate-openapi-articles.js cloud-dedicated
+```
+
+**Step 4: Start Hugo and verify pages render**
+
+```bash
+npx hugo server --port 1315
+```
+
+Visit the product URL--for example:
+
+Expected: API reference pages render with RapiDoc component showing operations.
+
+**Step 5: Check for console errors**
+
+Open browser DevTools, verify no JavaScript errors related to RapiDoc.
+
+**Step 6: Commit if working**
+
+```bash
+git add content/influxdb3/cloud-dedicated/api/
+git add static/openapi/influxdb3-cloud-dedicated/
+git add data/article-data/influxdb3/cloud-dedicated/
+git commit -m "feat(api): generate cloud-dedicated API reference with RapiDoc"
+```
+
+### How to generate API reference articles
+
+**Step 1: Rebuild TypeScript**
+
+```bash
+cd api-docs/scripts && yarn build
+```
+
+Or from root:
+
+```bash
+tsc --project api-docs/scripts/tsconfig.json
+```
+
+**Step 2: Test compilation succeeded**
+
+```bash
+node api-docs/scripts/dist/generate-openapi-articles.js --help
+```
+
+**Step 3: Commit the config change**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): enable cloud-v2 product config for RapiDoc migration"
+```
+
+***
+
+## Verification Checklist
+
+Before considering migration complete:
+
+- [ ] All product API pages render without errors
+- [ ] RapiDoc "Try It Out" works for each product
+- [ ] Mobile responsive layout works correctly
+- [ ] Navigation menus updated
+- [ ] Old URLs redirect to new locations
+- [ ] E2E tests pass
+- [ ] No console errors in browser DevTools
+- [ ] Links validation passes
+
+***
+
+## Rollback Plan
+
+If issues are found:
+
+1. Revert the product config changes in `generate-openapi-articles.ts`
+2. Remove generated content directories
+3. Restore original navigation files from git history
+
+```bash
+git checkout HEAD~N -- content/influxdb/cloud/reference/api/
+git checkout HEAD~N -- api-docs/scripts/generate-openapi-articles.ts
+```
+
+***
+
+## Notes
+
+- The `useTagBasedGeneration` option creates pages organized by OpenAPI tags (used for influxdb3 products)
+- The path-based generation creates pages organized by API paths (used for v2 products)
+- The `skipParentMenu` option prevents duplicate menu entries when existing reference pages have menus
diff --git a/docs/plans/2026-01-21-api-tag-pages-design.md b/docs/plans/2026-01-21-api-tag-pages-design.md
new file mode 100644
index 000000000..ddf6c6d6a
--- /dev/null
+++ b/docs/plans/2026-01-21-api-tag-pages-design.md
@@ -0,0 +1,145 @@
+# API Tag Pages Design
+
+## Overview
+
+Consolidate API documentation onto tag pages, where each tag page displays all operations for that tag using RapiDoc. This replaces the previous path-based page structure.
+
+## Goals
+
+1. Keep tag-based navigation in the left sidebar
+2. Remove operations as children of tags in the left sidebar
+3. Each tag page displays all RapiDoc renderings for operations in that tag
+4. "On this page" TOC links to Overview and each operation
+5. No frame/internal scrolling - page scrolls naturally as one document
+6. Consistent styling with existing implementation
+7. Clear visual separation between operations
+
+## URL Structure
+
+- **Tag page:** `/influxdb3/core/api/cache-data/`
+- **Operation anchor:** `/influxdb3/core/api/cache-data/#post-/api/v3/configure/distinct_cache`
+
+## RapiDoc Anchor Reference
+
+| Feature | Format/Value |
+| ------------------------------ | ---------------------------------------------------------------------------------- |
+| Anchor format | `#{method}-{path}` (e.g., `#post-/api/v3/configure/distinct_cache`) |
+| `goto-path` attribute | Navigate to operation on load: `goto-path="post-/api/v3/configure/distinct_cache"` |
+| `scrollToPath(path)` method | Programmatic navigation |
+| `update-route` (default: true) | Updates URL hash as user scrolls |
+| `route-prefix` (default: #) | Hash prefix for routes |
+| Built-in anchors | `#overview`, `#servers`, `#auth`, `#operations-top` |
+
+## Page Layout
+
+```
+┌─────────────────────────────────────────────────────────────┐
+│ Header / Top Nav │
+├──────────┬─────────────────────────────────────┬────────────┤
+│ │ │ │
+│ Left │ Main Content │ On This │
+│ Sidebar │ │ Page TOC │
+│ (nav) │ ┌─────────────────────────────┐ │ │
+│ │ │ Cache data
│ │ Overview │
+│ │ │ Tag description...
│ │ POST ... │
+│ │ └─────────────────────────────┘ │ DELETE .. │
+│ │ │ POST ... │
+│ │ ┌─────────────────────────────┐ │ DELETE .. │
+│ │ │ RapiDoc (full height, │ │ │
+│ │ │ no internal scroll) │ │ │
+│ │ │ │ │ │
+│ │ │ - POST distinct_cache │ │ │
+│ │ │ - DELETE distinct_cache │ │ │
+│ │ │ - POST last_cache │ │ │
+│ │ │ - DELETE last_cache │ │ │
+│ │ │ │ │ │
+│ │ └─────────────────────────────┘ │ │
+│ │ │ │
+├──────────┴─────────────────────────────────────┴────────────┤
+│ Footer │
+└─────────────────────────────────────────────────────────────┘
+```
+
+## RapiDoc Configuration
+
+- `render-style="read"` - Linear document flow (no internal scrolling)
+- `spec-url` - Tag-specific spec (e.g., `/openapi/influxdb3-core/tags/tags/influxdb3-core-cache-data.yaml`)
+- `update-route="true"` - URL updates as user navigates (default)
+- No fixed height on container - expands to fit content
+
+## "On This Page" TOC
+
+Generated server-side from frontmatter `operations` array:
+
+```yaml
+operations:
+ - operationId: PostConfigureDistinctCache
+ method: POST
+ path: /api/v3/configure/distinct_cache
+ summary: Create distinct cache
+ - operationId: DeleteConfigureDistinctCache
+ method: DELETE
+ path: /api/v3/configure/distinct_cache
+ summary: Delete distinct cache
+```
+
+TOC output:
+
+```
+ON THIS PAGE
+- Overview
+- POST /api/v3/configure/distinct_cache
+- DELETE /api/v3/configure/distinct_cache
+- POST /api/v3/configure/last_cache
+- DELETE /api/v3/configure/last_cache
+```
+
+Links use `#{method}-{path}` format matching RapiDoc anchors.
+
+## Hash Navigation
+
+1. On page load, JS reads `window.location.hash`
+2. If hash present, set RapiDoc's `goto-path` attribute (without the `#`)
+3. RapiDoc's default `update-route=true` updates URL as user scrolls
+4. Native URL sharing works
+
+## Files to Modify
+
+### Layouts
+
+- `layouts/api/list.html` - Embed RapiDoc instead of operation cards grid
+- `layouts/partials/api/rapidoc-tag.html` - New partial for tag-level RapiDoc
+
+### JavaScript
+
+- `assets/js/components/rapidoc-mini.ts` - Add hash-based `goto-path` initialization
+
+### Remove/Deprecate
+
+- `layouts/api-path/path.html` - Path page layout
+- `layouts/partials/api/rapidoc-path.html` - Path partial
+- Generated path pages in `content/influxdb3/*/api/v*/`
+
+### Keep
+
+- Tag-specific spec files (`static/openapi/influxdb3-core/tags/tags/`)
+- Generation script for tag pages and article data
+- All endpoints page
+
+### Generation Script
+
+- Remove `generatePathPages()` function
+- Keep tag page generation
+- Ensure frontmatter `operations` array is complete for TOC
+
+## Development Scope
+
+Focus on `influxdb3/core` first, then migrate other products.
+
+## Testing
+
+- Verify tag pages load with all operations rendered
+- Test hash navigation (direct URL, TOC clicks, browser back/forward)
+- Verify no internal scrolling - page flows naturally
+- Check visual separation between operations
+- Test "On this page" TOC links
diff --git a/docs/plans/2026-02-04-api-link-migration-design.md b/docs/plans/2026-02-04-api-link-migration-design.md
new file mode 100644
index 000000000..4927e44b5
--- /dev/null
+++ b/docs/plans/2026-02-04-api-link-migration-design.md
@@ -0,0 +1,174 @@
+# API Link Migration: Redoc to RapiDoc Anchors
+
+## Overview
+
+Migrate all internal API operation links from Redoc's `#operation/{operationId}` format to RapiDoc's native `#{method}-{path}` format.
+
+## Background
+
+The RapiDoc migration changes how anchor links work for API operations:
+
+| Source | Pattern | Example |
+|--------|---------|---------|
+| **Redoc (old)** | `#operation/{operationId}` | `#operation/PostTasks` |
+| **RapiDoc (new)** | `#{method}-{path}` | `#post-/api/v2/tasks` |
+
+**Scope:** 237 links across 111 content files use the Redoc pattern.
+
+**Constraint:** Don't modify source OpenAPI specs—transformation happens at the link level only.
+
+## Goals
+
+1. **Prevent 404s** for external links to API pages (base URL stability)
+2. **Clean migration** of all internal links to RapiDoc's native format
+3. **Validation** via link-checker after migration
+
+## Non-Goals
+
+- Backward compatibility for fragment identifiers (URL fragments are client-side only; server redirects can't translate them)
+- External links with old `#operation/` fragments will land on the correct page but won't auto-scroll
+
+## URL Structure
+
+**API page URLs remain stable:**
+- `/influxdb/cloud/api/` — All endpoints page
+- `/influxdb3/core/api/` — All endpoints page
+- `/influxdb3/core/api/{tag-name}/` — Tag page
+
+**Anchor format changes:**
+- Old: `/influxdb/cloud/api/#operation/PostTasks`
+- New: `/influxdb/cloud/api/#post-/api/v2/tasks`
+
+## RapiDoc Anchor Format
+
+RapiDoc uses `#{method}-{path}` with these conventions:
+
+- Method is lowercase: `post`, `get`, `delete`, `put`, `patch`
+- Path parameters `{param}` become `-param-`: `/tasks/{taskID}` → `/tasks/-taskID-`
+- Slashes in fragments are valid per RFC 3986
+
+**Examples:**
+```
+#get-/api/v2/tasks
+#post-/api/v2/write
+#delete-/api/v2/tasks/-taskID-
+#get-/api/v2/tasks/-taskID-/runs/-runID-
+```
+
+## Migration Script Design
+
+### Location
+
+`helper-scripts/migrate-api-links.js` (one-time migration tool, plain JS)
+
+### Algorithm
+
+**Step 1: Build lookup table from OpenAPI specs**
+
+Key by product to handle duplicate operationIds across specs:
+
+```json
+{
+ "influxdb3/cloud-dedicated": {
+ "PostWrite": "post-/api/v2/write",
+ "GetDatabaseTokens": "get-/api/v0/accounts/-accountId-/clusters/-clusterId-/tokens"
+ },
+ "influxdb3/core": {
+ "PostWrite": "post-/api/v3/write"
+ },
+ "influxdb/cloud": {
+ "PostTasks": "post-/api/v2/tasks",
+ "GetTasksID": "get-/api/v2/tasks/-taskID-"
+ }
+}
+```
+
+**Step 2: Scan and transform content files**
+
+```
+For each .md file in content/:
+ Find all patterns: #operation/(\w+)
+ Extract product from link URL path
+ Look up operationId in product's mapping
+ Replace with RapiDoc anchor format
+ Flag unmapped operationIds for manual review
+```
+
+**Step 3: Report**
+
+- Files modified
+- Links updated (count)
+- Unmapped operationIds (manual review needed)
+- Dry-run mode available
+
+### Edge Cases
+
+| Case | Example | Handling |
+|------|---------|----------|
+| Path parameters | `{taskID}` | Replace with `-taskID-` in anchor |
+| Multiple params | `/tasks/{taskID}/runs/{runID}` | Replace all params |
+| Missing operationId | Path exists but no operationId in spec | Flag for manual review |
+| Deprecated operations | Link to removed endpoint | Flag as potentially broken |
+
+### Usage
+
+```bash
+# Dry-run (report only, no changes)
+node helper-scripts/migrate-api-links.js --dry-run
+
+# Execute migration
+node helper-scripts/migrate-api-links.js
+
+# Review changes
+git diff content/
+```
+
+## Validation
+
+### Pre-migration
+
+Verify API page URLs are stable:
+- Check `_index.md` files have `aliases:` if paths changed
+- Confirm no 404s for existing API base paths
+
+### Post-migration
+
+```bash
+# Build site
+npx hugo --quiet
+
+# Run link-checker on full site
+link-checker check public/
+```
+
+## Rollback
+
+Git provides easy rollback:
+
+```bash
+git checkout -- content/
+```
+
+## Files to Create/Modify
+
+### New Files
+
+- `helper-scripts/migrate-api-links.js` — Migration script
+
+### Modified Files
+
+- ~111 content files containing API operation links
+
+## Testing Checklist
+
+- [ ] Dry-run reports expected changes
+- [ ] All operationIds map successfully (or flagged for review)
+- [ ] Links transform to correct RapiDoc format
+- [ ] Hugo build succeeds after migration
+- [ ] Link-checker passes on full site
+- [ ] Spot-check: anchors navigate to correct operations in browser
+
+## Related Documents
+
+- [API Tag Pages Design](2026-01-21-api-tag-pages-design.md)
+- [API Reference RapiDoc Migration Plan](2026-01-07-api-reference-rapidoc-migration.md)
diff --git a/docs/plans/2026-02-04-api-link-migration-implementation.md b/docs/plans/2026-02-04-api-link-migration-implementation.md
new file mode 100644
index 000000000..e8f0d2888
--- /dev/null
+++ b/docs/plans/2026-02-04-api-link-migration-implementation.md
@@ -0,0 +1,605 @@
+# API Link Migration Implementation Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Migrate all 237 internal API links from Redoc `#operation/{operationId}` format to RapiDoc `#{method}-{path}` format.
+
+**Architecture:** One-time Node.js script that (1) parses OpenAPI specs to build operationId→anchor mapping, (2) scans content files for `#operation/` links, (3) replaces with RapiDoc anchors using the mapping.
+
+**Tech Stack:** Node.js, js-yaml (already in dependencies), glob (already in dependencies)
+
+---
+
+## Spec Files → Product URL Mapping
+
+| Spec File | Product URL Prefix |
+|-----------|-------------------|
+| `api-docs/influxdb/cloud/v2/ref.yml` | `/influxdb/cloud/api/` |
+| `api-docs/influxdb/v2/v2/ref.yml` | `/influxdb/v2/api/` |
+| `api-docs/influxdb/v1/v1/ref.yml` | `/influxdb/v1/api/` |
+| `api-docs/enterprise_influxdb/v1/v1/ref.yml` | `/enterprise_influxdb/v1/api/` |
+| `api-docs/influxdb3/core/v3/ref.yml` | `/influxdb3/core/api/` |
+| `api-docs/influxdb3/enterprise/v3/ref.yml` | `/influxdb3/enterprise/api/` |
+| `api-docs/influxdb3/cloud-dedicated/v2/ref.yml` | `/influxdb3/cloud-dedicated/api/` |
+| `api-docs/influxdb3/cloud-dedicated/management/openapi.yml` | `/influxdb3/cloud-dedicated/api/management/` |
+| `api-docs/influxdb3/cloud-serverless/v2/ref.yml` | `/influxdb3/cloud-serverless/api/` |
+| `api-docs/influxdb3/clustered/v2/ref.yml` | `/influxdb3/clustered/api/` |
+| `api-docs/influxdb3/clustered/management/openapi.yml` | `/influxdb3/clustered/api/management/` |
+
+---
+
+## Task 1: Create Migration Script Skeleton
+
+**Files:**
+- Create: `helper-scripts/migrate-api-links.js`
+
+**Step 1: Create the script with CLI setup**
+
+```javascript
+#!/usr/bin/env node
+/**
+ * migrate-api-links.js
+ *
+ * One-time migration script to convert Redoc API links to RapiDoc format.
+ *
+ * Usage:
+ * node helper-scripts/migrate-api-links.js --dry-run # Preview changes
+ * node helper-scripts/migrate-api-links.js # Execute migration
+ */
+
+const fs = require('fs');
+const path = require('path');
+const yaml = require('js-yaml');
+const { glob } = require('glob');
+
+// CLI arguments
+const args = process.argv.slice(2);
+const DRY_RUN = args.includes('--dry-run');
+const VERBOSE = args.includes('--verbose');
+
+// Paths
+const ROOT_DIR = path.resolve(__dirname, '..');
+const CONTENT_DIR = path.join(ROOT_DIR, 'content');
+const API_DOCS_DIR = path.join(ROOT_DIR, 'api-docs');
+
+// Spec file → product URL mapping
+const SPEC_MAPPINGS = [
+ { spec: 'influxdb/cloud/v2/ref.yml', urlPrefix: '/influxdb/cloud/api/' },
+ { spec: 'influxdb/v2/v2/ref.yml', urlPrefix: '/influxdb/v2/api/' },
+ { spec: 'influxdb/v1/v1/ref.yml', urlPrefix: '/influxdb/v1/api/' },
+ { spec: 'enterprise_influxdb/v1/v1/ref.yml', urlPrefix: '/enterprise_influxdb/v1/api/' },
+ { spec: 'influxdb3/core/v3/ref.yml', urlPrefix: '/influxdb3/core/api/' },
+ { spec: 'influxdb3/enterprise/v3/ref.yml', urlPrefix: '/influxdb3/enterprise/api/' },
+ { spec: 'influxdb3/cloud-dedicated/v2/ref.yml', urlPrefix: '/influxdb3/cloud-dedicated/api/' },
+ { spec: 'influxdb3/cloud-dedicated/management/openapi.yml', urlPrefix: '/influxdb3/cloud-dedicated/api/management/' },
+ { spec: 'influxdb3/cloud-serverless/v2/ref.yml', urlPrefix: '/influxdb3/cloud-serverless/api/' },
+ { spec: 'influxdb3/clustered/v2/ref.yml', urlPrefix: '/influxdb3/clustered/api/' },
+ { spec: 'influxdb3/clustered/management/openapi.yml', urlPrefix: '/influxdb3/clustered/api/management/' },
+];
+
+console.log(`API Link Migration Script`);
+console.log(`Mode: ${DRY_RUN ? 'DRY RUN (no changes)' : 'EXECUTE'}\n`);
+```
+
+**Step 2: Make it executable and test**
+
+Run:
+```bash
+chmod +x helper-scripts/migrate-api-links.js
+node helper-scripts/migrate-api-links.js --dry-run
+```
+
+Expected: Script runs and prints header without errors.
+
+**Step 3: Commit**
+
+```bash
+git add helper-scripts/migrate-api-links.js
+git commit -m "feat(api): add migration script skeleton"
+```
+
+---
+
+## Task 2: Build OperationId Lookup Table
+
+**Files:**
+- Modify: `helper-scripts/migrate-api-links.js`
+
+**Step 1: Add function to parse spec and extract operationIds**
+
+Add after the SPEC_MAPPINGS constant:
+
+```javascript
+/**
+ * Convert path parameters from {param} to -param- (RapiDoc format)
+ */
+function convertPathParams(path) {
+ return path.replace(/\{([^}]+)\}/g, '-$1-');
+}
+
+/**
+ * Build RapiDoc anchor from method and path
+ * Format: {method}-{path} with {param} → -param-
+ */
+function buildAnchor(method, pathStr) {
+ const convertedPath = convertPathParams(pathStr);
+ return `${method.toLowerCase()}-${convertedPath}`;
+}
+
+/**
+ * Parse OpenAPI spec and extract operationId → anchor mapping
+ */
+function parseSpec(specPath) {
+ const mapping = {};
+
+ try {
+ const content = fs.readFileSync(specPath, 'utf8');
+ const spec = yaml.load(content);
+
+ if (!spec.paths) {
+ console.warn(` Warning: No paths in ${specPath}`);
+ return mapping;
+ }
+
+ for (const [pathStr, pathItem] of Object.entries(spec.paths)) {
+ const methods = ['get', 'post', 'put', 'patch', 'delete', 'options', 'head'];
+
+ for (const method of methods) {
+ const operation = pathItem[method];
+ if (operation && operation.operationId) {
+ const anchor = buildAnchor(method, pathStr);
+ mapping[operation.operationId] = anchor;
+
+ if (VERBOSE) {
+ console.log(` ${operation.operationId} → #${anchor}`);
+ }
+ }
+ }
+ }
+ } catch (error) {
+ console.error(` Error parsing ${specPath}: ${error.message}`);
+ }
+
+ return mapping;
+}
+
+/**
+ * Build complete lookup table from all specs
+ * Returns: { urlPrefix: { operationId: anchor } }
+ */
+function buildLookupTable() {
+ const lookup = {};
+
+ console.log('Building operationId lookup table...\n');
+
+ for (const { spec, urlPrefix } of SPEC_MAPPINGS) {
+ const specPath = path.join(API_DOCS_DIR, spec);
+
+ if (!fs.existsSync(specPath)) {
+ console.warn(` Skipping missing spec: ${spec}`);
+ continue;
+ }
+
+ console.log(` Processing: ${spec}`);
+ const mapping = parseSpec(specPath);
+ lookup[urlPrefix] = mapping;
+ console.log(` Found ${Object.keys(mapping).length} operations`);
+ }
+
+ console.log('');
+ return lookup;
+}
+
+// Test: Build and display lookup table
+const lookupTable = buildLookupTable();
+console.log('Lookup table built successfully.\n');
+```
+
+**Step 2: Test lookup table generation**
+
+Run:
+```bash
+node helper-scripts/migrate-api-links.js --dry-run --verbose 2>&1 | head -50
+```
+
+Expected: See operationId mappings printed for each spec.
+
+**Step 3: Commit**
+
+```bash
+git add helper-scripts/migrate-api-links.js
+git commit -m "feat(api): add operationId lookup table generation"
+```
+
+---
+
+## Task 3: Add Content File Scanner
+
+**Files:**
+- Modify: `helper-scripts/migrate-api-links.js`
+
+**Step 1: Add function to find and parse links**
+
+Add after buildLookupTable function:
+
+```javascript
+/**
+ * Find all #operation/ links in a file
+ * Returns array of { match, operationId, urlPath, fullUrl }
+ */
+function findOperationLinks(content) {
+ const links = [];
+ // Match patterns like: /influxdb/cloud/api/#operation/PostTasks
+ // or /influxdb3/cloud-dedicated/api/management/#operation/CreateDatabaseToken
+ const regex = /(\/[a-z0-9_/-]+\/api(?:\/management)?(?:\/[a-z0-9-]*)?\/)#operation\/(\w+)/g;
+
+ let match;
+ while ((match = regex.exec(content)) !== null) {
+ links.push({
+ match: match[0],
+ urlPath: match[1],
+ operationId: match[2],
+ });
+ }
+
+ return links;
+}
+
+/**
+ * Find the best matching URL prefix for a given URL path
+ */
+function findUrlPrefix(urlPath, lookup) {
+ // Sort by length descending to match most specific first
+ const prefixes = Object.keys(lookup).sort((a, b) => b.length - a.length);
+
+ for (const prefix of prefixes) {
+ if (urlPath.startsWith(prefix) || urlPath === prefix.slice(0, -1)) {
+ return prefix;
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Scan content directory for files with #operation/ links
+ */
+async function scanContentFiles(lookup) {
+ console.log('Scanning content files for #operation/ links...\n');
+
+ const files = await glob('**/*.md', { cwd: CONTENT_DIR });
+ const results = {
+ filesWithLinks: [],
+ totalLinks: 0,
+ unmapped: [],
+ };
+
+ for (const file of files) {
+ const filePath = path.join(CONTENT_DIR, file);
+ const content = fs.readFileSync(filePath, 'utf8');
+ const links = findOperationLinks(content);
+
+ if (links.length > 0) {
+ const fileResult = {
+ file,
+ links: [],
+ };
+
+ for (const link of links) {
+ const urlPrefix = findUrlPrefix(link.urlPath, lookup);
+
+ if (!urlPrefix) {
+ results.unmapped.push({ file, ...link, reason: 'No matching URL prefix' });
+ continue;
+ }
+
+ const productLookup = lookup[urlPrefix];
+ const anchor = productLookup[link.operationId];
+
+ if (!anchor) {
+ results.unmapped.push({ file, ...link, reason: 'OperationId not found in spec' });
+ continue;
+ }
+
+ fileResult.links.push({
+ ...link,
+ urlPrefix,
+ newAnchor: anchor,
+ oldLink: `${link.urlPath}#operation/${link.operationId}`,
+ newLink: `${link.urlPath}#${anchor}`,
+ });
+ }
+
+ if (fileResult.links.length > 0) {
+ results.filesWithLinks.push(fileResult);
+ results.totalLinks += fileResult.links.length;
+ }
+ }
+ }
+
+ return results;
+}
+```
+
+**Step 2: Add main execution and reporting**
+
+Replace the test code at the bottom with:
+
+```javascript
+async function main() {
+ // Build lookup table
+ const lookupTable = buildLookupTable();
+
+ // Scan content files
+ const results = await scanContentFiles(lookupTable);
+
+ // Report findings
+ console.log('=== SCAN RESULTS ===\n');
+ console.log(`Files with links: ${results.filesWithLinks.length}`);
+ console.log(`Total links to migrate: ${results.totalLinks}`);
+ console.log(`Unmapped links: ${results.unmapped.length}\n`);
+
+ if (VERBOSE && results.filesWithLinks.length > 0) {
+ console.log('Links to migrate:');
+ for (const { file, links } of results.filesWithLinks) {
+ console.log(`\n ${file}:`);
+ for (const link of links) {
+ console.log(` ${link.oldLink}`);
+ console.log(` → ${link.newLink}`);
+ }
+ }
+ }
+
+ if (results.unmapped.length > 0) {
+ console.log('\n=== UNMAPPED LINKS (require manual review) ===\n');
+ for (const item of results.unmapped) {
+ console.log(` ${item.file}:`);
+ console.log(` ${item.match}`);
+ console.log(` Reason: ${item.reason}\n`);
+ }
+ }
+
+ if (DRY_RUN) {
+ console.log('\n[DRY RUN] No files modified. Run without --dry-run to apply changes.');
+ }
+}
+
+main().catch(console.error);
+```
+
+**Step 3: Test scanner**
+
+Run:
+```bash
+node helper-scripts/migrate-api-links.js --dry-run
+```
+
+Expected: See count of files and links found, plus any unmapped links.
+
+**Step 4: Commit**
+
+```bash
+git add helper-scripts/migrate-api-links.js
+git commit -m "feat(api): add content file scanner for operation links"
+```
+
+---
+
+## Task 4: Add Link Replacement Logic
+
+**Files:**
+- Modify: `helper-scripts/migrate-api-links.js`
+
+**Step 1: Add replacement function**
+
+Add before the main function:
+
+```javascript
+/**
+ * Replace operation links in a file
+ * Returns the modified content
+ */
+function replaceLinks(content, links) {
+ let modified = content;
+
+ for (const link of links) {
+ // Replace all occurrences of this specific link
+ modified = modified.split(link.oldLink).join(link.newLink);
+ }
+
+ return modified;
+}
+
+/**
+ * Apply migrations to files
+ */
+async function applyMigrations(results) {
+ console.log('\n=== APPLYING MIGRATIONS ===\n');
+
+ let filesModified = 0;
+ let linksReplaced = 0;
+
+ for (const { file, links } of results.filesWithLinks) {
+ const filePath = path.join(CONTENT_DIR, file);
+ const originalContent = fs.readFileSync(filePath, 'utf8');
+ const modifiedContent = replaceLinks(originalContent, links);
+
+ if (originalContent !== modifiedContent) {
+ fs.writeFileSync(filePath, modifiedContent, 'utf8');
+ filesModified++;
+ linksReplaced += links.length;
+ console.log(` ✓ ${file} (${links.length} links)`);
+ }
+ }
+
+ console.log(`\nMigration complete: ${filesModified} files modified, ${linksReplaced} links replaced.`);
+}
+```
+
+**Step 2: Update main function to apply changes**
+
+Update the main function to call applyMigrations when not in dry-run mode:
+
+```javascript
+async function main() {
+ // Build lookup table
+ const lookupTable = buildLookupTable();
+
+ // Scan content files
+ const results = await scanContentFiles(lookupTable);
+
+ // Report findings
+ console.log('=== SCAN RESULTS ===\n');
+ console.log(`Files with links: ${results.filesWithLinks.length}`);
+ console.log(`Total links to migrate: ${results.totalLinks}`);
+ console.log(`Unmapped links: ${results.unmapped.length}\n`);
+
+ if (VERBOSE && results.filesWithLinks.length > 0) {
+ console.log('Links to migrate:');
+ for (const { file, links } of results.filesWithLinks) {
+ console.log(`\n ${file}:`);
+ for (const link of links) {
+ console.log(` ${link.oldLink}`);
+ console.log(` → ${link.newLink}`);
+ }
+ }
+ }
+
+ if (results.unmapped.length > 0) {
+ console.log('\n=== UNMAPPED LINKS (require manual review) ===\n');
+ for (const item of results.unmapped) {
+ console.log(` ${item.file}:`);
+ console.log(` ${item.match}`);
+ console.log(` Reason: ${item.reason}\n`);
+ }
+ }
+
+ // Apply migrations if not dry-run
+ if (DRY_RUN) {
+ console.log('\n[DRY RUN] No files modified. Run without --dry-run to apply changes.');
+ } else if (results.filesWithLinks.length > 0) {
+ await applyMigrations(results);
+ } else {
+ console.log('\nNo links to migrate.');
+ }
+}
+
+main().catch(console.error);
+```
+
+**Step 3: Test dry-run shows expected changes**
+
+Run:
+```bash
+node helper-scripts/migrate-api-links.js --dry-run --verbose 2>&1 | head -100
+```
+
+Expected: See specific link transformations listed.
+
+**Step 4: Commit script completion**
+
+```bash
+git add helper-scripts/migrate-api-links.js
+git commit -m "feat(api): complete migration script with replacement logic"
+```
+
+---
+
+## Task 5: Execute Migration
+
+**Step 1: Final dry-run review**
+
+Run:
+```bash
+node helper-scripts/migrate-api-links.js --dry-run
+```
+
+Review the output. Verify:
+- Link count matches expectations (~237 links)
+- No critical unmapped links
+- Transformations look correct
+
+**Step 2: Execute migration**
+
+Run:
+```bash
+node helper-scripts/migrate-api-links.js
+```
+
+Expected: Files modified, links replaced.
+
+**Step 3: Review changes**
+
+Run:
+```bash
+git diff content/ | head -200
+```
+
+Verify transformations look correct (spot check a few).
+
+**Step 4: Commit migrated content**
+
+```bash
+git add content/
+git commit -m "refactor(api): migrate operation links to RapiDoc anchor format
+
+Migrated ~237 links from #operation/{operationId} to #{method}-{path} format
+for RapiDoc compatibility."
+```
+
+---
+
+## Task 6: Validate with Link-Checker
+
+**Step 1: Build Hugo site**
+
+Run:
+```bash
+npx hugo --quiet
+```
+
+Expected: Build succeeds without errors.
+
+**Step 2: Run link-checker**
+
+Run:
+```bash
+link-checker check public/
+```
+
+Or if link-checker isn't installed globally:
+```bash
+# Map changed content files to HTML and check
+git diff --name-only HEAD~1 HEAD | grep '\.md$' | head -20 | \
+ xargs -I {} link-checker map {} | \
+ xargs link-checker check
+```
+
+Expected: No broken links related to API anchors.
+
+**Step 3: Manual spot-check in browser**
+
+1. Start Hugo server: `npx hugo server`
+2. Visit a page with migrated links
+3. Click API links and verify they navigate to correct operations
+
+**Step 4: Final commit if any fixes needed**
+
+If link-checker found issues, fix and commit:
+```bash
+git add content/
+git commit -m "fix(api): correct link migration issues found by link-checker"
+```
+
+---
+
+## Summary
+
+| Task | Description | Output |
+|------|-------------|--------|
+| 1 | Script skeleton | `helper-scripts/migrate-api-links.js` |
+| 2 | Lookup table generation | operationId → anchor mapping |
+| 3 | Content file scanner | Find all `#operation/` links |
+| 4 | Replacement logic | Transform links in place |
+| 5 | Execute migration | ~237 links migrated |
+| 6 | Validate | Link-checker passes |
diff --git a/docs/plans/2026-02-04-v1-api-deduplication-design.md b/docs/plans/2026-02-04-v1-api-deduplication-design.md
new file mode 100644
index 000000000..4fb66b9b3
--- /dev/null
+++ b/docs/plans/2026-02-04-v1-api-deduplication-design.md
@@ -0,0 +1,93 @@
+# InfluxDB v1 API Consistency Design
+
+**Date:** 2026-02-04
+**Goal:** Make InfluxDB v1 API specs consistent with other products by using the same Redocly-based overlay approach.
+
+## Current State
+
+- `api-docs/influxdb/v1/v1/ref.yml` - Complete standalone spec (OSS)
+- `api-docs/enterprise_influxdb/v1/v1/ref.yml` - Complete standalone spec (Enterprise)
+- Not using Redocly decorators or content overlays
+- Not integrated with `getswagger.sh`
+
+## Target State
+
+- Both v1 products use `.config.yml` and `content/` overlays like other products
+- Integrated with `getswagger.sh` and Redocly decorator pipeline
+- Remove unused tag-groups decorator (not used by RapiDoc)
+
+## Design Decisions
+
+1. **Keep both specs as complete, standalone files** - Accept duplication for simplicity
+2. **Use overlays for info and servers only** - Paths stay in each `ref.yml`
+3. **Remove tag-groups entirely** - Not used by RapiDoc UI
+
+## Implementation
+
+### 1. Directory Structure
+
+```
+api-docs/
+ influxdb/
+ v1/
+ .config.yml # Redocly config
+ v1/
+ content/
+ info.yml # OSS info overlay
+ servers.yml # OSS servers overlay
+ ref.yml # Complete OSS spec (exists)
+ enterprise_influxdb/
+ v1/
+ .config.yml # Redocly config
+ v1/
+ content/
+ info.yml # Enterprise info overlay
+ servers.yml # Enterprise servers overlay
+ ref.yml # Complete Enterprise spec (exists)
+```
+
+### 2. Redocly Decorator Changes
+
+**Remove (unused with RapiDoc):**
+
+- `openapi/plugins/decorators/tags/set-tag-groups.cjs`
+- `tag-groups.yml` loading from `docs-content.cjs`
+- `set-tag-groups` references in `docs-plugin.cjs`
+- All `content/tag-groups.yml` files across products
+
+**Keep:**
+
+- `set-info.cjs` - merges info.yml overlay
+- `set-servers.cjs` - merges servers.yml overlay
+- `replace-shortcodes.cjs` - handles doc URL placeholders
+
+### 3. getswagger.sh Changes
+
+Add functions:
+
+```bash
+function updateOSSV1 {
+ postProcess influxdb/v1/v1/ref.yml 'influxdb/v1/.config.yml' 'v1@1'
+}
+
+function updateEnterpriseV1 {
+ postProcess enterprise_influxdb/v1/v1/ref.yml 'enterprise_influxdb/v1/.config.yml' 'v1@1'
+}
+```
+
+## Tasks
+
+1. [x] Create `influxdb/v1/.config.yml`
+2. [x] Create `influxdb/v1/v1/content/info.yml`
+3. [x] Create `influxdb/v1/v1/content/servers.yml`
+4. [x] Create `enterprise_influxdb/v1/.config.yml`
+5. [x] Create `enterprise_influxdb/v1/v1/content/info.yml`
+6. [x] Create `enterprise_influxdb/v1/v1/content/servers.yml`
+7. [x] Remove tag-groups decorator and all tag-groups.yml files
+8. [x] Add `updateOSSV1()` and `updateEnterpriseV1()` to getswagger.sh
+9. [x] Test: Run getswagger.sh for both v1 products
+10. [x] Test: Verify API pages render correctly
+
+## Completed: 2026-02-04
+
+All tasks completed successfully. The v1 products now use the same Redocly overlay pattern as other products.
diff --git a/docs/plans/2026-02-13-hugo-native-api-migration.md b/docs/plans/2026-02-13-hugo-native-api-migration.md
new file mode 100644
index 000000000..99bb7616a
--- /dev/null
+++ b/docs/plans/2026-02-13-hugo-native-api-migration.md
@@ -0,0 +1,344 @@
+# Hugo-Native API Reference Migration Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Complete migration to Hugo-native API reference rendering for all InfluxDB products, removing RapiDoc and simplifying the codebase.
+
+**Architecture:** The Hugo-native approach renders OpenAPI specs using Hugo templates instead of RapiDoc web components. This provides faster page loads, better SEO, consistent styling, and easier customization. Users access operations only through tag pages (no individual operation URLs).
+
+**Tech Stack:** TypeScript (generation scripts), Hugo templates, SCSS, OpenAPI 3.0 specs
+
+***
+
+## Overview
+
+### Design Principles
+
+- **Consistency:** Unified look and feel across all API reference pages
+- **Performance:** Fast page loads, full SEO indexability (no shadow DOM)
+- **Simplicity:** No web components, no client-side rendering
+- **Tag-based navigation:** Operations grouped by tag, accessed via tag pages only
+
+### URL Structure
+
+- **API index:** `/influxdb3/core/api/`
+- **Tag page:** `/influxdb3/core/api/cache-distinct-values/`
+- **All endpoints:** `/influxdb3/core/api/all-endpoints/`
+
+**Note:** Individual operation pages (e.g., `/influxdb3/core/api/v1/write/`) are being removed. Operations are accessed only through tag pages.
+
+***
+
+## Migration Tasks
+
+### Task 1: Promote Hugo-native templates to default ✅ COMPLETED
+
+**Priority:** High | **Status:** Completed 2026-02-13
+
+Move Hugo-native templates from POC location to production location.
+
+**Files moved:**
+
+- `layouts/partials/api/hugo-native/tag-renderer.html` → `layouts/partials/api/tag-renderer.html`
+- `layouts/partials/api/hugo-native/operation.html` → `layouts/partials/api/operation.html`
+- `layouts/partials/api/hugo-native/parameters.html` → `layouts/partials/api/parameters.html`
+- `layouts/partials/api/hugo-native/parameter-row.html` → `layouts/partials/api/parameter-row.html`
+- `layouts/partials/api/hugo-native/request-body.html` → `layouts/partials/api/request-body.html`
+- `layouts/partials/api/hugo-native/schema.html` → `layouts/partials/api/schema.html`
+- `layouts/partials/api/hugo-native/responses.html` → `layouts/partials/api/responses.html`
+
+**Completed steps:**
+
+1. ✅ Moved 7 files from `hugo-native/` subdirectory to parent directory
+2. ✅ Updated `layouts/api/list.html` to use new locations (removed `hugo-native/` prefix)
+3. ✅ Removed `$useHugoNative` conditional logic from `layouts/api/list.html`
+4. ✅ Deleted `layouts/partials/api/hugo-native/` directory
+
+**Verification:** Hugo build passes, pages render correctly at `/influxdb3/core/api/`
+
+***
+
+### Task 2: Remove RapiDoc templates and partials ✅ COMPLETED
+
+**Priority:** High | **Status:** Completed 2026-02-13
+
+Delete RapiDoc-specific templates now that Hugo-native is the default.
+
+**Files deleted:**
+
+- `layouts/partials/api/rapidoc.html`
+- `layouts/partials/api/rapidoc-tag.html`
+- `layouts/partials/api/rapidoc-mini.html`
+
+**Verification:** `grep -r "rapidoc" layouts/` returns no results
+
+***
+
+### Task 3: Remove RapiDoc JavaScript components ✅ COMPLETED
+
+**Priority:** High | **Status:** Completed 2026-02-13
+
+Delete RapiDoc-specific TypeScript components.
+
+**Files deleted:**
+
+- `assets/js/components/api-rapidoc.ts`
+- `assets/js/components/rapidoc-mini.ts`
+
+**Files updated:**
+
+- `assets/js/main.js` - Removed RapiDoc component imports and registrations
+
+**Verification:** `yarn build:ts` completes without errors
+
+***
+
+### Task 4: Remove operation page generation ✅ COMPLETED
+
+**Priority:** High | **Status:** Completed 2026-02-13
+
+Update generation scripts to remove dead code and RapiDoc references.
+
+**Files modified:**
+
+- `api-docs/scripts/generate-openapi-articles.ts` - Removed \~200 lines of dead `generatePathPages` function
+- `api-docs/scripts/openapi-paths-to-hugo-data/index.ts` - Updated comments to remove RapiDoc references
+
+**Changes:**
+
+1. ✅ Removed dead `generatePathPages` function (operation page generation was already disabled)
+2. ✅ Updated comments from "RapiDoc" to "Hugo-native templates"
+3. ✅ Updated "RapiDoc fragment links" to "OpenAPI fragment links"
+
+**Note:** The `useHugoNative` flag was not found in the codebase - operation page generation was already disabled with a comment noting operations are rendered inline on tag pages.
+
+***
+
+### Task 5: Update Cypress tests for Hugo-native ✅ COMPLETED
+
+**Priority:** High | **Status:** Completed 2026-02-13
+
+Simplified Cypress tests now that we use standard HTML instead of shadow DOM.
+
+**Files modified:**
+
+- `cypress/e2e/content/api-reference.cy.js` - Rewrote test file
+
+**Changes:**
+
+1. ✅ Removed entire "RapiDoc Mini component" describe block (\~160 lines of shadow DOM tests)
+2. ✅ Added "API tag pages" tests with Hugo-native selectors (`.api-operation`, `.api-method`, `.api-path`)
+3. ✅ Added "API section page structure" tests
+4. ✅ Added "All endpoints page" tests
+5. ✅ Updated "API reference layout" tests to use Hugo-native selectors
+
+**New test structure implemented:**
+
+- `API reference content` - Tests API index pages load with valid links
+- `API reference layout` - Tests 3-column layout (sidebar, content, TOC)
+- `API tag pages` - Tests operation rendering, method badges, TOC links
+- `API section page structure` - Tests tag listing on section pages
+- `All endpoints page` - Tests operation cards with links to tag pages
+
+***
+
+### Task 6: Clean up styles ✅ COMPLETED
+
+**Priority:** Medium | **Status:** Completed 2026-02-13
+
+Remove RapiDoc-specific styles, JavaScript, and references from the codebase.
+
+**Files modified:**
+
+- `assets/styles/layouts/_api-layout.scss` - Removed \~40 lines of `rapi-doc::part()` CSS selectors
+- `assets/styles/layouts/_api-overrides.scss` - Updated comment header
+- `assets/styles/layouts/_api-security-schemes.scss` - Removed \~290 lines of dead auth modal styles
+- `assets/js/main.js` - Removed dead `api-auth-input` import and registration
+- `assets/js/components/api-toc.ts` - Removed RapiDoc-specific code and updated comments
+
+**Files deleted:**
+
+- `static/css/rapidoc-custom.css` - Unused static CSS file
+
+**Changes:**
+
+1. ✅ Removed `rapi-doc` container styling and `::part()` selectors from `_api-layout.scss`
+2. ✅ Removed dead auth modal section from `_api-security-schemes.scss` (was for RapiDoc "Try it" integration)
+3. ✅ Removed `api-auth-input` dead import from `main.js` (component file was already deleted)
+4. ✅ Removed `setupRapiDocNavigation()` dead function and references from `api-toc.ts`
+5. ✅ Updated comments throughout to remove RapiDoc mentions
+6. ✅ Rebuilt `api-docs/scripts/dist/` to update compiled JavaScript
+
+**Architecture decision:** Kept operation styles separate from layout styles for cleaner separation of concerns:
+
+- `_api-layout.scss` handles page structure and navigation
+- `_api-operations.scss` handles operation/schema component rendering (renamed from `_api-hugo-native.scss`)
+
+***
+
+### Task 7: Fix Generation Script for Clean Regeneration ✅ COMPLETED
+
+**Priority:** Medium | **Status:** Completed 2026-02-17
+
+Added clean regeneration to prevent stale files from accumulating when tags are renamed or removed.
+
+**Files modified:**
+
+- `api-docs/scripts/generate-openapi-articles.ts` - Added cleanup functions and CLI flags
+
+**Implementation:**
+
+1. ✅ Added `--no-clean` flag to skip cleanup (default is to clean)
+2. ✅ Added `--dry-run` flag to preview what would be deleted
+3. ✅ Added `getCleanupPaths()` function to identify directories/files to clean
+4. ✅ Added `cleanProductOutputs()` function to delete directories and files
+5. ✅ Added `showDryRunPreview()` function for dry-run output
+6. ✅ Integrated cleanup into `processProduct()` (runs before generation)
+7. ✅ Updated script header documentation with new usage examples
+
+**Cleaned directories per product:**
+
+- `static/openapi/{staticDirName}/` - Tag specs
+- `static/openapi/{staticDirName}-*.yml` and `.json` - Root specs
+- `data/article_data/influxdb/{productKey}/` - Article data
+- `content/{pagesDir}/api/` - Content pages
+
+**Design:** See `plans/2026-02-17-api-clean-regeneration-design.md`
+
+***
+
+### Task 8: Apply Cache Data tag split to InfluxDB 3 Enterprise
+
+**Priority:** Medium
+
+Apply the same tag split done for Core.
+
+**Files to modify:**
+
+- `api-docs/influxdb3/enterprise/v3/ref.yml`
+
+**Changes:**
+
+1. Replace "Cache data" tag with "Cache distinct values" and "Cache last value" tags
+2. Update operation tag references
+3. Update x-tagGroups references
+4. Regenerate: `sh api-docs/generate-api-docs.sh`
+
+***
+
+### Task 9: Migrate remaining products to Hugo-native
+
+**Priority:** Medium
+
+After the infrastructure is in place, migrate remaining products.
+
+**Products:**
+
+- [ ] cloud-dedicated (management API)
+- [ ] cloud-serverless
+- [ ] clustered (management API)
+- [ ] cloud-v2
+- [ ] oss-v2
+- [ ] oss-v1
+
+**For each product:**
+
+1. Review tag structure in OpenAPI spec
+2. Add `x-influxdata-related` links where appropriate
+3. Clean and regenerate
+4. Verify all tag pages render correctly
+
+***
+
+## Key Files Reference
+
+**Hugo-Native Templates (after migration):**
+
+- `layouts/partials/api/tag-renderer.html` - Main tag page renderer
+- `layouts/partials/api/operation.html` - Individual operation renderer
+- `layouts/partials/api/parameters.html` - Parameters section
+- `layouts/partials/api/parameter-row.html` - Single parameter row
+- `layouts/partials/api/request-body.html` - Request body section
+- `layouts/partials/api/schema.html` - JSON schema renderer
+- `layouts/partials/api/responses.html` - Response section
+
+**Layouts:**
+
+- `layouts/api/list.html` - Tag page layout (Hugo-native only)
+- `layouts/api/section.html` - API section page layout
+- `layouts/api/all-endpoints.html` - All endpoints page layout
+
+**Styles:**
+
+- `assets/styles/layouts/_api-layout.scss` - Consolidated API styles
+
+**Generation:**
+
+- `api-docs/scripts/generate-openapi-articles.ts` - Main generation script
+- `api-docs/scripts/openapi-paths-to-hugo-data/index.ts` - OpenAPI processing
+
+***
+
+## Verification Checklist
+
+Before considering migration complete for each product:
+
+- [ ] All tag pages render without errors
+- [ ] Operation details (parameters, request body, responses) display correctly
+- [ ] Schema references resolve and render
+- [ ] `x-influxdata-related` links appear at page bottom
+- [ ] Navigation shows correct tag structure
+- [ ] Mobile responsive layout works
+- [ ] No console errors in browser DevTools
+- [ ] "On this page" TOC links work correctly
+- [ ] Cypress tests pass
+- [ ] No RapiDoc references remain in codebase
+
+## Files to Delete (Summary)
+
+**Already deleted (Tasks 1-3):**
+
+- ✅ `layouts/partials/api/rapidoc.html`
+- ✅ `layouts/partials/api/rapidoc-tag.html`
+- ✅ `layouts/partials/api/rapidoc-mini.html`
+- ✅ `layouts/partials/api/hugo-native/` (entire directory - 7 files moved to parent)
+- ✅ `assets/js/components/api-rapidoc.ts`
+- ✅ `assets/js/components/rapidoc-mini.ts`
+
+**Still to review (Task 6):**
+
+- `assets/styles/layouts/_api-overrides.scss` (if RapiDoc-only)
+
+***
+
+## Migration Findings
+
+### Completed Work Summary (Tasks 1-5)
+
+**Infrastructure changes:**
+
+- Hugo-native templates are now the default (no feature flag required)
+- All RapiDoc code removed from layouts and JavaScript
+- Generation scripts cleaned up (\~200 lines of dead code removed)
+- Cypress tests simplified (no more shadow DOM piercing)
+
+**Key discoveries:**
+
+1. The `useHugoNative` flag did not exist in the codebase - operation page generation was already disabled
+2. The `generatePathPages` function was dead code that could be safely removed
+3. RapiDoc Mini tests were \~160 lines that are no longer needed
+4. Hugo build and TypeScript compilation both pass after all changes
+
+**Verification status:**
+
+- ✅ Hugo build: `npx hugo --quiet` passes
+- ✅ TypeScript: `yarn build:ts` passes
+- ⏳ Cypress tests: Need to run `yarn test:e2e` to verify new tests pass
+- ⏳ Visual review: Need to check pages render correctly in browser
+
+### Remaining Work (Tasks 6-9)
+
+1. **Task 6 (styles)**: Review and consolidate SCSS files
+2. **Task 7 (clean regeneration)**: Add `--clean` flag to generation scripts
+3. **Task 8 (Enterprise tags)**: Split Cache Data tag in Enterprise spec
+4. **Task 9 (product migration)**: Apply to remaining 6 products
diff --git a/docs/plans/2026-02-17-api-clean-regeneration-design.md b/docs/plans/2026-02-17-api-clean-regeneration-design.md
new file mode 100644
index 000000000..06e62e6cc
--- /dev/null
+++ b/docs/plans/2026-02-17-api-clean-regeneration-design.md
@@ -0,0 +1,160 @@
+# API Clean Regeneration Design
+
+**Goal:** Add clean regeneration to `generate-openapi-articles.ts` to prevent stale files from accumulating when tags are renamed or removed.
+
+**Problem:** When OpenAPI tags are renamed (e.g., "Cache data" → "Cache distinct values" + "Cache last value"), old generated files persist alongside new ones, causing navigation confusion and stale content.
+
+***
+
+## CLI Interface
+
+**New flags:**
+
+| Flag | Description |
+| ------------ | ---------------------------------------------------- |
+| `--no-clean` | Skip directory cleanup (preserve existing files) |
+| `--dry-run` | Show what would be deleted without actually deleting |
+
+**Behavior:**
+
+- Default is to clean before generating (no flag needed)
+- `--dry-run` implies `--no-clean` (shows deletions but doesn't execute or generate)
+- Existing flags (`--validate-links`, `--skip-fetch`) continue to work
+
+**Usage examples:**
+
+```bash
+# Default: clean and regenerate all products
+node generate-openapi-articles.js
+
+# Clean and regenerate specific product
+node generate-openapi-articles.js influxdb3_core
+
+# Preview what would be deleted
+node generate-openapi-articles.js --dry-run
+
+# Preserve existing files (legacy behavior)
+node generate-openapi-articles.js --no-clean
+```
+
+***
+
+## Directories Cleaned Per Product
+
+For each product (e.g., `influxdb3_core`), the following are cleaned:
+
+| Location | Pattern | Example |
+| ------------- | -------------------------------------------------- | -------------------------------------------- |
+| Tag specs | `static/openapi/{staticDirName}/` | `static/openapi/influxdb3-core/` |
+| Root specs | `static/openapi/{staticDirName}-*.yml` and `.json` | `static/openapi/influxdb3-core-ref.yml` |
+| Article data | `data/article_data/influxdb/{productKey}/` | `data/article_data/influxdb/influxdb3_core/` |
+| Content pages | `content/{pagesDir}/api/` | `content/influxdb3/core/api/` |
+
+**Boundaries:**
+
+- Only cleans the `api/` subdirectory within content, not the entire product
+- Only cleans files matching the product's `staticDirName` pattern
+- Never touches other products' files
+- Multi-spec products (cloud-dedicated, clustered) clean all spec variants
+
+***
+
+## Dry-Run Output Format
+
+```
+$ node generate-openapi-articles.js influxdb3_core --dry-run
+
+DRY RUN: Would clean the following for influxdb3_core:
+
+Directories to remove:
+ - static/openapi/influxdb3-core/
+ - data/article_data/influxdb/influxdb3_core/
+ - content/influxdb3/core/api/
+
+Files to remove:
+ - static/openapi/influxdb3-core-ref.yml
+ - static/openapi/influxdb3-core-ref.json
+
+Summary: 3 directories, 2 files would be removed
+
+Skipping generation (dry-run mode).
+```
+
+***
+
+## Code Structure
+
+**File modified:** `api-docs/scripts/generate-openapi-articles.ts`
+
+**New CLI flag parsing:**
+
+```typescript
+const noClean = process.argv.includes('--no-clean');
+const dryRun = process.argv.includes('--dry-run');
+```
+
+**New functions:**
+
+```typescript
+/**
+ * Get all paths that would be cleaned for a product
+ */
+function getCleanupPaths(productKey: string, config: ProductConfig): {
+ directories: string[];
+ files: string[];
+}
+
+/**
+ * Clean output directories for a product before regeneration
+ */
+function cleanProductOutputs(productKey: string, config: ProductConfig): void
+
+/**
+ * Display dry-run preview of what would be cleaned
+ */
+function showDryRunPreview(productKey: string, config: ProductConfig): void
+```
+
+**Changes to `processProduct()`:**
+
+```typescript
+function processProduct(productKey: string, config: ProductConfig): void {
+ // Clean before generating (unless --no-clean or --dry-run)
+ if (!noClean && !dryRun) {
+ cleanProductOutputs(productKey, config);
+ }
+
+ // Existing generation logic...
+}
+```
+
+**Changes to `main()`:**
+
+```typescript
+function main(): void {
+ // Handle dry-run mode
+ if (dryRun) {
+ productsToProcess.forEach((productKey) => {
+ showDryRunPreview(productKey, productConfigs[productKey]);
+ });
+ console.log('\nDry run complete. No files were modified.');
+ return; // Exit without generating
+ }
+
+ // Existing processing logic...
+}
+```
+
+**No changes to:** `openapi-paths-to-hugo-data/index.ts`
+
+***
+
+## Verification
+
+After implementation:
+
+1. Run `--dry-run` and verify output matches expected format
+2. Run without flags and verify old files are removed
+3. Run with `--no-clean` and verify files are preserved
+4. Verify Hugo build passes after clean regeneration
+5. Verify no stale tag pages appear in navigation
diff --git a/docs/plans/2026-02-17-api-clean-regeneration-implementation.md b/docs/plans/2026-02-17-api-clean-regeneration-implementation.md
new file mode 100644
index 000000000..723b140d6
--- /dev/null
+++ b/docs/plans/2026-02-17-api-clean-regeneration-implementation.md
@@ -0,0 +1,519 @@
+# API Clean Regeneration Implementation Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Add `--no-clean` and `--dry-run` flags to `generate-openapi-articles.ts` so stale files are automatically removed before regeneration.
+
+**Architecture:** Delete-and-regenerate approach. Before processing each product, remove its output directories (static specs, article data, content pages), then generate fresh. Default behavior is to clean; `--no-clean` preserves existing files.
+
+**Tech Stack:** TypeScript, Node.js fs module, existing generation script
+
+**Design:** See `plans/2026-02-17-api-clean-regeneration-design.md`
+
+***
+
+## Task 1: Add CLI Flag Parsing
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts:88-89`
+
+**Step 1: Add flag constants after existing flags**
+
+Find the existing CLI flags section (around line 88):
+
+```typescript
+// CLI flags
+const validateLinks = process.argv.includes('--validate-links');
+const skipFetch = process.argv.includes('--skip-fetch');
+```
+
+Add new flags below:
+
+```typescript
+// CLI flags
+const validateLinks = process.argv.includes('--validate-links');
+const skipFetch = process.argv.includes('--skip-fetch');
+const noClean = process.argv.includes('--no-clean');
+const dryRun = process.argv.includes('--dry-run');
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): add --no-clean and --dry-run CLI flags"
+```
+
+***
+
+## Task 2: Add getCleanupPaths Function
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts`
+
+**Step 1: Add getCleanupPaths function after getStaticDirName function (around line 170)**
+
+```typescript
+/**
+ * Get all paths that would be cleaned for a product
+ *
+ * @param productKey - Product identifier (e.g., 'influxdb3_core')
+ * @param config - Product configuration
+ * @returns Object with directories and files arrays
+ */
+function getCleanupPaths(
+ productKey: string,
+ config: ProductConfig
+): { directories: string[]; files: string[] } {
+ const staticDirName = getStaticDirName(productKey);
+ const staticPath = path.join(DOCS_ROOT, 'static/openapi');
+
+ const directories: string[] = [];
+ const files: string[] = [];
+
+ // Tag specs directory: static/openapi/{staticDirName}/
+ const tagSpecsDir = path.join(staticPath, staticDirName);
+ if (fs.existsSync(tagSpecsDir)) {
+ directories.push(tagSpecsDir);
+ }
+
+ // Article data directory: data/article_data/influxdb/{productKey}/
+ const articleDataDir = path.join(
+ DOCS_ROOT,
+ `data/article_data/influxdb/${productKey}`
+ );
+ if (fs.existsSync(articleDataDir)) {
+ directories.push(articleDataDir);
+ }
+
+ // Content pages directory: content/{pagesDir}/api/
+ const contentApiDir = path.join(config.pagesDir, 'api');
+ if (fs.existsSync(contentApiDir)) {
+ directories.push(contentApiDir);
+ }
+
+ // Root spec files: static/openapi/{staticDirName}-*.yml and .json
+ if (fs.existsSync(staticPath)) {
+ const staticFiles = fs.readdirSync(staticPath);
+ const pattern = new RegExp(`^${staticDirName}-.*\\.(yml|json)$`);
+ staticFiles
+ .filter((f) => pattern.test(f))
+ .forEach((f) => {
+ files.push(path.join(staticPath, f));
+ });
+ }
+
+ return { directories, files };
+}
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): add getCleanupPaths function"
+```
+
+***
+
+## Task 3: Add cleanProductOutputs Function
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts`
+
+**Step 1: Add cleanProductOutputs function after getCleanupPaths**
+
+```typescript
+/**
+ * Clean output directories for a product before regeneration
+ *
+ * @param productKey - Product identifier
+ * @param config - Product configuration
+ */
+function cleanProductOutputs(productKey: string, config: ProductConfig): void {
+ const { directories, files } = getCleanupPaths(productKey, config);
+
+ // Remove directories recursively
+ for (const dir of directories) {
+ console.log(`🧹 Removing directory: ${dir}`);
+ fs.rmSync(dir, { recursive: true, force: true });
+ }
+
+ // Remove individual files
+ for (const file of files) {
+ console.log(`🧹 Removing file: ${file}`);
+ fs.unlinkSync(file);
+ }
+
+ const total = directories.length + files.length;
+ if (total > 0) {
+ console.log(
+ `✓ Cleaned ${directories.length} directories, ${files.length} files for ${productKey}`
+ );
+ }
+}
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): add cleanProductOutputs function"
+```
+
+***
+
+## Task 4: Add showDryRunPreview Function
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts`
+
+**Step 1: Add showDryRunPreview function after cleanProductOutputs**
+
+```typescript
+/**
+ * Display dry-run preview of what would be cleaned
+ *
+ * @param productKey - Product identifier
+ * @param config - Product configuration
+ */
+function showDryRunPreview(productKey: string, config: ProductConfig): void {
+ const { directories, files } = getCleanupPaths(productKey, config);
+
+ console.log(`\nDRY RUN: Would clean the following for ${productKey}:\n`);
+
+ if (directories.length > 0) {
+ console.log('Directories to remove:');
+ directories.forEach((dir) => console.log(` - ${dir}`));
+ }
+
+ if (files.length > 0) {
+ console.log('\nFiles to remove:');
+ files.forEach((file) => console.log(` - ${file}`));
+ }
+
+ if (directories.length === 0 && files.length === 0) {
+ console.log(' (no files to clean)');
+ }
+
+ console.log(
+ `\nSummary: ${directories.length} directories, ${files.length} files would be removed`
+ );
+}
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): add showDryRunPreview function"
+```
+
+***
+
+## Task 5: Integrate Cleanup into processProduct
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts:1129-1135`
+
+**Step 1: Add cleanup call at the start of processProduct function**
+
+Find the beginning of `processProduct` function (around line 1129):
+
+```typescript
+function processProduct(productKey: string, config: ProductConfig): void {
+ console.log('\n' + '='.repeat(80));
+ console.log(`Processing ${config.description || productKey}`);
+ console.log('='.repeat(80));
+```
+
+Add cleanup after the header output:
+
+```typescript
+function processProduct(productKey: string, config: ProductConfig): void {
+ console.log('\n' + '='.repeat(80));
+ console.log(`Processing ${config.description || productKey}`);
+ console.log('='.repeat(80));
+
+ // Clean output directories before regeneration (unless --no-clean)
+ if (!noClean && !dryRun) {
+ cleanProductOutputs(productKey, config);
+ }
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): integrate cleanup into processProduct"
+```
+
+***
+
+## Task 6: Add Dry-Run Mode to main Function
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts:1307-1346`
+
+**Step 1: Add dry-run handling after product validation in main()**
+
+Find the section after product validation (around line 1340):
+
+```typescript
+ // Validate product keys
+ const invalidProducts = productsToProcess.filter(
+ (key) => !productConfigs[key]
+ );
+ if (invalidProducts.length > 0) {
+ // ... error handling ...
+ }
+
+ // Process each product
+ productsToProcess.forEach((productKey) => {
+```
+
+Add dry-run handling before the forEach:
+
+```typescript
+ // Validate product keys
+ const invalidProducts = productsToProcess.filter(
+ (key) => !productConfigs[key]
+ );
+ if (invalidProducts.length > 0) {
+ // ... error handling ...
+ }
+
+ // Handle dry-run mode
+ if (dryRun) {
+ console.log('\n📋 DRY RUN MODE - No files will be modified\n');
+ productsToProcess.forEach((productKey) => {
+ showDryRunPreview(productKey, productConfigs[productKey]);
+ });
+ console.log('\nDry run complete. No files were modified.');
+ return;
+ }
+
+ // Process each product
+ productsToProcess.forEach((productKey) => {
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "feat(api): add dry-run mode to main function"
+```
+
+***
+
+## Task 7: Update Script Header Documentation
+
+**Files:**
+
+- Modify: `api-docs/scripts/generate-openapi-articles.ts:1-21`
+
+**Step 1: Update the usage documentation in the file header**
+
+Find the header comment block and update:
+
+```typescript
+#!/usr/bin/env node
+/**
+ * Generate OpenAPI Articles Script
+ *
+ * Generates Hugo data files and content pages from OpenAPI specifications
+ * for all InfluxDB products.
+ *
+ * This script:
+ * 1. Cleans output directories (unless --no-clean)
+ * 2. Runs getswagger.sh to fetch/bundle OpenAPI specs
+ * 3. Copies specs to static directory for download
+ * 4. Generates path group fragments (YAML and JSON)
+ * 5. Creates article metadata (YAML and JSON)
+ * 6. Generates Hugo content pages from article data
+ *
+ * Usage:
+ * node generate-openapi-articles.js # Clean and generate all products
+ * node generate-openapi-articles.js cloud-v2 # Clean and generate single product
+ * node generate-openapi-articles.js --no-clean # Generate without cleaning
+ * node generate-openapi-articles.js --dry-run # Preview what would be cleaned
+ * node generate-openapi-articles.js --skip-fetch # Skip getswagger.sh fetch step
+ * node generate-openapi-articles.js --validate-links # Validate documentation links
+ *
+ * @module generate-openapi-articles
+ */
+```
+
+**Step 2: Verify TypeScript compiles**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors
+
+**Step 3: Commit**
+
+```bash
+git add api-docs/scripts/generate-openapi-articles.ts
+git commit -m "docs(api): update script header with new flags"
+```
+
+***
+
+## Task 8: Rebuild Compiled JavaScript
+
+**Files:**
+
+- Modify: `api-docs/scripts/dist/generate-openapi-articles.js` (generated)
+
+**Step 1: Rebuild TypeScript**
+
+Run: `yarn build:ts`
+Expected: Compiles without errors, updates dist/ files
+
+**Step 2: Verify the compiled output includes new functions**
+
+Run: `grep -n "getCleanupPaths\|cleanProductOutputs\|showDryRunPreview\|noClean\|dryRun" api-docs/scripts/dist/generate-openapi-articles.js | head -10`
+Expected: Shows line numbers where new code appears
+
+**Step 3: Commit compiled output**
+
+```bash
+git add api-docs/scripts/dist/
+git commit -m "build(api): rebuild compiled generation scripts"
+```
+
+***
+
+## Task 9: Manual Testing
+
+**Step 1: Test dry-run mode**
+
+Run: `node api-docs/scripts/dist/generate-openapi-articles.js influxdb3_core --dry-run`
+
+Expected output format:
+
+```
+📋 DRY RUN MODE - No files will be modified
+
+DRY RUN: Would clean the following for influxdb3_core:
+
+Directories to remove:
+ - static/openapi/influxdb3-core
+ - data/article_data/influxdb/influxdb3_core
+ - content/influxdb3/core/api
+
+Files to remove:
+ - static/openapi/influxdb3-core-ref.yml
+ - static/openapi/influxdb3-core-ref.json
+
+Summary: 3 directories, 2 files would be removed
+
+Dry run complete. No files were modified.
+```
+
+**Step 2: Verify files were NOT deleted after dry-run**
+
+Run: `ls content/influxdb3/core/api/`
+Expected: Directory still exists with content
+
+**Step 3: Test actual clean regeneration**
+
+Run: `node api-docs/scripts/dist/generate-openapi-articles.js influxdb3_core --skip-fetch`
+Expected: Shows cleanup messages, then regenerates successfully
+
+**Step 4: Verify Hugo build passes**
+
+Run: `npx hugo --quiet`
+Expected: Builds without errors
+
+**Step 5: Test --no-clean flag preserves files**
+
+First, create a marker file:
+
+```bash
+touch content/influxdb3/core/api/MARKER_FILE.md
+```
+
+Run: `node api-docs/scripts/dist/generate-openapi-articles.js influxdb3_core --skip-fetch --no-clean`
+
+Verify marker still exists:
+
+```bash
+ls content/influxdb3/core/api/MARKER_FILE.md
+```
+
+Expected: File exists
+
+Clean up marker:
+
+```bash
+rm content/influxdb3/core/api/MARKER_FILE.md
+```
+
+***
+
+## Task 10: Update Migration Plan
+
+**Files:**
+
+- Modify: `plans/2026-02-13-hugo-native-api-migration.md`
+
+**Step 1: Mark Task 7 as completed**
+
+Update the task status from planned to completed.
+
+**Step 2: Commit**
+
+```bash
+git add plans/2026-02-13-hugo-native-api-migration.md
+git commit -m "docs(plan): mark Task 7 (clean regeneration) as completed"
+```
+
+***
+
+## Verification Checklist
+
+Before considering complete:
+
+- [ ] `yarn build:ts` compiles without errors
+- [ ] `--dry-run` shows expected output format
+- [ ] `--dry-run` does NOT delete any files
+- [ ] Default mode (no flags) cleans before regenerating
+- [ ] `--no-clean` preserves existing files
+- [ ] `npx hugo --quiet` builds successfully after regeneration
+- [ ] All new code is committed
diff --git a/docs/plans/2026-03-07-api-code-samples-design.md b/docs/plans/2026-03-07-api-code-samples-design.md
new file mode 100644
index 000000000..1ef32cc2b
--- /dev/null
+++ b/docs/plans/2026-03-07-api-code-samples-design.md
@@ -0,0 +1,125 @@
+# API Code Samples & Ask AI Integration Plan
+
+## Scope
+
+This plan covers:
+
+1. **Inline curl examples** for each API operation, generated at Hugo template time from the OpenAPI spec
+2. **"Ask AI about this example"** link on each curl example, using the existing Kapa integration
+3. **Client library related link** on all InfluxDB 3 API tag pages
+
+**Out of scope** (separate plans):
+
+- Site-wide Ask AI on all code blocks (render-codeblock hook)
+- Client library tabbed code samples with language tabs
+- Duplicate response schema rendering (already shown in Responses section)
+
+***
+
+## Architecture
+
+**No build script changes for curl generation.** The curl example is constructed entirely in a Hugo partial (`api/code-sample.html`) using data already loaded by `tag-renderer.html` — the full parsed OpenAPI spec with server URLs, parameters, request body schemas, and examples.
+
+The existing `influxdb-url.js` automatically replaces the default placeholder host in `` elements with the user's custom URL. No new JavaScript is needed for URL personalization.
+
+### Operation layout order (revised)
+
+1. Header (method + path + summary)
+2. Description
+3. Parameters
+4. Request Body
+5. **Example (curl + Ask AI)** — new
+6. Responses
+
+***
+
+## curl Example Generation
+
+### Partial: `layouts/partials/api/code-sample.html`
+
+Receives the operation definition (`$opDef`), spec (`$spec`), and operation metadata from `operation.html`. Constructs a curl command:
+
+1. **Server URL**: `spec.servers[0].url` — falls back to the product's `placeholder_host`. The existing `influxdb-url.js` replaces this in the DOM if the user has a custom URL.
+2. **Method**: Always explicit `--request METHOD`
+3. **Path**: Appended to server URL. `{param}` placeholders left as-is in the URL.
+4. **Query parameters**: Only required ones. Uses `example` value if available, otherwise an `UPPER_SNAKE_CASE` placeholder derived from the parameter name.
+5. **Headers**:
+ - Always: `--header "Authorization: Bearer INFLUX_TOKEN"`
+ - When request body exists: `--header "Content-Type: ..."` derived from the first key in `requestBody.content`
+6. **Request body**:
+ - `application/json`: Uses `schema.example` if present. If no example, body is omitted entirely — no synthesized fake data.
+ - `text/plain` (line protocol): Hardcoded sample: `--data-raw "measurement,tag=value field=1.0"`
+ - No example and no special content type: body omitted, shows only URL + headers.
+
+### Ask AI link
+
+Each code sample block includes an "Ask AI about this example" link using the existing `ask-ai-open` CSS class and `data-query` attribute. The existing `ask-ai-trigger.js` handles click events and opens the Kapa widget — no new JavaScript needed.
+
+```html
+
+ Ask AI about this example
+
+```
+
+***
+
+## Client Library Related Link
+
+The generation script adds a related link to `/influxdb3/{product}/reference/client-libraries/v3/` for all InfluxDB 3 product tag pages.
+
+**InfluxDB 3 products** (identified by `pagesDir` containing `influxdb3/`):
+
+- `influxdb3_core`
+- `influxdb3_enterprise`
+- `cloud-dedicated`
+- `cloud-serverless`
+- `clustered`
+
+**Excluded** (future plan with v2 client library links):
+
+- `cloud-v2`, `oss-v2`, `oss-v1`, `enterprise-v1`
+
+The `{product}` segment is derived from the `pagesDir` (e.g., `content/influxdb3/core` yields `core`).
+
+***
+
+## File Changes
+
+### New files
+
+| File | Purpose |
+| ---------------------------------------------- | ---------------------------- |
+| `layouts/partials/api/code-sample.html` | curl example + Ask AI link |
+| `assets/styles/layouts/_api-code-samples.scss` | Styles for code sample block |
+
+### Modified files
+
+| File | Change |
+| ----------------------------------------------- | ------------------------------------------------------------------ |
+| `layouts/partials/api/operation.html` | Insert `code-sample.html` between request body and responses |
+| `assets/styles/styles-default.scss` | Import `_api-code-samples.scss` |
+| `api-docs/scripts/generate-openapi-articles.ts` | Add client library reference related link for InfluxDB 3 tag pages |
+
+### Not modified
+
+| File | Reason |
+| ------------------------------------------------------ | ------------------------ |
+| `layouts/api/list.html` | No layout changes needed |
+| `assets/js/main.js` | No new JS components |
+| `assets/js/components/api-toc.ts` | TOC unchanged |
+| `assets/styles/layouts/_api-layout.scss` | Layout unchanged |
+| `api-docs/scripts/openapi-paths-to-hugo-data/index.ts` | No data model changes |
+
+***
+
+## Verification
+
+1. **Build**: `npx hugo --quiet` — no template errors
+2. **Visual**: Dev server — navigate to API tag page (e.g., `/influxdb3/core/api/write-data/`) — each operation has a curl example between Request Body and Responses
+3. **URL replacement**: Set a custom URL in the URL selector — verify it replaces the host in curl examples
+4. **Ask AI**: Click "Ask AI about this example" — Kapa opens with pre-populated query
+5. **Related link**: Client library reference link appears at bottom of all InfluxDB 3 API tag pages
+6. **Cypress**: Add test verifying `.api-code-sample` elements render on tag pages
+7. **Dark/light mode**: Code block renders correctly in both themes
+8. **Responsive**: Code sample block handles narrow viewports (horizontal scroll for long curl commands)
diff --git a/docs/plans/TESTING.md b/docs/plans/TESTING.md
new file mode 100644
index 000000000..7b2888650
--- /dev/null
+++ b/docs/plans/TESTING.md
@@ -0,0 +1,77 @@
+# API Reference Testing Plan
+
+> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
+
+**Goal:** Validate Hugo-native API reference pages render correctly and all tests pass.
+
+**Architecture:** Hugo-native rendering uses standard HTML without shadow DOM, making tests simpler. No RapiDoc web components - operations are rendered server-side by Hugo templates.
+
+**Tech Stack:** Hugo templates, SCSS, Cypress
+
+***
+
+## Test Structure
+
+The API reference tests validate:
+
+1. **API index pages** - Main API landing pages load correctly
+2. **API tag pages** - Tag pages render operations with parameters/responses
+3. **Section structure** - Section pages list tag children correctly
+4. **All endpoints** - All endpoints page shows all operations
+5. **Layout** - 3-column layout with sidebar, content, and TOC
+
+## Running Tests
+
+### Quick validation
+
+```bash
+# Build site
+yarn hugo --quiet
+
+# Start server
+yarn hugo server &
+
+# Test pages load
+curl -s -o /dev/null -w "%{http_code}" http://localhost:1313/influxdb3/core/api/
+# Expected: 200
+
+# Run Cypress tests (for example, for InfluxDB 3 Core)
+node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/api-reference.cy.js" content/influxdb3/core/api/_index.md
+
+# Stop server
+pkill -f "hugo server"
+```
+
+### Full test suite
+
+```bash
+node cypress/support/run-e2e-specs.js --spec "cypress/e2e/content/api-reference.cy.js"
+```
+
+## Test Selectors (Hugo-Native)
+
+Since Hugo-native uses standard HTML, tests use simple CSS selectors:
+
+| Element | Selector |
+| ---------------- | ------------------- |
+| Page title | `h1` |
+| Operation | `.api-operation` |
+| Method badge | `.api-method` |
+| Path | `.api-path` |
+| Parameters table | `.api-parameters` |
+| Request body | `.api-request-body` |
+| Responses | `.api-responses` |
+| TOC | `.api-toc` |
+| Related links | `.article--related` |
+
+## Expected Test Coverage
+
+- [ ] API index pages (Core, Enterprise, Cloud Dedicated, Clustered, Cloud Serverless)
+- [ ] Tag pages render operations
+- [ ] Parameters display correctly
+- [ ] Request body sections display
+- [ ] Response sections display
+- [ ] TOC links work
+- [ ] All endpoints page lists operations
+- [ ] Section pages list tags
+- [ ] Links are valid
diff --git a/helper-scripts/migrate-api-links.cjs b/helper-scripts/migrate-api-links.cjs
new file mode 100755
index 000000000..98ed624a1
--- /dev/null
+++ b/helper-scripts/migrate-api-links.cjs
@@ -0,0 +1,331 @@
+#!/usr/bin/env node
+/**
+ * migrate-api-links.js
+ *
+ * One-time migration script to convert Redoc API links to RapiDoc format.
+ *
+ * Usage:
+ * node helper-scripts/migrate-api-links.js --dry-run # Preview changes
+ * node helper-scripts/migrate-api-links.js # Execute migration
+ */
+
+const fs = require('fs');
+const path = require('path');
+const yaml = require('js-yaml');
+const { glob } = require('glob');
+
+// CLI arguments
+const args = process.argv.slice(2);
+const DRY_RUN = args.includes('--dry-run');
+const VERBOSE = args.includes('--verbose');
+
+// Paths
+const ROOT_DIR = path.resolve(__dirname, '..');
+const CONTENT_DIR = path.join(ROOT_DIR, 'content');
+const API_DOCS_DIR = path.join(ROOT_DIR, 'api-docs');
+
+// Spec file → product URL mapping
+const SPEC_MAPPINGS = [
+ { spec: 'influxdb/cloud/v2/ref.yml', urlPrefix: '/influxdb/cloud/api/' },
+ { spec: 'influxdb/v2/v2/ref.yml', urlPrefix: '/influxdb/v2/api/' },
+ { spec: 'influxdb/v1/v1/ref.yml', urlPrefix: '/influxdb/v1/api/' },
+ { spec: 'enterprise_influxdb/v1/v1/ref.yml', urlPrefix: '/enterprise_influxdb/v1/api/' },
+ { spec: 'influxdb3/core/v3/ref.yml', urlPrefix: '/influxdb3/core/api/' },
+ { spec: 'influxdb3/enterprise/v3/ref.yml', urlPrefix: '/influxdb3/enterprise/api/' },
+ { spec: 'influxdb3/cloud-dedicated/v2/ref.yml', urlPrefix: '/influxdb3/cloud-dedicated/api/' },
+ { spec: 'influxdb3/cloud-dedicated/management/openapi.yml', urlPrefix: '/influxdb3/cloud-dedicated/api/management/' },
+ { spec: 'influxdb3/cloud-serverless/v2/ref.yml', urlPrefix: '/influxdb3/cloud-serverless/api/' },
+ { spec: 'influxdb3/clustered/v2/ref.yml', urlPrefix: '/influxdb3/clustered/api/' },
+ { spec: 'influxdb3/clustered/management/openapi.yml', urlPrefix: '/influxdb3/clustered/api/management/' },
+];
+
+// Version placeholder mappings for shared content
+// Maps /version/ placeholder URLs to representative specs for operationId lookup
+const VERSION_PLACEHOLDER_MAPPINGS = [
+ // InfluxDB 3 v3 API (core/enterprise share same operationIds)
+ { pattern: /^\/influxdb3\/version\/api\/v3\//, lookupPrefix: '/influxdb3/core/api/' },
+ // InfluxDB 3 reference path variant
+ { pattern: /^\/influxdb3\/[^/]+\/reference\/api\/v3\//, lookupPrefix: '/influxdb3/core/api/' },
+ // InfluxDB v2 API - use v2 (OSS) as it has more operations than cloud (replication, etc.)
+ { pattern: /^\/influxdb\/version\/api\/v2\//, lookupPrefix: '/influxdb/v2/api/' },
+ { pattern: /^\/influxdb\/version\/api\/v1\//, lookupPrefix: '/influxdb/v2/api/' }, // v1 compat is in v2 spec
+ { pattern: /^\/influxdb\/version\/api\//, lookupPrefix: '/influxdb/v2/api/' },
+ // InfluxDB 3 version placeholder (generic)
+ { pattern: /^\/influxdb3\/version\/api\//, lookupPrefix: '/influxdb3/cloud-serverless/api/' },
+];
+
+/**
+ * Convert path parameters from {param} to -param- (RapiDoc format)
+ */
+function convertPathParams(path) {
+ return path.replace(/\{([^}]+)\}/g, '-$1-');
+}
+
+/**
+ * Build RapiDoc anchor from method and path
+ * Format: {method}-{path} with {param} → -param-
+ */
+function buildAnchor(method, pathStr) {
+ const convertedPath = convertPathParams(pathStr);
+ return `${method.toLowerCase()}-${convertedPath}`;
+}
+
+/**
+ * Parse OpenAPI spec and extract operationId → anchor mapping
+ */
+function parseSpec(specPath) {
+ const mapping = {};
+
+ try {
+ const content = fs.readFileSync(specPath, 'utf8');
+ const spec = yaml.load(content);
+
+ if (!spec.paths) {
+ console.warn(` Warning: No paths in ${specPath}`);
+ return mapping;
+ }
+
+ for (const [pathStr, pathItem] of Object.entries(spec.paths)) {
+ const methods = ['get', 'post', 'put', 'patch', 'delete', 'options', 'head'];
+
+ for (const method of methods) {
+ const operation = pathItem[method];
+ if (operation && operation.operationId) {
+ const anchor = buildAnchor(method, pathStr);
+ mapping[operation.operationId] = anchor;
+
+ if (VERBOSE) {
+ console.log(` ${operation.operationId} → #${anchor}`);
+ }
+ }
+ }
+ }
+ } catch (error) {
+ console.error(` Error parsing ${specPath}: ${error.message}`);
+ }
+
+ return mapping;
+}
+
+/**
+ * Build complete lookup table from all specs
+ * Returns: { urlPrefix: { operationId: anchor } }
+ */
+function buildLookupTable() {
+ const lookup = {};
+
+ console.log('Building operationId lookup table...\n');
+
+ for (const { spec, urlPrefix } of SPEC_MAPPINGS) {
+ const specPath = path.join(API_DOCS_DIR, spec);
+
+ if (!fs.existsSync(specPath)) {
+ console.warn(` Skipping missing spec: ${spec}`);
+ continue;
+ }
+
+ console.log(` Processing: ${spec}`);
+ const mapping = parseSpec(specPath);
+ lookup[urlPrefix] = mapping;
+ console.log(` Found ${Object.keys(mapping).length} operations`);
+ }
+
+ console.log('');
+ return lookup;
+}
+
+/**
+ * Find all #operation/ links in a file
+ * Returns array of { match, operationId, urlPath, fullUrl }
+ */
+function findOperationLinks(content) {
+ const links = [];
+ // Match patterns like: /influxdb/cloud/api/#operation/PostTasks
+ // or /influxdb3/cloud-dedicated/api/management/#operation/CreateDatabaseToken
+ const regex = /(\/[a-z0-9_/-]+\/api(?:\/management)?(?:\/[a-z0-9-]*)?\/)#operation\/(\w+)/g;
+
+ let match;
+ while ((match = regex.exec(content)) !== null) {
+ links.push({
+ match: match[0],
+ urlPath: match[1],
+ operationId: match[2],
+ });
+ }
+
+ return links;
+}
+
+/**
+ * Find the best matching URL prefix for a given URL path
+ * Also handles /version/ placeholders in shared content
+ */
+function findUrlPrefix(urlPath, lookup) {
+ // Sort by length descending to match most specific first
+ const prefixes = Object.keys(lookup).sort((a, b) => b.length - a.length);
+
+ for (const prefix of prefixes) {
+ if (urlPath.startsWith(prefix) || urlPath === prefix.slice(0, -1)) {
+ return prefix;
+ }
+ }
+
+ // Check version placeholder mappings for shared content
+ for (const { pattern, lookupPrefix } of VERSION_PLACEHOLDER_MAPPINGS) {
+ if (pattern.test(urlPath)) {
+ if (VERBOSE) {
+ console.log(` Mapped ${urlPath} → ${lookupPrefix} (version placeholder)`);
+ }
+ return lookupPrefix;
+ }
+ }
+
+ return null;
+}
+
+/**
+ * Scan content directory for files with #operation/ links
+ */
+async function scanContentFiles(lookup) {
+ console.log('Scanning content files for #operation/ links...\n');
+
+ const files = await glob('**/*.md', { cwd: CONTENT_DIR });
+ const results = {
+ filesWithLinks: [],
+ totalLinks: 0,
+ unmapped: [],
+ };
+
+ for (const file of files) {
+ const filePath = path.join(CONTENT_DIR, file);
+ const content = fs.readFileSync(filePath, 'utf8');
+ const links = findOperationLinks(content);
+
+ if (links.length > 0) {
+ const fileResult = {
+ file,
+ links: [],
+ };
+
+ for (const link of links) {
+ const urlPrefix = findUrlPrefix(link.urlPath, lookup);
+
+ if (!urlPrefix) {
+ results.unmapped.push({ file, ...link, reason: 'No matching URL prefix' });
+ continue;
+ }
+
+ const productLookup = lookup[urlPrefix];
+ const anchor = productLookup[link.operationId];
+
+ if (!anchor) {
+ results.unmapped.push({ file, ...link, reason: 'OperationId not found in spec' });
+ continue;
+ }
+
+ fileResult.links.push({
+ ...link,
+ urlPrefix,
+ newAnchor: anchor,
+ oldLink: `${link.urlPath}#operation/${link.operationId}`,
+ newLink: `${link.urlPath}#${anchor}`,
+ });
+ }
+
+ if (fileResult.links.length > 0) {
+ results.filesWithLinks.push(fileResult);
+ results.totalLinks += fileResult.links.length;
+ }
+ }
+ }
+
+ return results;
+}
+
+/**
+ * Replace operation links in a file
+ * Returns the modified content
+ */
+function replaceLinks(content, links) {
+ let modified = content;
+
+ for (const link of links) {
+ // Replace all occurrences of this specific link
+ modified = modified.split(link.oldLink).join(link.newLink);
+ }
+
+ return modified;
+}
+
+/**
+ * Apply migrations to files
+ */
+async function applyMigrations(results) {
+ console.log('\n=== APPLYING MIGRATIONS ===\n');
+
+ let filesModified = 0;
+ let linksReplaced = 0;
+
+ for (const { file, links } of results.filesWithLinks) {
+ const filePath = path.join(CONTENT_DIR, file);
+ const originalContent = fs.readFileSync(filePath, 'utf8');
+ const modifiedContent = replaceLinks(originalContent, links);
+
+ if (originalContent !== modifiedContent) {
+ fs.writeFileSync(filePath, modifiedContent, 'utf8');
+ filesModified++;
+ linksReplaced += links.length;
+ console.log(` ✓ ${file} (${links.length} links)`);
+ }
+ }
+
+ console.log(`\nMigration complete: ${filesModified} files modified, ${linksReplaced} links replaced.`);
+}
+
+async function main() {
+ console.log(`API Link Migration Script`);
+ console.log(`Mode: ${DRY_RUN ? 'DRY RUN (no changes)' : 'EXECUTE'}\n`);
+
+ // Build lookup table
+ const lookupTable = buildLookupTable();
+
+ // Scan content files
+ const results = await scanContentFiles(lookupTable);
+
+ // Report findings
+ console.log('=== SCAN RESULTS ===\n');
+ console.log(`Files with links: ${results.filesWithLinks.length}`);
+ console.log(`Total links to migrate: ${results.totalLinks}`);
+ console.log(`Unmapped links: ${results.unmapped.length}\n`);
+
+ if (VERBOSE && results.filesWithLinks.length > 0) {
+ console.log('Links to migrate:');
+ for (const { file, links } of results.filesWithLinks) {
+ console.log(`\n ${file}:`);
+ for (const link of links) {
+ console.log(` ${link.oldLink}`);
+ console.log(` → ${link.newLink}`);
+ }
+ }
+ }
+
+ if (results.unmapped.length > 0) {
+ console.log('\n=== UNMAPPED LINKS (require manual review) ===\n');
+ for (const item of results.unmapped) {
+ console.log(` ${item.file}:`);
+ console.log(` ${item.match}`);
+ console.log(` Reason: ${item.reason}\n`);
+ }
+ }
+
+ // Apply migrations if not dry-run
+ if (DRY_RUN) {
+ console.log('\n[DRY RUN] No files modified. Run without --dry-run to apply changes.');
+ } else if (results.filesWithLinks.length > 0) {
+ await applyMigrations(results);
+ } else {
+ console.log('\nNo links to migrate.');
+ }
+}
+
+main().catch(console.error);
diff --git a/layouts/_default/LLMS-TXT-README.md b/layouts/LLMS-TXT-README.md
similarity index 63%
rename from layouts/_default/LLMS-TXT-README.md
rename to layouts/LLMS-TXT-README.md
index 0535d8f19..3d3900424 100644
--- a/layouts/_default/LLMS-TXT-README.md
+++ b/layouts/LLMS-TXT-README.md
@@ -8,26 +8,39 @@ The llms.txt format helps LLMs discover and understand documentation structure.
## Template Files
-### `index.llms.txt`
-- **Location**: `/layouts/index.llms.txt`
+### `index.llmstxt.txt`
+
+- **Location**: `/layouts/index.llmstxt.txt`
- **Output**: `/llms.txt` (site-level)
- **Type**: Hugo template
- **Purpose**: Primary entry point for LLM discovery
-- **Content**: Dynamically generated from `data/products.yml` with:
- - Product descriptions from data files
- - Organized by product category
- - Conditional rendering for optional products
+- **Content**: Hardcoded curated list of major product sections with:
+ - Direct links to product documentation
+ - Product descriptions
+ - Organized by product category (InfluxDB 3, InfluxDB 2, InfluxDB 1, Tools)
-### `section.llms.txt`
-- **Location**: `/layouts/_default/section.llms.txt`
-- **Output**: Product/section-level llms.txt files (e.g., `/influxdb3/core/llms.txt`)
-- **Type**: Hugo template
-- **Purpose**: Provide curated navigation for specific products/sections
+### `landing-influxdb.llms.txt`
+
+- **Location**: `/layouts/section/landing-influxdb.llms.txt`
+- **Output**: Section-level llms.txt files (e.g., `/influxdb3/core/llms.txt`)
+- **Type**: Hugo template (for `landing-influxdb` layout type)
+- **Purpose**: Provide curated navigation for specific products/sections with landing-influxdb layout
- **Content**: Dynamically generated from:
- Product metadata from `data/products.yml`
- Section content and child pages
- Page descriptions
+### `landing-influxdb.llmstxt.txt`
+
+- **Location**: `/layouts/_default/landing-influxdb.llmstxt.txt`
+- **Output**: Landing page llms.txt files
+- **Type**: Hugo template (for `landing-influxdb` layout type in \_default)
+- **Purpose**: Generate llms.txt for landing pages
+- **Content**: Dynamically generated from:
+ - Product metadata from `data/products.yml`
+ - Page title and description
+ - Child pages list
+
## Hugo Configuration
In `config/_default/hugo.yml`:
@@ -58,39 +71,47 @@ After building with `hugo`:
```
public/
-├── llms.txt # Site-level discovery file
+├── llms.txt # Site-level discovery file (from index.llmstxt.txt)
├── influxdb3/
│ ├── core/
-│ │ ├── llms.txt # InfluxDB 3 Core product index
-│ │ ├── get-started/
-│ │ │ └── llms.txt # Section-level index
-│ │ └── query-data/
-│ │ └── llms.txt # Section-level index
+│ │ └── llms.txt # InfluxDB 3 Core product index (landing-influxdb layout)
│ ├── cloud-dedicated/
-│ │ └── llms.txt # Cloud Dedicated product index
-│ └── cloud-serverless/
-│ └── llms.txt # Cloud Serverless product index
+│ │ └── llms.txt # Cloud Dedicated product index (landing-influxdb layout)
+│ ├── cloud-serverless/
+│ │ └── llms.txt # Cloud Serverless product index (landing-influxdb layout)
+│ └── clustered/
+│ └── llms.txt # Clustered product index (landing-influxdb layout)
+├── influxdb/
+│ ├── v2/
+│ │ └── llms.txt # InfluxDB v2 product index (landing-influxdb layout)
+│ └── cloud/
+│ └── llms.txt # InfluxDB Cloud TSM index (landing-influxdb layout)
├── telegraf/
│ └── v1/
-│ └── llms.txt # Telegraf product index
+│ └── llms.txt # Telegraf product index (landing-influxdb layout)
└── flux/
└── v0/
- └── llms.txt # Flux product index
+ └── llms.txt # Flux product index (landing-influxdb layout)
```
+Note: llms.txt files are only generated for pages with the `landing-influxdb` layout type and for the site root.
+
## llmstxt.org Specification Compliance
### Required Elements
+
- ✅ **H1 header**: Product or section name
- ✅ **Curated links**: Not exhaustive - intentionally selective
### Optional Elements
+
- ✅ **Blockquote summary**: Brief product/section description
- ✅ **Content paragraphs**: Additional context (NO headings allowed)
- ✅ **H2-delimited sections**: Organize links by category
- ✅ **Link format**: `[Title](url): Description`
### Key Rules
+
1. **H1 is required** - Only the product/section name
2. **Content sections cannot have headings** - Use paragraphs only
3. **Curate, don't list everything** - Be selective with links
@@ -101,24 +122,25 @@ public/
### For Site-Level (/llms.txt)
-Edit `/layouts/index.llms.txt` directly. This file is hardcoded for precise curation of top-level products.
+Edit `/layouts/index.llmstxt.txt` directly. This file is hardcoded for precise curation of top-level products.
-### For Product/Section-Level
+### For Product/Section-Level (landing-influxdb layout)
-The `/layouts/_default/section.llms.txt` template automatically generates llms.txt files for all sections.
+The `/layouts/section/landing-influxdb.llms.txt` template automatically generates llms.txt files for pages with the `landing-influxdb` layout type.
**To customize a specific product's llms.txt:**
1. Create a product-specific template following Hugo's lookup order:
```
- layouts/influxdb3/core/section.llms.txt # Specific to Core
- layouts/influxdb3/section.llms.txt # All InfluxDB 3 products
- layouts/_default/section.llms.txt # Default for all
+ layouts/influxdb3/core/landing-influxdb.llms.txt # Specific to Core
+ layouts/influxdb3/landing-influxdb.llms.txt # All InfluxDB 3 products
+ layouts/section/landing-influxdb.llms.txt # Default for all sections
```
2. **Example: Custom template for InfluxDB 3 Core**
- Create `/layouts/influxdb3/core/section.llms.txt`:
+ Create `/layouts/influxdb3/core/landing-influxdb.llms.txt`:
+
```
# InfluxDB 3 Core
@@ -137,6 +159,10 @@ The `/layouts/_default/section.llms.txt` template automatically generates llms.t
- [Query with SQL](/influxdb3/core/query-data/sql/): SQL query guide
```
+### For Landing Pages in \_default
+
+The `/layouts/_default/landing-influxdb.llmstxt.txt` template generates llms.txt for landing pages that use the default layout lookup.
+
### Using Product Metadata from data/products.yml
The template accesses product metadata:
@@ -206,7 +232,7 @@ llms.txt files are automatically generated during:
### Updating Site-Level llms.txt
-Edit `/layouts/index.llms.txt` to add/remove product links.
+Edit `/layouts/index.llmstxt.txt` to add/remove product links.
### Troubleshooting
@@ -223,4 +249,10 @@ Edit `/layouts/index.llms.txt` to add/remove product links.
- [llmstxt.org specification](https://llmstxt.org/)
- [Hugo output formats](https://gohugo.io/templates/output-formats/)
-- [InfluxData products.yml](../../data/products.yml)
+- [InfluxData products.yml](../data/products.yml)
+
+## Current Template Files
+
+- `/layouts/index.llmstxt.txt` - Root site llms.txt generator
+- `/layouts/section/landing-influxdb.llms.txt` - Section-level llms.txt for landing-influxdb layout
+- `/layouts/_default/landing-influxdb.llmstxt.txt` - Default landing page llms.txt generator
diff --git a/layouts/_default/api.html b/layouts/_default/api.html
index 68a09ae66..42987cb05 100644
--- a/layouts/_default/api.html
+++ b/layouts/_default/api.html
@@ -1 +1,111 @@
-{{ .Content }}
+{{/* API Documentation Default Layout Fallback layout for API documentation
+pages. Delegates to appropriate templates based on page type: - Section pages:
+Use section.html logic (children listing) - Pages with staticFilePath: Use
+Hugo-native renderer Note: This template exists as a catch-all but specific
+templates (api/section.html, api/list.html, api/single.html) should be
+preferred. */}}
+
+{{/* Extract product and version from URL path for download buttons */}}
+{{/* Example: /influxdb3/clustered/api/ → ["", "influxdb3", "clustered", "api", ""] */}}
+{{ $pathParts := split .RelPermalink "/" }}
+{{ $version := "" }}
+{{ if ge (len $pathParts) 3 }}
+ {{ $version = index $pathParts 2 }}
+{{ end }}
+
+{{/* Section pages without staticFilePath render content directly */}} {{ if and .IsSection (not .Params.staticFilePath)
+}} {{ partial "header.html" . }} {{ partial "topnav.html" . }}
+
+
+ {{ partial "sidebar.html" . }}
+
+
+
+
+
+ {{ .Title }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+
+
+ {{/* Dual download buttons for Clustered and Cloud Dedicated */}}
+ {{ if or (eq $version "clustered") (eq $version "cloud-dedicated") }}
+
+ {{ end }}
+
+ {{/* SECTION INDEX - Show page content then children listing */}} {{
+ with .Content }}
+ {{ . }}
+ {{ end }} {{/* Always show tag pages from article data */}} {{ partial
+ "api/section-children.html" . }} {{ partial "article/related.html" . }}
+
+
+
+
+
+
+
+{{ partial "footer.html" . }} {{ else }} {{/* Pages with staticFilePath
+(operation pages) use Hugo-native renderer */}} {{ partial "header.html" . }} {{
+partial "topnav.html" . }}
+
+
+ {{ partial "sidebar.html" . }}
+
+
+
+ {{ .Title }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+
+
+ {{/* Render API documentation using the configured renderer */}} {{
+ partial "api/renderer.html" . }}
+
+ © {{ now.Year }} InfluxData, Inc.
+
+
+
+{{ partial "footer.html" . }} {{ end }}
+
+
diff --git a/layouts/api/all-endpoints.html b/layouts/api/all-endpoints.html
new file mode 100644
index 000000000..b32fe8613
--- /dev/null
+++ b/layouts/api/all-endpoints.html
@@ -0,0 +1,48 @@
+{{/*
+ All Endpoints Layout
+
+ Shows all API operations on a single page, grouped by version and sorted by path.
+ Used for /api/all-endpoints/ pages.
+
+ Uses data from:
+ - data/article_data/influxdb/{product}/articles.yml
+*/}}
+
+{{ partial "header.html" . }}
+{{ partial "topnav.html" . }}
+
+
+ {{ partial "sidebar.html" . }}
+
+
+
+
+
+ {{ .Title }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+
+
+ {{ with .Content }}
+
+ {{ . }}
+
+ {{ end }}
+
+ {{/* Get all operations from article data */}}
+ {{ partial "api/all-endpoints-list.html" . }}
+
+ {{ partial "article/related.html" . }}
+
+
+
+
+
+
+
+
+{{ partial "footer.html" . }}
diff --git a/layouts/api/list.html b/layouts/api/list.html
new file mode 100644
index 000000000..452355078
--- /dev/null
+++ b/layouts/api/list.html
@@ -0,0 +1,200 @@
+{{/* API Documentation Layout
+ Two modes:
+ 1. Section index (no 'tag' param) - lists tag pages from article data
+ 2. Tag page (has 'tag' param) - shows operations via Hugo-native templates
+ Conceptual pages (isConceptual: true) show content without operations.
+*/}}
+
+
+{{ partial "header.html" . }} {{ partial "topnav.html" . }}
+
+
+ {{ partial "sidebar.html" . }}
+
+
+
+
+
+ {{ .Title }}
+ {{/* Only show description in header for section index pages */}}
+ {{ if not (isset .Params "tag") }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+ {{ end }}
+
+
+ {{ $hasTag := isset .Params "tag" }}
+ {{ if not $hasTag }}
+ {{/* SECTION INDEX - Show intro content then tag-based children */}}
+
+ {{ with .Content }}
+ {{ . }}
+ {{ end }}
+ {{ partial "api/section-children.html" . }}
+
+ {{ else }}
+ {{/* TAG PAGE - Show operations or conceptual content */}}
+ {{ $isConceptual := .Params.isConceptual | default false }}
+ {{ if $isConceptual }}
+
+ {{ with .Content }} {{ . }} {{ else }}
+ {{ with .Params.tagDescription }}{{ . | markdownify }}{{ end }}
+ {{ end }}
+
+
+ {{ else }}
+ {{/* Operational Page - Show all operations */}}
+
+ {{/* Download OpenAPI spec button — uses specDownloadPath from frontmatter */}}
+ {{ with .Params.specDownloadPath }}
+
+ {{ end }}
+
+ {{/* Hugo page content if any (for custom intro content) */}}
+ {{ with .Content }}
+ {{ . }}
+ {{ end }}
+
+ {{/* Render operations using Hugo-native templates */}}
+ {{ with .Params.staticFilePath }}
+
+ {{ partial "api/tag-renderer.html" $ }}
+
+ {{ end }} {{ end }} {{ end }} {{ partial "article/related.html" . }}
+
+
+
+ {{/* ON THIS PAGE TOC - Generated from operations array */}} {{ $operations
+ := .Params.operations }} {{ $hasTag := isset .Params "tag" }} {{
+ $isConceptual := .Params.isConceptual | default false }} {{ if and $hasTag
+ (not $isConceptual) }}
+
+ {{ else }}
+
+ {{ end }}
+
+
+
+{{ partial "footer.html" . }}
+
+
diff --git a/layouts/api/section.html b/layouts/api/section.html
new file mode 100644
index 000000000..84c5e298f
--- /dev/null
+++ b/layouts/api/section.html
@@ -0,0 +1,86 @@
+{{/* API Documentation Section Layout Used for API section index pages (e.g.,
+/influxdb3/core/api/). Shows page content with children listing.
+For tag pages (with 'tag' param), Hugo uses list.html instead.
+*/}}
+
+{{/* Extract product and version from URL path for download buttons */}}
+{{/* Example: /influxdb3/clustered/api/ → ["", "influxdb3", "clustered", "api", ""] */}}
+{{ $pathParts := split .RelPermalink "/" }}
+{{ $version := "" }}
+{{ if ge (len $pathParts) 3 }}
+ {{ $version = index $pathParts 2 }}
+{{ end }}
+
+{{ partial "header.html" . }} {{ partial "topnav.html" . }}
+
+
+ {{ partial "sidebar.html" . }}
+
+
+
+
+
+ {{ .Title }}
+ {{ with .Description }}
+ {{ . }}
+ {{ end }}
+
+
+ {{/* Dual download buttons for Clustered and Cloud Dedicated */}}
+ {{ if or (eq $version "clustered") (eq $version "cloud-dedicated") }}
+
+ {{ end }}
+
+ {{/* SECTION INDEX - Show intro content then tag-based children */}} {{
+ with .Content }}
+ {{ . }}
+ {{ end }} {{/* Always show tag pages from article data */}} {{ partial
+ "api/section-children.html" . }} {{ partial "article/related.html" . }}
+
+
+
+
+
+
+
+{{ partial "footer.html" . }}
+
+
diff --git a/layouts/api/single.html b/layouts/api/single.html
new file mode 100644
index 000000000..28a11e052
--- /dev/null
+++ b/layouts/api/single.html
@@ -0,0 +1,152 @@
+{{/*
+ API Documentation Single Page Layout
+
+ Used for:
+ - Conceptual pages (isConceptual: true) like Authentication, Quick start
+ - Individual operation pages (legacy - being phased out)
+
+ For conceptual pages:
+ - Shows Hugo content or tagDescription markdown
+
+ Required frontmatter:
+ - title: Page title
+ - isConceptual: true (for conceptual pages)
+*/}}
+
+{{ partial "header.html" . }}
+{{ partial "topnav.html" . }}
+
+
+ {{/* Left: Existing Hugo sidebar (includes API nav via sidebar.html) */}}
+ {{ partial "sidebar.html" . }}
+
+ {{/* Center + Right: Content and TOC */}}
+
+
+
+
+
+
+ {{/* For operation pages, show method badge with title */}}
+ {{ with .Params.method }}
+
+ {{ upper . }}
+ {{ $.Title }}
+
+ {{ with $.Params.path }}
+ {{ . }}
+ {{ end }}
+ {{ else }}
+ {{ .Title }}
+ {{ end }}
+
+ {{/* Summary/Description - skip for conceptual pages (shown in content section) */}}
+ {{ if not (.Params.isConceptual | default false) }}
+ {{ with .Params.summary }}
+ {{ . | markdownify }}
+ {{ else }}
+ {{ with .Description }}
+ {{ . | markdownify }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+
+ {{/* Download OpenAPI spec button - context-aware for Clustered/Cloud Dedicated */}}
+ {{ with .Params.staticFilePath }}
+ {{/* Extract product name from path like /openapi/influxdb-oss-v2/tags/... */}}
+ {{ $productName := replaceRE `^/openapi/([^/]+)/.*$` "$1" . }}
+
+ {{/* Check if this is a dual-API product (Clustered or Cloud Dedicated) */}}
+ {{ $isDualApi := or (strings.Contains $productName "clustered") (strings.Contains $productName "cloud-dedicated") }}
+
+ {{ if $isDualApi }}
+ {{/* Determine API type from path */}}
+ {{ $isManagementApi := strings.Contains . "management-api" }}
+ {{ if $isManagementApi }}
+ {{ $specPath := printf "/openapi/%s-management-api.yml" $productName }}
+
+ {{ else }}
+ {{ $specPath := printf "/openapi/%s-v2-data-api.yml" $productName }}
+
+ {{ end }}
+ {{ else }}
+ {{/* Single-spec products - existing behavior */}}
+ {{ $completeSpecPath := printf "/openapi/%s.yml" $productName }}
+
+ {{ end }}
+ {{ end }}
+
+
+
+ {{ $isConceptual := .Params.isConceptual | default false }}
+
+ {{ if $isConceptual }}
+ {{/* Conceptual Page - Show content directly */}}
+
+ {{ with .Content }}
+ {{ . }}
+ {{ else }}
+ {{ with .Params.tagDescription }}
+ {{ . | markdownify }}
+ {{ end }}
+ {{ end }}
+
+
+ {{/* Security Schemes from OpenAPI spec (only show if showSecuritySchemes: true) */}}
+ {{ if .Params.showSecuritySchemes }}
+ {{ partial "api/security-schemes.html" . }}
+ {{ end }}
+ {{ else }}
+ {{/* Operation Page - Hugo-native rendering */}}
+ {{/* Note: Individual operation pages are being phased out. */}}
+ {{/* Operations are now accessed via tag pages only. */}}
+
+ {{/* Hugo page content shown as overview */}}
+ {{ with .Content }}
+
+ {{ . }}
+
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Related documentation links */}}
+ {{ partial "article/related.html" . }}
+
+
+
+
+ {{/* Right: Page TOC - "ON THIS PAGE" */}}
+
+
+
+
+{{ partial "footer.html" . }}
diff --git a/layouts/partials/api/all-endpoints-list.html b/layouts/partials/api/all-endpoints-list.html
new file mode 100644
index 000000000..5bab0333a
--- /dev/null
+++ b/layouts/partials/api/all-endpoints-list.html
@@ -0,0 +1,221 @@
+{{/*
+ All Endpoints List
+
+ Renders all API operations grouped by version (v3, v2, v1) and sorted by path.
+ Links point to tag pages with hash anchors (e.g., /api/cache-data/#operation/PostConfigureDistinctCache)
+ Excludes conceptual/trait tag operations.
+
+ Uses frontmatter params:
+ - articleDataKey: product data key (e.g., 'influxdb3-core')
+ - articleSection: section slug (e.g., 'api' or 'management-api')
+*/}}
+{{ $currentPage := . }}
+
+{{/* Read data key and section from frontmatter */}}
+{{ $dataKey := .Params.articleDataKey | default "" }}
+{{ $section := .Params.articleSection | default "" }}
+
+{{/* Get article data using frontmatter-driven lookup */}}
+{{ $articles := slice }}
+{{ if and $dataKey $section }}
+ {{ with site.Data.article_data }}
+ {{ with index . "influxdb" }}
+ {{ with index . $dataKey }}
+ {{ with index . $section }}
+ {{ with index . "articles" }}
+ {{ with .articles }}
+ {{ $articles = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Build a map of tag name -> article path for URL lookups */}}
+{{ $tagToPath := dict }}
+{{ range $articles }}
+ {{ if and (reflect.IsMap .) (isset . "fields") }}
+ {{ $fields := index . "fields" }}
+ {{ if reflect.IsMap $fields }}
+ {{ if isset $fields "tag" }}
+ {{ $tag := index $fields "tag" }}
+ {{ $path := index . "path" }}
+ {{ $tagToPath = merge $tagToPath (dict $tag $path) }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Collect all operations from non-conceptual articles */}}
+{{ $allOperations := slice }}
+{{ range $articles }}
+ {{ if and (reflect.IsMap .) (isset . "fields") }}
+ {{ $fields := index . "fields" }}
+ {{ if reflect.IsMap $fields }}
+ {{ $isConceptual := false }}
+ {{ if isset $fields "isConceptual" }}
+ {{ $isConceptual = index $fields "isConceptual" }}
+ {{ end }}
+ {{ if not $isConceptual }}
+ {{ if isset $fields "operations" }}
+ {{ $tag := index $fields "tag" }}
+ {{ $articlePath := index . "path" }}
+ {{ range index $fields "operations" }}
+ {{ $allOperations = $allOperations | append (dict "op" . "tag" $tag "articlePath" $articlePath) }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{ if gt (len $allOperations) 0 }}
+ {{/* Group operations by API version prefix */}}
+ {{ $v3Ops := slice }}
+ {{ $v2Ops := slice }}
+ {{ $v1Ops := slice }}
+ {{ $otherOps := slice }}
+
+ {{ range $allOperations }}
+ {{ $path := .op.path }}
+ {{ if hasPrefix $path "/api/v3" }}
+ {{ $v3Ops = $v3Ops | append . }}
+ {{ else if hasPrefix $path "/api/v2" }}
+ {{ $v2Ops = $v2Ops | append . }}
+ {{ else if or (hasPrefix $path "/api/v1") (hasPrefix $path "/health") (hasPrefix $path "/ping") (hasPrefix $path "/metrics") (hasPrefix $path "/query") (hasPrefix $path "/write") }}
+ {{ $v1Ops = $v1Ops | append . }}
+ {{ else }}
+ {{ $otherOps = $otherOps | append . }}
+ {{ end }}
+ {{ end }}
+
+ {{/* Sort each group by path then method */}}
+ {{ $sortV3 := slice }}
+ {{ range $v3Ops }}
+ {{ $sortKey := printf "%s %s" .op.path (upper .op.method) }}
+ {{ $sortV3 = $sortV3 | append (dict "sortKey" $sortKey "data" .) }}
+ {{ end }}
+ {{ $sortV3 = sort $sortV3 "sortKey" }}
+
+ {{ $sortV2 := slice }}
+ {{ range $v2Ops }}
+ {{ $sortKey := printf "%s %s" .op.path (upper .op.method) }}
+ {{ $sortV2 = $sortV2 | append (dict "sortKey" $sortKey "data" .) }}
+ {{ end }}
+ {{ $sortV2 = sort $sortV2 "sortKey" }}
+
+ {{ $sortV1 := slice }}
+ {{ range $v1Ops }}
+ {{ $sortKey := printf "%s %s" .op.path (upper .op.method) }}
+ {{ $sortV1 = $sortV1 | append (dict "sortKey" $sortKey "data" .) }}
+ {{ end }}
+ {{ $sortV1 = sort $sortV1 "sortKey" }}
+
+ {{/* Render v3 API endpoints */}}
+ {{ if gt (len $sortV3) 0 }}
+
+ v3 API
+
+ {{ range $sortV3 }}
+ {{ $op := .data.op }}
+ {{ $articlePath := .data.articlePath }}
+ {{/* Build tag page URL with hash anchor: operation/{operationId} */}}
+ {{/* Build tag page URL relative to the section (parent of all-endpoints) */}}
+ {{ $sectionUrl := $currentPage.Parent.RelPermalink }}
+ {{ $tagSlug := path.Base $articlePath }}
+ {{ $tagPageUrl := printf "%s%s/" $sectionUrl $tagSlug }}
+ {{ $hashAnchor := printf "#operation/%s" $op.operationId }}
+
+ {{ upper $op.method }}
+ {{ $op.path }}
+ {{ $op.summary }}
+
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Render v2-compatible endpoints */}}
+ {{ if gt (len $sortV2) 0 }}
+
+ v2-compatible API
+
+ {{ range $sortV2 }}
+ {{ $op := .data.op }}
+ {{ $articlePath := .data.articlePath }}
+ {{/* Build tag page URL with hash anchor: operation/{operationId} */}}
+ {{/* Build tag page URL relative to the section (parent of all-endpoints) */}}
+ {{ $sectionUrl := $currentPage.Parent.RelPermalink }}
+ {{ $tagSlug := path.Base $articlePath }}
+ {{ $tagPageUrl := printf "%s%s/" $sectionUrl $tagSlug }}
+ {{ $hashAnchor := printf "#operation/%s" $op.operationId }}
+
+ {{ upper $op.method }}
+ {{ $op.path }}
+ {{ $op.summary }}
+ {{ with $op.compatVersion }}{{ . }}{{ end }}
+
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Render v1-compatible endpoints */}}
+ {{ if gt (len $sortV1) 0 }}
+
+ v1-compatible API
+
+ {{ range $sortV1 }}
+ {{ $op := .data.op }}
+ {{ $articlePath := .data.articlePath }}
+ {{/* Build tag page URL with hash anchor: operation/{operationId} */}}
+ {{/* Build tag page URL relative to the section (parent of all-endpoints) */}}
+ {{ $sectionUrl := $currentPage.Parent.RelPermalink }}
+ {{ $tagSlug := path.Base $articlePath }}
+ {{ $tagPageUrl := printf "%s%s/" $sectionUrl $tagSlug }}
+ {{ $hashAnchor := printf "#operation/%s" $op.operationId }}
+
+ {{ upper $op.method }}
+ {{ $op.path }}
+ {{ $op.summary }}
+ {{ with $op.compatVersion }}{{ . }}{{ end }}
+
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Render Management API endpoints (paths not matching v1/v2/v3 patterns) */}}
+ {{ if gt (len $otherOps) 0 }}
+ {{ $sortOther := slice }}
+ {{ range $otherOps }}
+ {{ $sortKey := printf "%s %s" .op.path (upper .op.method) }}
+ {{ $sortOther = $sortOther | append (dict "sortKey" $sortKey "data" .) }}
+ {{ end }}
+ {{ $sortOther = sort $sortOther "sortKey" }}
+
+ Management API
+
+ {{ range $sortOther }}
+ {{ $op := .data.op }}
+ {{ $articlePath := .data.articlePath }}
+ {{/* Build tag page URL with hash anchor: operation/{operationId} */}}
+ {{/* Build tag page URL relative to the section (parent of all-endpoints) */}}
+ {{ $sectionUrl := $currentPage.Parent.RelPermalink }}
+ {{ $tagSlug := path.Base $articlePath }}
+ {{ $tagPageUrl := printf "%s%s/" $sectionUrl $tagSlug }}
+ {{ $hashAnchor := printf "#operation/%s" $op.operationId }}
+
+ {{ upper $op.method }}
+ {{ $op.path }}
+ {{ $op.summary }}
+
+ {{ end }}
+
+
+ {{ end }}
+{{ else }}
+ No endpoints available.
+{{ end }}
diff --git a/layouts/partials/api/code-sample.html b/layouts/partials/api/code-sample.html
new file mode 100644
index 000000000..c8787de74
--- /dev/null
+++ b/layouts/partials/api/code-sample.html
@@ -0,0 +1,235 @@
+{{/*
+ API Code Sample
+
+ Renders an inline curl example for an API operation, constructed from the
+ OpenAPI spec at Hugo build time. The existing influxdb-url.js replaces
+ the default host in elements if the user has a custom URL set.
+
+ Params:
+ - opDef: The operation definition from the parsed spec
+ - operation: Operation metadata from frontmatter (method, path, summary, operationId)
+ - spec: The full OpenAPI spec object for resolving $ref
+ - context: The page context
+*/}}
+
+{{ $opDef := .opDef }}
+{{ $operation := .operation }}
+{{ $spec := .spec }}
+{{ $method := upper $operation.method }}
+{{ $path := $operation.path }}
+
+{{/* --- Resolve server URL --- */}}
+{{ $serverUrl := "" }}
+{{ with index ($spec.servers | default slice) 0 }}
+ {{ $serverUrl = .url | default "" }}
+ {{/* Resolve {variable} placeholders using variable defaults */}}
+ {{ range $varName, $varDef := .variables | default dict }}
+ {{ $placeholder := printf "{%s}" $varName }}
+ {{ $serverUrl = replace $serverUrl $placeholder ($varDef.default | default "") }}
+ {{ end }}
+{{ end }}
+{{ if not $serverUrl }}
+ {{ $serverUrl = "http://localhost:8086" }}
+{{ end }}
+
+{{/* --- Resolve parameters (handle $ref) --- */}}
+{{ $params := $opDef.parameters | default slice }}
+{{ $resolvedParams := slice }}
+{{ range $params }}
+ {{ $param := . }}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $paramName := index $refParts 3 }}
+ {{ with index $spec.components.parameters $paramName }}
+ {{ $param = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ $resolvedParams = $resolvedParams | append $param }}
+{{ end }}
+
+{{/* --- Build query string from required query parameters --- */}}
+{{ $queryParts := slice }}
+{{ range $resolvedParams }}
+ {{ if and (eq .in "query") .required }}
+ {{ $value := "" }}
+ {{ with .schema }}
+ {{ if .example }}
+ {{ $value = .example | string }}
+ {{ else if .default }}
+ {{ $value = .default | string }}
+ {{ end }}
+ {{ end }}
+ {{ if not $value }}
+ {{ $value = .name | upper | replaceRE "[^A-Z0-9]" "_" }}
+ {{ end }}
+ {{ $queryParts = $queryParts | append (printf "%s=%s" .name $value) }}
+ {{ end }}
+{{ end }}
+
+{{ $fullUrl := printf "%s%s" $serverUrl $path }}
+{{ if gt (len $queryParts) 0 }}
+ {{ $fullUrl = printf "%s?%s" $fullUrl (delimit $queryParts "&") }}
+{{ end }}
+
+{{/* --- Resolve request body (handle $ref) --- */}}
+{{ $requestBody := $opDef.requestBody | default dict }}
+{{ if isset $requestBody "$ref" }}
+ {{ $refPath := index $requestBody "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $rbName := index $refParts 3 }}
+ {{ with index $spec.components.requestBodies $rbName }}
+ {{ $requestBody = . }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* --- Determine content type and body --- */}}
+{{ $contentType := "" }}
+{{ $bodyFlag := "" }}
+{{ $rbContent := $requestBody.content | default dict }}
+{{ if gt (len $rbContent) 0 }}
+ {{/* Get first content type key */}}
+ {{ range $ct, $_ := $rbContent }}
+ {{ if not $contentType }}
+ {{ $contentType = $ct }}
+ {{ end }}
+ {{ end }}
+
+ {{ $mediaType := index $rbContent $contentType | default dict }}
+
+ {{ if hasPrefix $contentType "text/plain" }}
+ {{/* Line protocol — use first example value or a default sample */}}
+ {{ $lpSample := "measurement,tag=value field=1.0" }}
+ {{ with $mediaType.examples }}
+ {{ range $_, $ex := . }}
+ {{ if not $bodyFlag }}
+ {{ $lpSample = $ex.value | string }}
+ {{/* Take only the first line for single-line display */}}
+ {{ $lines := split $lpSample "\n" }}
+ {{ $lpSample = index $lines 0 }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ $bodyFlag = printf "--data-raw '%s'" $lpSample }}
+ {{ else if hasPrefix $contentType "application/json" }}
+ {{/* JSON — use schema.example, or build from properties */}}
+ {{ with $mediaType.schema }}
+ {{/* Resolve schema $ref */}}
+ {{ $schema := . }}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $schemaName := index $refParts 3 }}
+ {{ with index $spec.components.schemas $schemaName }}
+ {{ $schema = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ if $schema.example }}
+ {{ $bodyFlag = printf "--data-raw '%s'" (jsonify $schema.example) }}
+ {{ else if $schema.properties }}
+ {{/* Build example JSON from schema properties */}}
+ {{ $bodyObj := dict }}
+ {{ $requiredList := $schema.required | default slice }}
+ {{ range $propName, $propDef := $schema.properties }}
+ {{/* Resolve property $ref */}}
+ {{ $prop := $propDef }}
+ {{ if isset $propDef "$ref" }}
+ {{ $pRefPath := index $propDef "$ref" }}
+ {{ $pRefParts := split $pRefPath "/" }}
+ {{ if ge (len $pRefParts) 4 }}
+ {{ $pSchemaName := index $pRefParts 3 }}
+ {{ with index $spec.components.schemas $pSchemaName }}
+ {{ $prop = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{/* Use example → default → enum[0] → type placeholder */}}
+ {{ $val := "" }}
+ {{ if ne $prop.example nil }}
+ {{ $val = $prop.example }}
+ {{ else if ne $prop.default nil }}
+ {{ $val = $prop.default }}
+ {{ else if $prop.enum }}
+ {{ $val = index $prop.enum 0 }}
+ {{ else if eq $prop.type "string" }}
+ {{ $val = printf "%s" ($propName | upper) }}
+ {{ else if eq $prop.type "integer" }}
+ {{ $val = 0 }}
+ {{ else if eq $prop.type "number" }}
+ {{ $val = 0 }}
+ {{ else if eq $prop.type "boolean" }}
+ {{ $val = false }}
+ {{ else if eq $prop.type "array" }}
+ {{ if $prop.items }}
+ {{ if eq $prop.items.type "string" }}
+ {{ $val = slice "example" }}
+ {{ else }}
+ {{ $val = slice }}
+ {{ end }}
+ {{ else }}
+ {{ $val = slice }}
+ {{ end }}
+ {{ else if eq $prop.type "object" }}
+ {{ $val = dict }}
+ {{ else }}
+ {{ $val = printf "%s" ($propName | upper) }}
+ {{ end }}
+ {{ $bodyObj = merge $bodyObj (dict $propName $val) }}
+ {{ end }}
+ {{ $bodyFlag = printf "--data-raw '%s'" (jsonify (dict "indent" " ") $bodyObj) }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* --- Assemble curl command --- */}}
+{{ $lines := slice }}
+{{ $lines = $lines | append (printf "curl --request %s \\" $method) }}
+{{ $lines = $lines | append (printf " \"%s\" \\" $fullUrl) }}
+{{ $lines = $lines | append " --header \"Authorization: Bearer INFLUX_TOKEN\" \\" }}
+{{ if $contentType }}
+ {{ $lines = $lines | append (printf " --header \"Content-Type: %s\" \\" $contentType) }}
+{{ end }}
+{{ if $bodyFlag }}
+ {{/* Last line — no trailing backslash */}}
+ {{ $lines = $lines | append (printf " %s" $bodyFlag) }}
+{{ else }}
+ {{/* Remove trailing backslash from last header line */}}
+ {{ $lastIdx := sub (len $lines) 1 }}
+ {{ $lastLine := index $lines $lastIdx }}
+ {{ $lastLine = strings.TrimSuffix " \\" $lastLine }}
+ {{ $newLines := slice }}
+ {{ range $i, $line := $lines }}
+ {{ if eq $i $lastIdx }}
+ {{ $newLines = $newLines | append $lastLine }}
+ {{ else }}
+ {{ $newLines = $newLines | append $line }}
+ {{ end }}
+ {{ end }}
+ {{ $lines = $newLines }}
+{{ end }}
+
+{{ $curlCommand := delimit $lines "\n" }}
+
+{{/* --- Build Ask AI query --- */}}
+{{ $aiQuery := printf "Explain this %s %s API request and its response: %s" $method $path ($operation.summary | default "") }}
+
+{{/* --- Render --- */}}
+
+
+ Example request
+
+ Ask AI about this
+
+
+
+ {{ $curlCommand }}
+
+
diff --git a/layouts/partials/api/normalize-path.html b/layouts/partials/api/normalize-path.html
new file mode 100644
index 000000000..7f3735a64
--- /dev/null
+++ b/layouts/partials/api/normalize-path.html
@@ -0,0 +1,22 @@
+{{/*
+ Normalize API path for URL generation
+
+ Transforms an API path to a URL-friendly slug:
+ 1. Strips leading "/api" prefix (parent directory provides /api/)
+ 2. Adds v1/ prefix for paths without a version (e.g., /write → v1/write)
+ 3. Strips leading "/" to avoid double slashes
+ 4. Removes curly braces from path parameters (e.g., {db} → db)
+
+ Parameters:
+ - path: The API path (e.g., "/write", "/api/v3/engine/{request_path}")
+
+ Returns: URL-safe path slug (e.g., "v1/write", "v3/engine/request_path")
+*/}}
+{{ $path := . | strings.TrimPrefix "/api" }}
+{{ if not (findRE `^/v\d+/` $path) }}
+ {{ $path = printf "/v1%s" $path }}
+{{ end }}
+{{ $path = $path | strings.TrimPrefix "/" }}
+{{/* Remove curly braces from path parameters */}}
+{{ $path = replaceRE `[{}]` "" $path }}
+{{ return $path }}
diff --git a/layouts/partials/api/operation.html b/layouts/partials/api/operation.html
new file mode 100644
index 000000000..12fb7881a
--- /dev/null
+++ b/layouts/partials/api/operation.html
@@ -0,0 +1,69 @@
+{{/*
+ Hugo-Native Operation Renderer
+
+ Renders a single API operation with parameters, request body, and responses.
+ Styled to match docusaurus-openapi aesthetic.
+
+ Params:
+ - operation: Map with method, path, summary, operationId
+ - spec: The full OpenAPI spec object
+ - context: The page context for URL generation
+*/}}
+
+{{ $operation := .operation }}
+{{ $spec := .spec }}
+{{ $method := lower $operation.method }}
+{{ $path := $operation.path }}
+{{ $operationId := $operation.operationId }}
+
+{{/* Find the operation definition in the spec */}}
+{{ $pathDef := index $spec.paths $path }}
+{{ $opDef := dict }}
+{{ if $pathDef }}
+ {{ $opDef = index $pathDef $method | default dict }}
+{{ end }}
+
+{{/* Generate anchor ID matching Redocly operation/{operationId} format */}}
+{{ $anchorId := printf "operation/%s" $operationId }}
+
+
+ {{/* Operation Header */}}
+
+
+ {{ upper $method }}
+ {{ $path }}
+
+ {{ $operation.summary }}
+
+
+ {{/* Operation Description */}}
+ {{ with $opDef.description }}
+
+ {{ . | markdownify }}
+
+ {{ end }}
+
+ {{/* Parameters Section */}}
+ {{ $params := $opDef.parameters | default slice }}
+ {{ if gt (len $params) 0 }}
+ {{ partial "api/parameters.html" (dict "parameters" $params "spec" $spec) }}
+ {{ end }}
+
+ {{/* Request Body Section */}}
+ {{ with $opDef.requestBody }}
+ {{ partial "api/request-body.html" (dict "requestBody" . "spec" $spec) }}
+ {{ end }}
+
+ {{/* Code Sample Section */}}
+ {{ partial "api/code-sample.html" (dict
+ "opDef" $opDef
+ "operation" $operation
+ "spec" $spec
+ "context" .context
+ ) }}
+
+ {{/* Responses Section */}}
+ {{ with $opDef.responses }}
+ {{ partial "api/responses.html" (dict "responses" . "spec" $spec) }}
+ {{ end }}
+
diff --git a/layouts/partials/api/parameter-row.html b/layouts/partials/api/parameter-row.html
new file mode 100644
index 000000000..5f34125a9
--- /dev/null
+++ b/layouts/partials/api/parameter-row.html
@@ -0,0 +1,65 @@
+{{/*
+ Hugo-Native Parameter Row Renderer
+
+ Renders a single parameter with name, type, required badge, and description.
+
+ Params:
+ - param: Parameter object with name, schema, required, description
+ - spec: The full OpenAPI spec object for resolving schema $ref
+*/}}
+
+{{ $param := .param }}
+{{ $spec := .spec }}
+
+{{ $name := $param.name }}
+{{ $required := $param.required | default false }}
+{{ $description := $param.description | default "" }}
+
+{{/* Resolve schema type */}}
+{{ $schema := $param.schema | default dict }}
+{{ $type := $schema.type | default "string" }}
+{{ $format := $schema.format | default "" }}
+{{ $enum := $schema.enum | default slice }}
+{{ $default := $schema.default }}
+
+{{/* Build type display string */}}
+{{ $typeDisplay := $type }}
+{{ if $format }}
+ {{ $typeDisplay = printf "%s <%s>" $type $format }}
+{{ end }}
+
+
+
+
+ {{ $name }}
+ {{ if $required }}
+ required
+ {{ end }}
+ {{ $typeDisplay }}
+
+
+ {{ if $description }}
+
+ {{ $description | markdownify }}
+
+ {{ end }}
+
+ {{/* Show enum values if present */}}
+ {{ if gt (len $enum) 0 }}
+
+ Allowed values:
+ {{ range $i, $val := $enum }}
+ {{ if $i }}, {{ end }}{{ $val }}
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Show default value if present */}}
+ {{ if $default }}
+
+ Default:
+ {{ $default }}
+
+ {{ end }}
+
+
diff --git a/layouts/partials/api/parameters.html b/layouts/partials/api/parameters.html
new file mode 100644
index 000000000..4285feafd
--- /dev/null
+++ b/layouts/partials/api/parameters.html
@@ -0,0 +1,85 @@
+{{/*
+ Hugo-Native Parameters Renderer
+
+ Renders a table of API operation parameters (query, path, header).
+ Resolves $ref references to component parameters.
+
+ Params:
+ - parameters: Array of parameter objects
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $parameters := .parameters }}
+{{ $spec := .spec }}
+
+{{/* Resolve $ref parameters and group by location */}}
+{{ $queryParams := slice }}
+{{ $pathParams := slice }}
+{{ $headerParams := slice }}
+
+{{ range $parameters }}
+ {{ $param := . }}
+
+ {{/* Resolve $ref if present */}}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{/* Parse ref like "#/components/parameters/db" */}}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $paramName := index $refParts 3 }}
+ {{ with index $spec.components.parameters $paramName }}
+ {{ $param = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{/* Group by 'in' location */}}
+ {{ $location := $param.in | default "query" }}
+ {{ if eq $location "query" }}
+ {{ $queryParams = $queryParams | append $param }}
+ {{ else if eq $location "path" }}
+ {{ $pathParams = $pathParams | append $param }}
+ {{ else if eq $location "header" }}
+ {{ $headerParams = $headerParams | append $param }}
+ {{ end }}
+{{ end }}
+
+
+ Parameters
+
+ {{/* Path Parameters */}}
+ {{ if gt (len $pathParams) 0 }}
+
+ Path parameters
+
+ {{ range $pathParams }}
+ {{ partial "api/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Query Parameters */}}
+ {{ if gt (len $queryParams) 0 }}
+
+ Query parameters
+
+ {{ range $queryParams }}
+ {{ partial "api/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
+ {{/* Header Parameters */}}
+ {{ if gt (len $headerParams) 0 }}
+
+ Header parameters
+
+ {{ range $headerParams }}
+ {{ partial "api/parameter-row.html" (dict "param" . "spec" $spec) }}
+ {{ end }}
+
+
+ {{ end }}
+
diff --git a/layouts/partials/api/renderer.html b/layouts/partials/api/renderer.html
new file mode 100644
index 000000000..d2b32f308
--- /dev/null
+++ b/layouts/partials/api/renderer.html
@@ -0,0 +1,12 @@
+{{/*
+ API Renderer
+
+ Renders API documentation using Hugo-native templates.
+ This partial is maintained for backward compatibility.
+
+ Required page params:
+ - staticFilePath: Path to the OpenAPI specification file
+ - operations: Array of operation metadata
+*/}}
+
+{{ partial "api/tag-renderer.html" . }}
diff --git a/layouts/partials/api/request-body.html b/layouts/partials/api/request-body.html
new file mode 100644
index 000000000..9663c8d56
--- /dev/null
+++ b/layouts/partials/api/request-body.html
@@ -0,0 +1,60 @@
+{{/*
+ Hugo-Native Request Body Renderer
+
+ Renders the request body section including schema properties.
+
+ Params:
+ - requestBody: OpenAPI requestBody object
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $requestBody := .requestBody }}
+{{ $spec := .spec }}
+
+{{ $required := $requestBody.required | default false }}
+{{ $description := $requestBody.description | default "" }}
+
+{{/* Get content schema - typically application/json */}}
+{{ $content := $requestBody.content | default dict }}
+{{ $jsonContent := index $content "application/json" | default dict }}
+{{ $schema := $jsonContent.schema | default dict }}
+
+{{/* Resolve $ref if present */}}
+{{ $resolvedSchema := $schema }}
+{{ if isset $schema "$ref" }}
+ {{ $refPath := index $schema "$ref" }}
+ {{/* Parse ref like "#/components/schemas/DistinctCacheCreateRequest" */}}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $schemaName := index $refParts 3 }}
+ {{ with index $spec.components.schemas $schemaName }}
+ {{ $resolvedSchema = . }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+
+
+ Request body
+ {{ if $required }}
+ required
+ {{ end }}
+
+
+ {{ if $description }}
+
+ {{ $description | markdownify }}
+
+ {{ end }}
+
+ {{/* Content type indicator */}}
+
+ Content-Type:
+ application/json
+
+
+ {{/* Render schema properties */}}
+ {{ with $resolvedSchema }}
+ {{ partial "api/schema.html" (dict "schema" . "spec" $spec "level" 0) }}
+ {{ end }}
+
diff --git a/layouts/partials/api/responses.html b/layouts/partials/api/responses.html
new file mode 100644
index 000000000..3973a431d
--- /dev/null
+++ b/layouts/partials/api/responses.html
@@ -0,0 +1,79 @@
+{{/*
+ Hugo-Native Responses Renderer
+
+ Renders the responses section for an API operation.
+ Shows status codes, descriptions, and response schemas.
+
+ Params:
+ - responses: Map of status codes to response objects
+ - spec: The full OpenAPI spec object for resolving $ref
+*/}}
+
+{{ $responses := .responses }}
+{{ $spec := .spec }}
+
+
+ Responses
+
+
+ {{ range $statusCode, $response := $responses }}
+ {{/* Resolve $ref if present */}}
+ {{ $resolvedResponse := $response }}
+ {{ if isset $response "$ref" }}
+ {{ $refPath := index $response "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $responseName := index $refParts 3 }}
+ {{ with index $spec.components.responses $responseName }}
+ {{ $resolvedResponse = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ $description := $resolvedResponse.description | default "" }}
+ {{ $content := $resolvedResponse.content | default dict }}
+
+ {{/* Determine status category for styling */}}
+ {{ $statusCategory := "info" }}
+ {{ if hasPrefix $statusCode "2" }}
+ {{ $statusCategory = "success" }}
+ {{ else if hasPrefix $statusCode "3" }}
+ {{ $statusCategory = "redirect" }}
+ {{ else if hasPrefix $statusCode "4" }}
+ {{ $statusCategory = "client-error" }}
+ {{ else if hasPrefix $statusCode "5" }}
+ {{ $statusCategory = "server-error" }}
+ {{ end }}
+
+
+
+ {{ $statusCode }}
+ {{ $description }}
+
+
+ {{/* Response body schema if present */}}
+ {{ with $content }}
+ {{ $jsonContent := index . "application/json" | default dict }}
+ {{ with $jsonContent.schema }}
+ {{/* Resolve schema $ref if present */}}
+ {{ $resolvedSchema := . }}
+ {{ if isset . "$ref" }}
+ {{ $refPath := index . "$ref" }}
+ {{ $refParts := split $refPath "/" }}
+ {{ if ge (len $refParts) 4 }}
+ {{ $schemaName := index $refParts 3 }}
+ {{ with index $spec.components.schemas $schemaName }}
+ {{ $resolvedSchema = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+
+ {{ partial "api/schema.html" (dict "schema" $resolvedSchema "spec" $spec "level" 0) }}
+
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+
diff --git a/layouts/partials/api/schema.html b/layouts/partials/api/schema.html
new file mode 100644
index 000000000..29d1eb704
--- /dev/null
+++ b/layouts/partials/api/schema.html
@@ -0,0 +1,117 @@
+{{/*
+ Hugo-Native Schema Renderer
+
+ Renders a JSON schema as a property table with nested object support.
+ Similar to docusaurus-openapi's schema tables.
+
+ Params:
+ - schema: OpenAPI schema object
+ - spec: The full OpenAPI spec object for resolving $ref
+ - level: Nesting level (0 = root)
+*/}}
+
+{{ $schema := .schema }}
+{{ $spec := .spec }}
+{{ $level := .level | default 0 }}
+
+{{ $type := $schema.type | default "object" }}
+{{ $properties := $schema.properties | default dict }}
+{{ $required := $schema.required | default slice }}
+{{ $example := $schema.example }}
+
+{{/* Convert required slice to map for easy lookup */}}
+{{ $requiredMap := dict }}
+{{ range $required }}
+ {{ $requiredMap = merge $requiredMap (dict . true) }}
+{{ end }}
+
+
+ {{ if gt (len $properties) 0 }}
+
+ {{ range $propName, $propSchema := $properties }}
+ {{ $isRequired := index $requiredMap $propName | default false }}
+ {{ $propType := $propSchema.type | default "string" }}
+ {{ $propDescription := $propSchema.description | default "" }}
+ {{ $propFormat := $propSchema.format | default "" }}
+ {{ $propEnum := $propSchema.enum | default slice }}
+ {{ $propDefault := $propSchema.default }}
+ {{ $propExample := $propSchema.example }}
+
+ {{/* Build type display */}}
+ {{ $typeDisplay := $propType }}
+ {{ if eq $propType "array" }}
+ {{ $itemsType := "object" }}
+ {{ with $propSchema.items }}
+ {{ $itemsType = .type | default "object" }}
+ {{ end }}
+ {{ $typeDisplay = printf "%s[]" $itemsType }}
+ {{ else if $propFormat }}
+ {{ $typeDisplay = printf "%s <%s>" $propType $propFormat }}
+ {{ end }}
+
+
+
+ {{ $propName }}
+ {{ if $isRequired }}
+ required
+ {{ end }}
+ {{ $typeDisplay }}
+
+
+ {{ if $propDescription }}
+
+ {{ $propDescription | markdownify }}
+
+ {{ end }}
+
+ {{/* Enum values */}}
+ {{ if gt (len $propEnum) 0 }}
+
+ Allowed:
+ {{ range $i, $val := $propEnum }}
+ {{ if $i }}, {{ end }}{{ $val }}
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Default value */}}
+ {{ if $propDefault }}
+
+ Default:
+ {{ $propDefault }}
+
+ {{ end }}
+
+ {{/* Example value */}}
+ {{ if $propExample }}
+
+ Example:
+ {{ jsonify $propExample }}
+
+ {{ end }}
+
+ {{/* Nested object/array rendering (limit depth to prevent infinite loops) */}}
+ {{ if and (eq $propType "object") (lt $level 2) }}
+ {{ with $propSchema.properties }}
+ {{ partial "api/schema.html" (dict "schema" $propSchema "spec" $spec "level" (add $level 1)) }}
+ {{ end }}
+ {{ else if and (eq $propType "array") (lt $level 2) }}
+ {{ with $propSchema.items }}
+ {{ if isset . "properties" }}
+ {{ partial "api/schema.html" (dict "schema" . "spec" $spec "level" (add $level 1)) }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{ end }}
+
+ {{ end }}
+
+ {{/* Show example at schema level */}}
+ {{ if and $example (eq $level 0) }}
+
+ Example request body
+ {{ jsonify (dict "indent" " ") $example }}
+
+ {{ end }}
+
diff --git a/layouts/partials/api/section-children.html b/layouts/partials/api/section-children.html
new file mode 100644
index 000000000..c217ce5b5
--- /dev/null
+++ b/layouts/partials/api/section-children.html
@@ -0,0 +1,112 @@
+{{/*
+ API Section Children
+
+ Renders tag pages from article data as a children list.
+ Sort order: conceptual tags (traitTags) first, then other tags alphabetically.
+
+ Uses frontmatter params from generated pages:
+ - articleDataKey: product data key (e.g., 'influxdb3-core')
+ - articleSection: section slug (e.g., 'api' or 'management-api')
+
+ Data path: data/article_data/influxdb/{articleDataKey}/{articleSection}/articles.yml
+*/}}
+{{ $currentPage := . }}
+
+{{/* Read data key and section from frontmatter */}}
+{{ $dataKey := .Params.articleDataKey | default "" }}
+{{ $section := .Params.articleSection | default "" }}
+
+{{/* Get article data using frontmatter-driven lookup */}}
+{{ $articles := slice }}
+{{ if and $dataKey $section }}
+ {{ with site.Data.article_data }}
+ {{ with index . "influxdb" }}
+ {{ with index . $dataKey }}
+ {{ with index . $section }}
+ {{ with index . "articles" }}
+ {{ with .articles }}
+ {{ $articles = . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Separate conceptual (traitTag) and non-conceptual articles */}}
+{{ $conceptualArticles := slice }}
+{{ $operationArticles := slice }}
+
+{{ range $articles }}
+ {{ if and (reflect.IsMap .) (isset . "fields") }}
+ {{ $fields := index . "fields" }}
+ {{ if reflect.IsMap $fields }}
+ {{ $isConceptual := false }}
+ {{ if isset $fields "isConceptual" }}
+ {{ $isConceptual = index $fields "isConceptual" }}
+ {{ end }}
+ {{ if $isConceptual }}
+ {{ $conceptualArticles = $conceptualArticles | append . }}
+ {{ else }}
+ {{ $operationArticles = $operationArticles | append . }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Sort each group by weight (default 100), then alphabetically by tag name */}}
+{{ $conceptualArticles = sort $conceptualArticles "fields.weight" }}
+{{ $operationArticles = sort $operationArticles "fields.weight" }}
+
+{{/* Combine: conceptual first, then operations */}}
+{{ $sortedArticles := $conceptualArticles | append $operationArticles }}
+
+{{/* Also include static API pages (HTML files) not in article data */}}
+{{/* These are compatibility API pages like v1-compatibility, v2, management */}}
+{{ $staticApiPages := slice }}
+{{ range $currentPage.Pages }}
+ {{/* Skip pages that are in article data (have tag param) or are all-endpoints */}}
+ {{ if and (not (isset .Params "tag")) (not .Params.isAllEndpoints) }}
+ {{ $staticApiPages = $staticApiPages | append . }}
+ {{ end }}
+{{ end }}
+{{ $staticApiPages = sort $staticApiPages "Weight" }}
+
+
+ {{/* Render article-based pages */}}
+ {{ range $sortedArticles }}
+ {{ $path := index . "path" }}
+ {{ $fields := index . "fields" }}
+ {{ $tag := index $fields "tag" }}
+ {{ $description := index $fields "description" | default "" }}
+ {{/* Build URL relative to the current section page */}}
+ {{ $tagPageUrl := print $currentPage.RelPermalink (path.Base $path) "/" | relURL }}
+
+ {{ $tag }}
+ {{ with $description }}
+ {{/* Truncate to first paragraph (before double newline) or 200 chars */}}
+ {{/* Skip paragraphs that are just headings (start with #) */}}
+ {{ $paragraphs := split . "\n\n" }}
+ {{ $firstPara := "" }}
+ {{ range $paragraphs }}
+ {{ if and (not $firstPara) (not (hasPrefix . "#")) }}
+ {{ $firstPara = . }}
+ {{ end }}
+ {{ end }}
+ {{ if $firstPara }}
+ {{ $truncated := $firstPara | truncate 200 "..." }}
+ {{ $truncated | markdownify }}
+ {{ end }}
+ {{ end }}
+ {{ end }}
+
+ {{/* Render static API pages (compatibility APIs) */}}
+ {{ range $staticApiPages }}
+ {{ .Title }}
+ {{ with .Description }}
+ {{ $truncated := . | truncate 200 "..." }}
+ {{ $truncated | markdownify }}
+ {{ end }}
+ {{ end }}
+
diff --git a/layouts/partials/api/security-schemes.html b/layouts/partials/api/security-schemes.html
new file mode 100644
index 000000000..87210f3a3
--- /dev/null
+++ b/layouts/partials/api/security-schemes.html
@@ -0,0 +1,68 @@
+{{/*
+ Security Schemes Display
+
+ Renders OpenAPI security schemes as human-readable documentation.
+ Extracts securitySchemes from the referenced OpenAPI spec file.
+
+ Design principles:
+ - Each scheme gets an h2 heading (appears in "On this page" TOC)
+ - Focus on human-readable descriptions, not OpenAPI schema details
+ - Technical details (type, scheme, in) are omitted - they're for machines
+ - Descriptions should include usage examples
+
+ Required page params:
+ - staticFilePath: Path to the OpenAPI specification file
+*/}}
+
+{{ $specPath := .Params.staticFilePath }}
+{{ if $specPath }}
+ {{/* Load the OpenAPI spec file from static directory */}}
+ {{ $fullPath := printf "static%s" $specPath }}
+ {{ $specContent := readFile $fullPath }}
+ {{ if $specContent }}
+ {{ $spec := transform.Unmarshal $specContent }}
+ {{ with $spec.components.securitySchemes }}
+
+ {{ range $name, $scheme := . }}
+
+ {{/* Human-friendly title from scheme name */}}
+ {{ $title := $name }}
+ {{/* Convert common scheme names to readable titles */}}
+ {{/* Short names (v1 specs) */}}
+ {{ if eq $name "BasicAuth" }}{{ $title = "Basic Authentication" }}{{ end }}
+ {{ if eq $name "TokenAuth" }}{{ $title = "Token Authentication" }}{{ end }}
+ {{ if eq $name "QueryAuth" }}{{ $title = "Query String Authentication" }}{{ end }}
+ {{ if eq $name "BearerAuth" }}{{ $title = "Bearer Token Authentication" }}{{ end }}
+ {{ if eq $name "ApiKeyAuth" }}{{ $title = "API Key Authentication" }}{{ end }}
+ {{/* Long names (v2+ specs) */}}
+ {{ if eq $name "BasicAuthentication" }}{{ $title = "Basic Authentication" }}{{ end }}
+ {{ if eq $name "TokenAuthentication" }}{{ $title = "Token Authentication" }}{{ end }}
+ {{ if eq $name "QuerystringAuthentication" }}{{ $title = "Query String Authentication" }}{{ end }}
+
+ {{ $title }}
+
+ {{/* Description is the primary content - should include usage examples */}}
+ {{ with $scheme.description }}
+
+ {{ . | markdownify }}
+
+ {{ else }}
+ {{/* Fallback descriptions when OpenAPI spec doesn't provide one */}}
+
+ {{ if eq $scheme.type "http" }}
+ {{ if eq $scheme.scheme "basic" }}
+ Use HTTP Basic Authentication by including your credentials in the request.
+ {{ else if eq $scheme.scheme "bearer" }}
+ Include a bearer token in the Authorization header.
+ {{ end }}
+ {{ else if eq $scheme.type "apiKey" }}
+ Pass your API key {{ if eq $scheme.in "header" }}in the {{ $scheme.name }} header{{ else if eq $scheme.in "query" }}as the {{ $scheme.name }} query parameter{{ end }}.
+ {{ end }}
+
+ {{ end }}
+
+ {{ end }}
+
+ {{ end }}
+ {{ end }}
+{{ end }}
diff --git a/layouts/partials/api/tag-renderer.html b/layouts/partials/api/tag-renderer.html
new file mode 100644
index 000000000..828b46bf1
--- /dev/null
+++ b/layouts/partials/api/tag-renderer.html
@@ -0,0 +1,68 @@
+{{/*
+ Tag Page Renderer
+
+ Renders all operations for a tag page using Hugo templates.
+ Parses the OpenAPI spec file and renders each operation natively.
+
+ Required page params:
+ - staticFilePath: Path to the OpenAPI specification file (YAML)
+ - operations: Array of operation metadata from frontmatter
+
+ Usage:
+ {{ partial "api/tag-renderer.html" . }}
+*/}}
+
+{{ $page := . }}
+{{ $specPath := .Params.staticFilePath }}
+{{ $operations := .Params.operations | default slice }}
+
+{{/* Load and parse the OpenAPI spec from static/ directory */}}
+{{ $spec := dict }}
+{{ if $specPath }}
+ {{/* Build path to static file (staticFilePath has leading slash, e.g. /openapi/...) */}}
+ {{ $staticFile := printf "static%s" $specPath }}
+
+ {{/* Use os.ReadFile (Hugo 0.121+) to read from static directory */}}
+ {{ with os.ReadFile $staticFile }}
+ {{ $spec = . | transform.Unmarshal }}
+ {{ else }}
+ {{/* Fallback: try unmounted resources (for assets mount configuration) */}}
+ {{ $cleanPath := strings.TrimPrefix "/" $specPath }}
+ {{ with resources.Get $cleanPath }}
+ {{ $spec = .Content | transform.Unmarshal }}
+ {{ end }}
+ {{ end }}
+{{ end }}
+
+{{/* Tag description from spec */}}
+{{ $tagDescription := "" }}
+{{ $tagName := .Params.tag | default "" }}
+{{ range $spec.tags }}
+ {{ if eq .name $tagName }}
+ {{ $tagDescription = .description | default "" }}
+ {{ end }}
+{{ end }}
+
+
+ {{/* Tag Overview/Description */}}
+ {{ if $tagDescription }}
+
+
+ {{ $tagDescription | markdownify }}
+
+
+ {{ end }}
+
+ {{/* Operations List */}}
+
+ {{ range $operations }}
+ {{ partial "api/operation.html" (dict
+ "operation" .
+ "spec" $spec
+ "context" $page
+ ) }}
+ {{ end }}
+
+
+ {{/* Related links rendered via frontmatter + article/related.html */}}
+
diff --git a/layouts/partials/article/related.html b/layouts/partials/article/related.html
index 184b7f6dd..41becf349 100644
--- a/layouts/partials/article/related.html
+++ b/layouts/partials/article/related.html
@@ -1,32 +1,25 @@
-{{ $scratch := newScratch }}
{{ if .Params.related }}