BTST
PluginsQuickstartDocs
Live Blog

From research to product evaluation

Evaluating a publishing workflow for an app you already own?

See what the BTST Blog plugin adds to an existing React or Next.js app
BTST

Open-source TypeScript features for the React application, data, and deployment you already own.

Released plugins

  • Blog
  • AI Chat
  • CMS
  • Form Builder
  • UI Builder
  • Kanban
  • Comments
  • Media
  • Route Docs
  • OpenAPI
  • Better Auth UI

Resources

  • Quickstart
  • Documentation
  • All plugins
  • Live Blog
  • GitHub (opens in a new tab)
© 2026 BTST. Open source under the MIT License.
AI Chat
September 11, 2026ReactOpenAPI

BTST OpenAPI Docs: Public Schemas and Protected Operations

Understand which BTST routes enter the OpenAPI contract, what access metadata means, and how to protect both documentation endpoints when needed.

BTST OpenAPI Docs: Public Schemas and Protected Operations

BTST's OpenAPI plugin documents registered backend routes and their access metadata. The documentation itself is public by default. If your API reference must be private, protect its JSON endpoint and its HTML reference page separately from the business operations they describe.

This distinction matters when adding generated documentation to an existing Next.js, TanStack Start, or React Router application. A private administration API can reject anonymous mutations while a public schema still describes its paths and input fields. Decide whether that metadata exposure is appropriate for your product.

What the plugin discovers#

In @btst/stack 3.0.0, OpenAPI generation uses the routes composed by the BTST backend stack, their endpoint metadata, and Zod inputs. It does not scan arbitrary framework route files. Adding a Next.js Route Handler elsewhere in your app does not automatically add it to this contract.

The generated document declares OpenAPI 3.1.0. Registered operation routes include x-btst-access, with public or permission access, and protected operations include a stable x-btst-permission identifier. Those extensions describe the operation boundary; they do not contain your actual authorization rules or resolve a visitor's identity. See the released generator.

Treat generated schemas as an artifact to inspect. Compare required inputs, nullable values, arrays, and response shapes with the runtime behavior you depend on. Do not assume generation captures every Zod refinement or produces a complete response model for client generation.

Know the two documentation endpoints#

With the backend base path /api/data, the default routes are:

URLPurpose
/api/data/open-api/schemaGenerated JSON document
/api/data/referenceScalar HTML reference

The reference path is configurable. The schema suffix remains /open-api/schema. The plugin is backend-only; it does not require a matching BTST client plugin. The OpenAPI installation guide shows where to register it in an existing stack.

This configuration fragment removes the HTML reference:

TS
  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
import { openApiBackendPlugin } from "@btst/stack/plugins/open-api/api";

export const openApi = openApiBackendPlugin({
  title: "Application API",
  disableDefaultReference: true,
});

Add the resulting plugin to your existing backend's plugins object. Disabling the reference does not disable or authenticate the JSON endpoint. The released plugin explicitly treats both documentation handlers as public infrastructure.

Make documentation privacy a separate decision#

If both the schema and interactive reference are intended for the public, inspect the output for inappropriate descriptions, examples, or internal details before deployment.

If documentation is internal, restrict both paths at the framework or deployment boundary, including a custom reference path if configured. Use the application's verified session and role policy. Another option is to omit this plugin from the public deployment and generate documentation in an appropriately restricted environment.

Do not embed production tokens in examples or use a secret URL as the access policy. Also review caching: an authenticated response must not become a shared public copy through a proxy or CDN.

The OpenAPI specification distinguishes declaring a security scheme from applying security requirements to operations. Its Security Requirement Object describes that contract. In every case, enforcement comes from your running backend and surrounding access controls, not from displaying a lock icon in a reference UI.

Verify metadata and enforcement independently#

In your own development environment, fetch the schema without credentials:

SH
  1. 1
curl --fail-with-body http://localhost:3000/api/data/open-api/schema

If documentation is public, expect a JSON response. If your application is meant to keep it private, verify the access control rejects this request. Repeat for the HTML reference and any custom reference URL.

Configure the backend's server auth adapter and operation rules first; BTST authorization is opt-in. Then choose one harmless protected operation and test it as an anonymous visitor and an authorized user. Do this even if its permission metadata appears correct. Documentation visibility and permission enforcement are different checks.

Finally, change one registered input field and confirm the next generated document reflects the change. Compare the contract before giving it to a client generator. The OpenAPI plugin overview describes the supported discovery boundary; BTST authorization explains how the actual operations are protected.

In This Post

What the plugin discoversKnow the two documentation endpointsMake documentation privacy a separate decisionVerify metadata and enforcement independently