{
  "openapi": "3.1.0",
  "info": {
    "title": "RIKAISO Help Portal API",
    "version": "1.0.0",
    "description": "Read published RIKAISO documentation and manage help content programmatically. Sample data for a fictional brand."
  },
  "servers": [
    {
      "url": "https://rikaiso.lovable.app/api/help/v1"
    }
  ],
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "rk_help_* API key or OAuth access token"
      },
      "oauth2": {
        "type": "oauth2",
        "description": "OAuth 2.1 with PKCE (S256), dynamic client registration and refresh-token rotation. Consent requires an admin or editor account.",
        "flows": {
          "authorizationCode": {
            "authorizationUrl": "https://rikaiso.lovable.app/oauth/authorize",
            "tokenUrl": "https://rikaiso.lovable.app/oauth/token",
            "refreshUrl": "https://rikaiso.lovable.app/oauth/token",
            "scopes": {
              "help:read": "Read help content, including drafts",
              "help:write": "Create, edit, move and delete help content"
            }
          }
        }
      }
    }
  },
  "paths": {
    "/versions": {
      "get": {
        "summary": "List versions",
        "description": "Returns every published documentation version, newest first. With a valid bearer key, draft and archived versions are included too (each object carries `status`). Hidden working copies (`hidden: true`, `workingCopyOf`) are listed only with `includeWorkingCopies=true`.",
        "security": [],
        "parameters": [
          {
            "name": "includeWorkingCopies",
            "in": "query",
            "required": false,
            "description": "true to include hidden working copies (authenticated callers only).",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Array of version objects."
          }
        }
      },
      "post": {
        "summary": "Create a version",
        "description": "Creates a documentation version. Answers 409 `conflict` when the slug already exists (use PATCH /versions/{version} to change one).",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "slug: string, e.g. 2026.1; label: string, display label; status: draft (default) | published | archived; languages: array of language codes (default [en]); the first one is the primary language; sortOrder: number, optional; isLatest: boolean, optional — marks this published version as latest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The stored version object."
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "409": {
            "description": "A version with this slug already exists."
          }
        }
      }
    },
    "/versions/{version}": {
      "patch": {
        "summary": "Update a version",
        "description": "Partially updates label, status, languages, sort order or latest flag: only the fields in the body change. `isLatest: true` needs a published version (clears the previous latest). Setting the status of a published version to `archived` unpublishes it.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug, e.g. 2026.1",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "label: string, optional; status: draft | published | archived, optional; languages: array of language codes, optional; sortOrder: number, optional; isLatest: boolean, optional"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The updated version object."
          },
          "404": {
            "description": "Unknown version."
          }
        }
      },
      "delete": {
        "summary": "Delete a version",
        "description": "Removes a version and every node and translation beneath it.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok: true }"
          },
          "404": {
            "description": "Unknown version."
          }
        }
      }
    },
    "/versions/{version}/tree": {
      "get": {
        "summary": "Get the contents tree",
        "description": "Returns the nested section/topic tree of a published version. With a valid bearer key, draft and archived versions can be read as well.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "description": "Language code, default en.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ version, tree }"
          },
          "404": {
            "description": "Version not published."
          }
        }
      }
    },
    "/versions/{version}/topics/{slug}": {
      "get": {
        "summary": "Get a topic",
        "description": "Returns one topic with its Markdown body, breadcrumbs, neighbours and `versionStatus`. Falls back to English when the requested language is missing. With a valid bearer key, topics of draft and archived versions can be read as well.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Topic slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "language",
            "in": "query",
            "required": false,
            "description": "Language code, default en.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Topic object."
          },
          "404": {
            "description": "Topic not found."
          }
        }
      }
    },
    "/versions/{version}/nodes": {
      "post": {
        "summary": "Create a node",
        "description": "Creates a section or topic in the version with its translations. Every translation language must be enabled on the version and the version's primary language (`languages[0]`) is required. Answers 409 `conflict` when the slug exists. The response carries the node's `updatedAt` and one per translation language, all valid as `expectedUpdatedAt` for follow-up writes.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "slug: string, unique within the version; kind: section | topic; parentSlug: string or null; icon: icon name or null; sortOrder: number; translations: object keyed by language: { title, summary, bodyMd }"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ id, slug, kind, parentSlug, icon, sortOrder, updatedAt, translations: { [lang]: { updatedAt } } }"
          },
          "400": {
            "description": "A translation language is not enabled on the version, or the primary language is missing."
          },
          "401": {
            "description": "Missing or invalid API key."
          },
          "409": {
            "description": "A node with this slug already exists."
          }
        }
      },
      "get": {
        "summary": "List nodes with translation status",
        "description": "Flat list of every node in document order with id, slug, kind, parentSlug, sortOrder, icon, updatedAt and `translations` keyed by language ({ title, summary, updatedAt, bodyChars }). Published versions are public (no bodies); with a credential drafts are visible and `include=bodies` adds bodyMd.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "include",
            "in": "query",
            "required": false,
            "description": "`bodies` to add bodyMd to every translation.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ version, status, nodes }"
          },
          "404": {
            "description": "Unknown version."
          }
        }
      }
    },
    "/versions/{version}/nodes/{slug}": {
      "patch": {
        "summary": "Update a node",
        "description": "Partially updates a node (only the fields in the body change) and merges any supplied translations, whose languages must be enabled on the version. Supports `expectedUpdatedAt` / If-Unmodified-Since (409 on conflict); the response carries kind, icon, parentSlug, sortOrder and `updatedAt`.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Node slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "slug: string, optional — renames the node; kind: section | topic, optional; parentSlug: string or null, optional; icon: icon name or null, optional; sortOrder: number, optional; translations: object keyed by language, optional"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ id, slug, kind, parentSlug, icon, sortOrder, updatedAt, translations: { [lang]: { updatedAt } } }"
          },
          "404": {
            "description": "Unknown node."
          },
          "409": {
            "description": "The node changed after expectedUpdatedAt, or the new slug is taken."
          }
        }
      },
      "delete": {
        "summary": "Delete a node",
        "description": "Removes a node and its descendants; the response lists the removed slugs.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Node slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok: true, removed: [slug] }"
          },
          "404": {
            "description": "Unknown node."
          }
        }
      }
    },
    "/versions/{version}/topics/{slug}/translations/{lang}": {
      "get": {
        "summary": "Get one translation",
        "description": "Returns the stored title, summary, bodyMd and updatedAt of one translation plus the node's availableLanguages. Draft and archived versions need a bearer key.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Node slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "path",
            "required": true,
            "description": "Language code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Translation object."
          },
          "404": {
            "description": "Unknown version, node or translation."
          }
        }
      },
      "put": {
        "summary": "Replace one translation",
        "description": "Full replacement of a translation (created when missing); the language must be enabled on the version. Supports `expectedUpdatedAt` / If-Unmodified-Since (409 on conflict). Use PATCH /nodes/{slug} with `translations` to merge several languages.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Node slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "path",
            "required": true,
            "description": "Language code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "title: string, 1–200 characters; summary: string, optional; bodyMd: Markdown string, optional; expectedUpdatedAt: ISO timestamp, optional"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ translation: { slug, language, title, summary, bodyMd, updatedAt, created } }"
          },
          "404": {
            "description": "Unknown node."
          },
          "409": {
            "description": "The translation changed after expectedUpdatedAt."
          }
        }
      },
      "delete": {
        "summary": "Delete one translation",
        "description": "Removes one language of a node; the response lists the remaining languages.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "Node slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "path",
            "required": true,
            "description": "Language code.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok: true, remainingLanguages }"
          },
          "404": {
            "description": "Translation not found."
          }
        }
      }
    },
    "/versions/{version}/reorder": {
      "post": {
        "summary": "Move and reorder nodes",
        "description": "Applies parent and sort order for the listed slugs in one call. Every slug must exist and no node may end up inside its own subtree (400 with code `cycle`); if any row fails the previous order is restored. Returns the new flat order.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "items: array of { slug, parentSlug: string | null, sortOrder: number }"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ version, items: [{ slug, parentSlug, sortOrder }] } in document order."
          },
          "400": {
            "description": "Unknown slug, unknown parent or cycle."
          }
        }
      }
    },
    "/versions/{version}/duplicate": {
      "post": {
        "summary": "Duplicate a version",
        "description": "Deep-copies every node and translation into a new version (draft unless `status` says otherwise). The copy is never marked latest.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Source version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "slug: string, new version slug; label: string, display label; status: draft | published | archived, optional (default draft)"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ version } — the new version object."
          },
          "409": {
            "description": "The target slug already exists."
          }
        }
      }
    },
    "/versions/{version}/search": {
      "get": {
        "summary": "Search a version",
        "description": "Case-insensitive match on title, summary and body text; up to 50 hits in document order with a snippet. Published versions are public; drafts need a bearer key.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": true,
            "description": "Search text (1–200 characters).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language code, default en.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ version, language, query, hits: [{ slug, title, summary, snippet }] }"
          },
          "404": {
            "description": "Unknown version."
          }
        }
      }
    },
    "/versions/{version}/export": {
      "get": {
        "summary": "Export a version",
        "description": "Full JSON document: { version, nodes } where every node carries slug, kind, parentSlug, icon, sortOrder and all translations including bodies. Published versions are public; drafts need a credential. Large for big versions.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Export document."
          },
          "404": {
            "description": "Unknown version."
          }
        }
      }
    },
    "/versions/{version}/import": {
      "post": {
        "summary": "Import a version document",
        "description": "Applies an export document to the version. `merge` upserts nodes and translations; `replace` also deletes nodes and translations the document omits. With `dryRun: true` nothing is written and the diff summary (created/updated/unchanged/deleted slugs) is returned.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "mode: merge | replace; dryRun: boolean, optional; nodes: array of export nodes (or wrap them in `document: { nodes }`)"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ dryRun, mode, diff: { created, updated, unchanged, deleted, updatedTranslations: [{ slug, language }], deletedTranslations: [{ slug, language }] }, version }"
          },
          "400": {
            "description": "Invalid document (unknown parent, duplicate slug, cycle, or a translation language the version does not enable — `offending` lists the { slug, language } pairs)."
          }
        }
      }
    },
    "/versions/{version}/import-files": {
      "post": {
        "summary": "Import a version from content files",
        "description": "Docs-as-code import used by the content repository's GitHub Action: `{ files: [{ path, content }] }` holding `version.json` and every `{lang}/{slug}.md` of the version (paths may be repository-relative). Files are parsed server-side; `dryRun=true` validates and reports `{ created, updated, deleted }` without writing. A real run replaces the version, marks it published, applies `isLatest`, deletes its working copy and closes matching publish requests. While publishing through pull requests is enabled, a real run needs a publisher key. At most 2,000 files / 10 MB.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dryRun",
            "in": "query",
            "required": false,
            "description": "true to validate only.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "description": "files: array of { path, content }; dryRun: boolean, optional"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "{ dryRun, summary: { created, updated, deleted, unchanged, slugs }, warnings, version: { slug, exists, status, isLatest }, workingCopyDeleted, requestsImported }"
          },
          "400": {
            "description": "{ error: { code: 'invalid_content', errors: [{ path, line?, message }], warnings } }"
          },
          "403": {
            "description": "{ error: { code: 'published_read_only' } } — a real run without a publisher key."
          }
        }
      }
    },
    "/versions/{version}/working-copy": {
      "post": {
        "summary": "Create a working copy",
        "description": "Duplicates a published version into the hidden draft `{version}-wip` (its `workingCopyOf` points at the original) so it can be edited and published back through a pull request. Returns the existing copy when one already exists. Requires publishing through pull requests to be enabled.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Published version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ version, existed: true }"
          },
          "201": {
            "description": "{ version, existed: false }"
          },
          "409": {
            "description": "Publishing through pull requests is disabled."
          }
        }
      },
      "delete": {
        "summary": "Discard a working copy",
        "description": "Deletes the working copy of the version. Refused while a publish request for it is open.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Original or working-copy slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ ok: true, discarded }"
          },
          "409": {
            "description": "An open publish request exists."
          }
        }
      }
    },
    "/versions/{version}/publish-request": {
      "post": {
        "summary": "Open a publish pull request",
        "description": "Exports a draft (new version) or a working copy (changes to its original) as content files, validates them, commits them to a `publish/{target}/{stamp}` branch of the content repository and opens a pull request titled `Publish {target}`. `dryRun=true` returns the validation result and counts without touching GitHub. One open request per target.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Draft or working-copy slug.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dryRun",
            "in": "query",
            "required": false,
            "description": "true to validate only.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ dryRun: true, targetSlug, summary: { created, updated, deleted, unchanged, slugs }, warnings, files }"
          },
          "201": {
            "description": "{ dryRun: false, request: { id, targetSlug, prNumber, prUrl, status, summary, … } }"
          },
          "400": {
            "description": "invalid_content with the error list."
          },
          "409": {
            "description": "A request for the target is already open, or publishing is disabled."
          },
          "502": {
            "description": "GitHub refused the call (the request is recorded as failed)."
          }
        }
      }
    },
    "/publish-requests": {
      "get": {
        "summary": "List publish requests",
        "description": "Publish requests newest first, optionally filtered by `target`. Each carries the PR number and URL, status (`open | merged | closed | imported | failed`), counts and timestamps.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "target",
            "in": "query",
            "required": false,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ requests: [...] }"
          }
        }
      }
    },
    "/publish-requests/{id}": {
      "delete": {
        "summary": "Cancel a publish request",
        "description": "Closes the pull request, deletes its branch and marks the request `closed`.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Request id.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "{ request }"
          },
          "409": {
            "description": "The request is not open."
          }
        }
      }
    },
    "/whoami": {
      "get": {
        "summary": "Describe the API key",
        "description": "Returns { kind, keyName, keyPrefix, createdAt, lastUsedAt, scopes, canWritePublished, publishViaPr } for the credential in use. `publishViaPr` is true while published versions can only change through a merged pull request; writes to them then answer 403 `published_read_only` unless the key is a publisher key.",
        "security": [
          {
            "bearerAuth": []
          },
          {
            "oauth2": [
              "help:write"
            ]
          }
        ],
        "parameters": [],
        "responses": {
          "200": {
            "description": "Key metadata."
          },
          "401": {
            "description": "Missing or invalid API key."
          }
        }
      }
    },
    "/versions/{version}/pdf-bundle": {
      "get": {
        "summary": "Get the data for a PDF export",
        "description": "Returns { version, language, template, entries, fonts, filename } for a published version, or for a comma-separated selection of topics resolved to document order (sections expand to their descendants, ancestors appear as chapter headings, at most 200 topics). The portal renders the PDF in the browser from this bundle; shareable links look like /support/{version}/{slug}?pdf=1&lang=de&topics=a,b.",
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug, or latest.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "Language code, default en.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "topics",
            "in": "query",
            "required": false,
            "description": "Comma-separated topic or section slugs; omit for the full document.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "Keep only the first N topics (1–200); used for template previews.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "PDF bundle object."
          },
          "400": {
            "description": "Invalid selection or more than 200 topics."
          },
          "404": {
            "description": "Version not published."
          }
        }
      }
    },
    "/versions/{version}/pdf": {
      "get": {
        "summary": "Download a PDF (retired)",
        "description": "Rendering now happens in the browser; use /pdf-bundle and a client renderer.",
        "deprecated": true,
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Gone."
          }
        }
      },
      "post": {
        "summary": "Download a PDF (retired)",
        "description": "Rendering now happens in the browser; use /pdf-bundle and a client renderer.",
        "deprecated": true,
        "security": [],
        "parameters": [
          {
            "name": "version",
            "in": "path",
            "required": true,
            "description": "Version slug.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "410": {
            "description": "Gone."
          }
        }
      }
    }
  }
}