Open an OpenAPI spec and the version line is the first thing you see. If that line shows openapi: "3.0.3" or openapi: "3.1.0", one question has been on the table since September 2025: what does OpenAPI 3.2 bring, and is the jump worth it?

Three of the new features tend to stand out in day-to-day work because they fix real pain points. Hierarchical tags make documentation navigation possible without vendor extensions, the QUERY method decouples complex filters from the URL, and streaming APIs finally get first-class support. The rest is smaller, but useful in specific spots.

Hinweis

OpenAPI 3.2.0 has been available since September 2025 and stays fully backward-compatible with 3.0 and 3.1. Three additions solve concrete day-to-day pain points. Hierarchical tags replace vendor extensions like x-tagGroups, the QUERY method makes GET-with-body an idempotent operation, and streaming picks up first-class support through Server-Sent Events. On top of that, the OAuth 2.0 device flow gets a proper home, XML modeling sharpens up, and multipart definitions get cleaner.

What OpenAPI 3.2 brings

OpenAPI 3.2.0 was released on September 18, 2025. The specification stays strictly backward-compatible with 3.0 and 3.1. Existing specs keep validating without changes, and existing tooling doesn’t need to migrate. The 3.2-specific constructs are opt-in and only show up where teams actively use them.

Seven areas pick up additions or clarifications. Hierarchical tags make documentation navigation possible without vendor extensions. The QUERY method turns GET-with-body into an official, idempotent operation. Streaming and Server-Sent Events become first-class to model. The OAuth 2.0 device authorization flow can be described officially. XML modeling covers attributes, nested, and mixed content more precisely. Multipart definitions that combine file uploads with structured metadata get cleaner. Finally, several older constructs and OAuth flows are marked as deprecated. The table below sorts the most important changes by practical impact.

FeaturePractical impact
Hierarchical tagsMicroservice domains can be structured without x-tagGroups or x-displayName. Tag navigation becomes tool-portable.
QUERY methodComplex filter bodies are idempotent and cacheable, without a POST workaround. Search and reporting APIs get an HTTP verb that actually fits.
Streaming and SSETooling can generate and validate Server-Sent Events instead of treating them as a special case. Maintaining a parallel AsyncAPI spec falls away.
OAuth device flowCLI tools, IoT devices, and smart TVs without a browser can be described officially.
XML improvementsAttributes, nested, and mixed content can be modeled without vendor extensions.
Multipart clarificationFile uploads with JSON metadata in the same request can be expressed cleanly.
Deprecation markersExisting specs can be maintained without forcing a 3.2 jump immediately.

From a migration perspective, 3.2 is a light jump. Teams already on 3.1 can flip the version line in the spec file to openapi: "3.2.0" and the spec keeps validating. New constructs are then introduced selectively, wherever a concrete use case calls for them. A big-bang migration across the entire API portfolio is neither necessary nor smart.

Hierarchical tags make doc navigation possible without vendor extensions

Tags in OpenAPI have always been used to group operations. Up to 3.1, they sit as a flat list at the top level. Anyone trying to organize an API with thirty endpoints across five domains had to fall back on vendor extensions like x-tagGroups (Redoc) or x-displayName (from various tool vendors).

The result was tool-specific and not portable. A spec that looked nicely structured in Redoc collapsed back to a flat list in Swagger UI. Teams that wanted to switch documentation generators had to remodel the tag structure every time.

In 3.2, hierarchical tags are part of the standard. Tag objects now carry the fields parent, summary, and kind. Nested navigation can be derived from those fields, and the structure stays portable across renderers.

yaml
# Before 3.2 (workaround with vendor extension)
tags:
  - name: Payments
  - name: Cards
  - name: Transfers
x-tagGroups:
  - name: Banking
    tags:
      - Payments
      - Cards
      - Transfers


# With OpenAPI 3.2
tags:
  - name: Banking
    summary: "Banking domain"
    kind: nav
  - name: Payments
    parent: Banking
    summary: "Payment processing"
  - name: Cards
    parent: Banking
    summary: "Card operations"
  - name: Transfers
    parent: Banking
    summary: "Transfers"

The practical effect is concrete. A team documenting an API for a banking platform can now group domains like Payments, Cards, and Transfers under a shared Banking node. The navigation shows up consistently in Swagger UI, Redoc, and Scalar without any tool-specific configuration.

There is no migration pressure for existing specs. Teams that want to keep using vendor extensions can do so, since 3.2 still accepts them. Teams that switch to the 3.2-native pattern gain portability and can phase out the vendor extensions step by step.

The QUERY method brings GET with a body as an idempotent operation

In the HTTP specification, GET requests are designed for read access: idempotent and cacheable. As soon as filter logic gets complex, the pattern runs into its limits. Long URLs with dozens of query parameters are awkward, and many servers cap URL length at 8 KB or less.

The obvious workaround so far has been POST with a JSON body. That works technically, but it signals the wrong semantics. POST stands for non-idempotent write operations, isn’t cacheable, and fits poorly with pure read access that happens to use complex filters.

OpenAPI 3.2 officially supports the QUERY method. QUERY is an ongoing HTTP standardization effort at the IETF, and it combines the semantics of GET (idempotent, safe, cacheable) with the option to send a request body alongside the request.

