cd /news/developer-tools/operationid-and-tags-in-openapi-nami… · home › topics › developer-tools › article
[ARTICLE · art-147352] src=dev.to ↗ pub= topic=developer-tools verified=true sentiment=· neutral

operationId and tags in OpenAPI: naming conventions that keep generated SDKs and docs usable

A developer outlines naming conventions for OpenAPI operationId and tags, arguing that these fields function as a service's public naming API because code generators turn operationIds into SDK method names and tags into SDK classes or doc sections. The guidance recommends unique, stable, lowerCamelCase, verb-first operationIds set deliberately from day one, plus a small, stable tag taxonomy aligned to business domains rather than URLs.

by read5 min views1 publishedOct 8, 2026

Open a generated SDK where the methods are named getV1UsersByIdGet, postV1UsersPost, and usersGet2, and the cost of careless operationId s is immediate: nobody can discover anything, and every rename is a breaking change for downstream code. Open the docs sidebar and see 200 operations in one flat list because every endpoint got its own tag, and the same problem appears on the human side. These two fields look like optional labels; they are the public naming API of your service.

Field Consumed by Consequence of getting it wrong
operationId Code generators, mocking tools, agent tool lists Becomes the method/function name; must be unique and stable
tags Documentation navigation, generator namespaces Groups operations into sections or SDK classes
summary /description Docs, AI tool descriptions The sentence a developer or agent reads first
x-* group names Some renderers Vendor-specific grouping; do not rely on it portably

Generators that do not find an operationId synthesize one from the method and path, which is how you get getV1UsersByIdGet. Once a synthesized name ships, fixing it later breaks every caller. Set the id deliberately from day one.

Unique across the whole document. Two operations cannot share an id; some generators dedupe by appending a number, silently. Enforce uniqueness with a linter.

Language-neutral and code-safe. Use lowerCamelCase with ASCII letters and digits, starting with a letter. Avoid hyphens, dots, and spaces, because not every language maps them cleanly into an identifier.

Verb-first, resource-oriented, specific. The id should read as an action on a resource and say enough to be unambiguous without the path:

Method and path Avoid Prefer
GET /users getUsersGet listUsers
POST /users postUsers createUser
GET /users/{id} getUserById (fine) orgetV1UsersId getUser
PATCH /users/{id} updateUser (ambiguous vs PUT) patchUser /updateUser split by verb
DELETE /users/{id} deleteUsersId deleteUser
POST /users/{id}/archive archive archiveUser
GET /users/{id}/orders getOrders listUserOrders

A consistent verb vocabulary removes the guesswork: list for collections, get for one, create, update/ patch, delete, plus domain actions like archive, cancel, approve, export. Avoid generic verbs like process or handle that say nothing.

Stable forever once published. The id is part of the contract because generated code embeds it. Renaming it is a breaking change for SDK users even if the URL does not change. Treat it like a field name: pick it once, lint it, and never reuse a retired id for a different operation.

Do not encode the version or HTTP method. getV2Users bakes the version into the method, so a future v3 forces a rename even for clients that never cared. Version belongs in the server URL or path, not the id.

Tags group operations in docs and often become SDK classes or namespaces. The failure modes are a tag per endpoint (no grouping at all) and a single tag for everything (one giant list). Aim for a small, stable set aligned to business domains, not to URLs:

tags:
  - name: Users
    description: Customer accounts, profiles, and authentication identities.
  - name: Orders
    description: Order lifecycle, line items, and status transitions.
  - name: Billing
    description: Invoices, payment methods, and refunds.
  - name: Webhooks
    description: Event subscriptions and delivery logs.

Rules that keep the taxonomy usable:

description; do not rely on ad-hoc names appearing only on operations (typos then create duplicate tags like User and Users). Webhooks, but three or more tags per operation scatter it across the docs.Billing, Orders), not internal service names ( payment-svc) or HTTP concepts. If you need finer grouping than a tag gives, use x-tagGroups (supported by several renderers) to cluster tags into sections like "Catalog" and "Account" without multiplying tags.

summary is a short imperative label; description is the detail. For an AI agent that turns operations into callable tools, the summary and the first line of the description are often the entire basis for choosing the operation. Write them to disambiguate:

operationId: listUserOrders
summary: List a user's orders
description: >-
  Returns orders belonging to the given user, newest first. Supports cursor
  pagination and filtering by status. Does not include line items; use
  getOrder for those.

That one sentence ("does not include line items; use getOrder") prevents a class of wrong agent calls that a name alone cannot.

Naming conventions are exactly the kind of rule a linter should guarantee rather than a wiki page hoping people remember. A few high-value rules:

operationId matching an allowed verb prefix; Run the ruleset in CI so a PR that introduces postV2ThingsPost fails before merge, and add a check that flags a brand-new tag, forcing a conscious decision to grow the taxonomy.

client.users.list() style APIs; a missing id yields path-derived noise.listUserOrders over listOrders correctly. Ambiguous or missing ids make the agent guess, and the guess lands in production calls. Get these right and the generated SDK reads like an API a human designed, the docs navigate cleanly at 200 routes, and an AI agent picks the right operation without guessing.

You can apply these conventions, generate a cleanly named TypeScript client, and lint the result all in one local-first workspace, right in your browser. To see how the ids and tags surface in a generated SDK, read generating a TypeScript client from OpenAPI.

── more in #developer-tools 4 stories · sorted by recency
── more on @openapi 3 stories trending now
sponsored brought to you by zahid.host 4,200+ EU-deployed projects
reading about agents? ship yours in a single git push.

Run your AI side-project on zahid.host

EU-based hosting, git-push deploys, automatic HTTPS, no cold starts. Free tier with a custom domain — perfect for shipping the agent you just read about.

$git push zahid main
→ Live at https://your-agent.zahid.host ✓
Get free account → Pricing
from €0/mo · no card required
LIVE [news/operationid-and-tags…] indexed:0 read:5min 2026-10-08 · —