hectoday
DocsCoursesChangelog GitHub
DocsCoursesChangelog GitHub

Access Required

Enter your access code to view courses.

Invalid code

← All courses API documentation with OpenAPI and @hectoday/http

Why documentation

  • Undocumented APIs are unusable
  • The OpenAPI standard
  • Project setup

Describing your API

  • Paths and operations
  • Request parameters
  • Request bodies
  • Responses

Schemas and reuse

  • Component schemas
  • Zod to OpenAPI
  • Error schemas

Beyond endpoints

  • Authentication documentation
  • Tags and grouping
  • Examples and descriptions

Serving and consuming

  • Serving the spec
  • Interactive docs with Scalar
  • Generating client SDKs

Wrapping up

  • Versioned specs
  • Checklist

Tags and grouping

As an API grows, the spec turns into a long flat list of endpoints. That is fine when you have three endpoints. But when you have twenty, a client looking for “create a review” has to scroll past books, authors, and auth endpoints to find it.

The OpenAPI standard solves this with tags. Each endpoint can be assigned to one or more tags, and documentation UIs like Scalar render them as collapsible groups. Let’s look at how tags work and what @hectoday/openapi supports today.

Defining tags in the config

You can define tags in the openapi() config:

Code along
const api = openapi(routes, {
  info: {
    title: "Book Catalog API",
    version: "2.0.0",
    description: "A catalog of books, authors, and reviews.",
  },
  tags: [
    { name: "Books", description: "Book catalog management" },
    { name: "Reviews", description: "Book reviews and ratings" },
  ],
});

The tags array defines the groups. Each tag has a name (which becomes the section heading in the docs) and an optional description (which appears as a section introduction). The order in this array determines the display order. Put the most important resources first.

Restart the server and check the spec:

curl http://localhost:3000/openapi.json | jq '.tags'
[
  { "name": "Books", "description": "Book catalog management" },
  { "name": "Reviews", "description": "Book reviews and ratings" }
]

The tags appear in the spec metadata.

Assigning endpoints to tags

For tags to actually group endpoints, each operation in the spec needs a tags array that says which group it belongs to. In the OpenAPI standard, that looks like this:

{
  "/v2/books": {
    "get": {
      "tags": ["Books"],
      "parameters": [...]
    },
    "post": {
      "tags": ["Books"],
      "requestBody": {...}
    }
  },
  "/v2/books/{id}/reviews": {
    "get": {
      "tags": ["Reviews"],
      "parameters": [...]
    }
  }
}

Documentation UIs read these tags arrays and group endpoints under the matching headings. Without tags on individual operations, the tags defined in the config just sit in the spec metadata with nothing linked to them.

@hectoday/openapi does not currently assign tags to operations automatically. The tags config adds the tag definitions to the spec, but the generated operations do not include tags arrays. This means documentation UIs will show your endpoints in a flat list rather than grouped under headings.

This is a limitation of the current tooling, not of the OpenAPI standard. If grouping matters for your docs, you can work around it by post-processing the generated spec, or check whether a newer version of @hectoday/openapi adds tag assignment support.

Tag descriptions with markdown

Even without per-operation assignment, tag descriptions are useful as documentation for your API’s resource groups. They support markdown:

tags: [
  {
    name: "Books",
    description:
      "The book catalog. Create, read, update, and delete books.\n\n" +
      "All book endpoints return the v2 response format with nested " +
      "author objects and ratings.\n\n" +
      "**Authentication:** Most endpoints require a Bearer token. " +
      "GET endpoints are public.",
  },
],

Think of tag descriptions as the introduction to a chapter. They give the client context about a resource before they dive into individual endpoints. This is a good place to note authentication requirements, rate limits, or conventions that apply to all endpoints in the group.

How tags work in other specs

When you read OpenAPI specs from other APIs, you will see tags used heavily. The pattern is always the same: define tags at the top level, then assign endpoints to those tags with a tags array on each operation. The Stripe API, GitHub API, and most large public APIs use this approach.

Understanding how tags work means you can read and navigate any OpenAPI spec you encounter, even if our current tooling does not generate them on operations.

In the next lesson, we will make the spec more useful by adding descriptions to individual fields using z.describe().

Exercises

Exercise 1: Add a tags array to your openapi() config with at least two tags. Restart the server and check http://localhost:3000/openapi.json to verify the tags appear in the spec.

Exercise 2: Look at a public API’s OpenAPI spec (like the Stripe API or GitHub API). Find examples of tags on individual operations and see how documentation UIs group them.

Exercise 3: Add a markdown description to one of your tags that includes authentication notes and a resource overview.

Why group endpoints with tags instead of relying on URL paths?

← Authentication documentation Examples and descriptions →

© 2026 hectoday. All rights reserved.