yaml
paths:
  /customers:
    query:
      summary: Customer search with complex filters
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                filters:
                  type: array
                  items:
                    $ref: '#/components/schemas/Filter'
                sort:
                  type: array
                  items:
                    type: string
      responses:
        '200':
          description: Matching customers
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CustomerList'

The method matters for search APIs, reporting endpoints, and GraphQL-style filter structures, where the filter logic no longer fits into query parameters. A team describing a search API with twenty optional filters and three sort criteria can now express the model cleanly.

Tooling support, however, is still limited. Most HTTP clients, browser implementations, and API gateways don’t support QUERY consistently yet. Teams using the method in their spec today mostly treat it as documentation and fall back on POST with an idempotency header at runtime until tooling catches up.

The HTTP standardization itself is still moving. QUERY is active as an IETF draft under draft-ietf-httpbis-safe-method-w-body and is expected to be ratified as an RFC in 2026 or 2027. So OpenAPI 3.2 gets out ahead of a standardization effort that hasn’t wrapped up in the HTTP stack itself yet. For teams with existing POST-based search APIs, a gradual spec adjustment makes sense once the client libraries in their own stack pick up QUERY.

Streaming and Server-Sent Events as first-class

Streaming APIs have been hard to express in OpenAPI so far. Server-Sent Events, long polling, and chunked-transfer endpoints could be described technically, but tooling had no real handle on generating code from them or validating the spec. In practice, SSE endpoints were either declared as regular GET endpoints with text/event-stream or factored out of the main spec entirely.

In 3.2, streaming patterns are officially on the table. Server-Sent Events can be modeled cleanly through the text/event-stream content type, and the streaming nature of an endpoint becomes machine-readable for tooling. The spec now distinguishes between one-off responses and continuous event streams. In practice, you’ll often still see a vendor extension like x-stream: true tacked on while generators are still catching up to the official streaming field.

yaml
paths:
  /events:
    get:
      summary: Event stream over Server-Sent Events
      responses:
        '200':
          description: Continuous event stream with order updates
          content:
            text/event-stream:
              schema:
                $ref: '#/components/schemas/OrderEvent'
              x-stream: true

Tooling implementations like OpenAPI Generator and Spectral are working on support for the streaming markers. Until then, the concrete benefit is limited to documentation and validation, which for many teams is already where most of the value sits.

Beobachtung aus der Praxis

Before 3.2, we kept streaming APIs in a separate AsyncAPI specification that ran in parallel to the OpenAPI spec. The dual maintenance overhead fell away as soon as 3.2 went into production and SSE endpoints could be described directly inside the OpenAPI document. Spec consumers no longer had to keep two different tools in their head, depending on whether they wanted to call a synchronous endpoint or a streaming one.

The line between OpenAPI and AsyncAPI still holds. AsyncAPI covers complex event-driven architectures with pub/sub patterns, channel definitions, and message brokers. OpenAPI 3.2 with streaming support covers synchronous and semi-synchronous HTTP-based streaming patterns, where a server continuously sends data to a client.

Typical use cases for streaming in OpenAPI 3.2 include live order updates in e-commerce platforms, telemetry streams from IoT devices, progress updates for long-running backend tasks, and live notifications in banking or logistics applications. Teams that cover one of these patterns and have so far relied on workarounds end up with noticeably cleaner specs under 3.2.

Other changes that tend to fly under the radar

The smaller additions in 3.2 attract less attention, but they help specific use cases that were hard to describe in 3.1.

When the jump from 3.1 to 3.2 is worth it

The call for or against 3.2 is unusually clear compared to previous version jumps. 3.2 is backward-compatible with 3.1, and the migration effort stays minimal. It comes down to which features you actually need.

Praxis-Tipp

  • Streaming or Server-Sent Events in your use case. The jump is worth it. Tooling generation and validation for SSE endpoints become possible, instead of maintaining workarounds.
  • Hierarchical doc navigation wanted. The jump is worth it. Vendor extensions like x-tagGroups can be removed, and the spec becomes tool-portable.
  • Complex filter endpoints (search, GraphQL-style filters). The jump is worth it. QUERY decouples the filter body from query-parameter limits more cleanly than POST with an idempotency header.
  • None of the three drivers apply. No acute migration pressure. 3.1 stays valid; the jump can wait until a use case actually shows up.

Tooling status is the second factor when sizing up the jump. OpenAPI Generator, Spectral, and the major doc renderers like Swagger UI, Redoc, and Scalar have rolled out 3.2 support to varying degrees. Teams that auto-generate from the spec should check 3.2 support in their own stack first, before flipping production specs.

On the migration side, the jump from 3.1 to 3.2 is pure schema adjustment. Existing tags structures, path definitions, and component schemas stay valid. 3.2 constructs are added, not replaced, and tooling that doesn’t understand 3.2 silently ignores the new fields. Validating the spec with a 3.1 linter gives you warnings at worst for unknown fields, not errors.

For anyone still unsure what actually separates OpenAPI from Swagger as a term, there’s a breakdown in OpenAPI vs Swagger.

How api-portal.io supports OpenAPI 3.2

In api-portal.io, OpenAPI 3.2 is supported side by side with 3.0 and 3.1. On spec import, 3.2 constructs like hierarchical tags, QUERY operations, and streaming markers are picked up directly and rendered in the documentation UI. The API Linter checks 3.2-specific patterns against the same style guide that already applies to 3.0 and 3.1.

The API Explorer supports rendering multiple API formats.