Event-Driven Architecture
AsyncAPI: Documenting Events as Contracts with AsyncAPI 3.0
AsyncAPI explained: the open specification for documenting event-driven APIs, what changed in AsyncAPI 3.0, and how catalogues and governance use it.
AsyncAPI is an open specification for describing event-driven APIs: a YAML or JSON document that states which broker an application connects to, which channels (topics or queues) it sends and receives on, and exactly what each message contains. It does for events what OpenAPI does for REST. The Linux Foundation has hosted the AsyncAPI Initiative since March 2021, alongside OpenAPI (Linux Foundation), and the current major version, AsyncAPI 3.0, was released in December 2023 (AsyncAPI).
For a plant or an enterprise building an event-driven architecture, AsyncAPI is the difference between “there is a topic called line3/filler/state” and a contract that says what the payload means, which version it is, who publishes it and who depends on it. This page explains the document, what changed in version 3.0, how it relates to CloudEvents and catalogues, and how governance uses it. It is part of our event-driven architecture guide.
Why events need contracts
Events decouple systems in time and identity, and that is also their risk. In a request-driven integration, a broken interface fails loudly: the call returns an error. In an event-driven one, a producer can rename a field or change a unit, and consumers keep running with wrong data until someone notices on a report. In our IT/OT integration experience, that silent breakage is the most common long-term failure of a unified namespace or event backbone, more common than any broker fault.
A contract fixes three things:
- Meaning. Is
countgood parts or total parts? Istempin Celsius? Is the timestamp from the PLC or the gateway? - Ownership. Who publishes this event, who consumes it, and who approves a change?
- Change. Which version is current, what changed, and how long does the old version keep flowing?
AsyncAPI puts those answers in a machine-readable file that can be validated, versioned in Git, rendered as documentation and used to generate code.
The anatomy of an AsyncAPI 3.0 document
| Object | What it records | Plant example |
|---|---|---|
asyncapi | The specification version | 3.0.0 |
info | Title, version and description of this application’s interface | “Line 3 filler events”, version 1.2.0 |
servers | Brokers the application connects to: host, protocol, pathname, security | The site MQTT broker on port 8883 with TLS |
channels | Addresses (topics, queues) and the messages that can appear on them | site1/packaging/line3/filler/state |
operations | What the application does on each channel: send or receive, and request and reply | The gateway sends state changes |
components | Reusable messages, schemas, security schemes, traits and bindings | The StateChanged message and its JSON Schema |
A worked plant example
The document below is illustrative. It describes an edge gateway that sends filler state changes to a plant MQTT broker, following the AsyncAPI 3.0 structure (specification).
asyncapi: 3.0.0
info:
title: Line 3 Filler Events
version: 1.2.0
description: State changes published by the line 3 filler edge gateway.
servers:
plantBroker:
host: broker.site1.example.local:8883
protocol: mqtt
channels:
fillerState:
address: site1/packaging/line3/filler/state
messages:
stateChanged:
$ref: '#/components/messages/StateChanged'
operations:
sendFillerState:
action: send
channel:
$ref: '#/channels/fillerState'
components:
messages:
StateChanged:
contentType: application/json
payload:
type: object
required: [eventId, state, timestamp]
properties:
eventId: { type: string, format: uuid }
state: { type: string, enum: [running, stopped, starved, blocked, faulted] }
reasonCode: { type: integer }
timestamp: { type: string, format: date-time }
What this gives the plant. The MES team knows the five allowed states and that eventId exists for de-duplication. The data team knows the timestamp format. A test can reject a message with a misspelt state before it reaches production. When the gateway owner wants to add a shift field, the version moves to 1.3.0 and every consumer listed against the channel can be told.
What changed in AsyncAPI 3.0
Version 3.0 was a breaking release. Teams with 2.x documents should plan a conversion; the AsyncAPI release notes summarise the changes (AsyncAPI).
| Change | In 2.x | In 3.0 | Why it matters |
|---|---|---|---|
| Operation keywords | publish and subscribe, which many readers found back to front | send and receive, from the application’s own point of view | Fewer misread documents |
| Channels and operations | Operations defined inside channels | Channels and messages detached from operations | A shared channel can be described once and reused |
| Request and reply | Not modelled directly | First-class request and reply | Commands and acknowledgements can be documented |
| Server address | A single url | Separate host, pathname and protocol | Clearer, easier to template per site |
| Messages on a channel | One message or oneOf | A named map of messages | Easier references and reuse |
| Reuse | Limited components | Components for channels, operations, replies and more | Shared plant conventions live in one place |
Bindings, CloudEvents and schema registries
Bindings carry protocol detail. AsyncAPI is protocol-agnostic, so MQTT-specific settings (QoS, retain), Kafka-specific settings (partitions, key schema) and others are expressed as bindings on servers, channels, operations or messages. Vendor protocols have bindings too; Solace, for example, contributed bindings for its own protocol.
CloudEvents is complementary. CloudEvents defines a common envelope inside each event (source, type, id, time and so on), and the CNCF graduated it in January 2024 (CNCF). AsyncAPI describes the interface; CloudEvents standardises the metadata. Using both gives tools a predictable event id and type without reading every schema.
Schema registries hold the payload schemas that AsyncAPI references, with compatibility checks when a schema changes. Kafka estates usually already run one. The AsyncAPI document and the registry should point at the same schema, not hold two copies.
Catalogues and governance

An event catalogue is the searchable collection of every AsyncAPI document and schema in the organisation, with owners, versions and the relationships between producers and consumers. For a manufacturer it becomes the plant data dictionary: a quality engineer can find “which events tell me a batch completed, and who owns them?” without asking around. Commercial catalogues exist, and some import and export AsyncAPI; the Solace Event Portal is one example (Solace docs). Open-source tooling from the AsyncAPI Initiative covers editing, validation and generation.
Governance in practice means a few rules that are actually enforced:
- Design first for shared events. The contract is reviewed before the producer is built.
- Version with meaning. Additive changes are minor versions; removed or renamed fields are major versions with a migration window.
- Validate in the pipeline. Documents are linted, and test messages are checked against the schema before deployment.
- Name an owner per event. The owner approves changes and answers questions.
- Keep the catalogue in step with runtime. Some tools compare what the broker actually carries with what is documented; without that, the catalogue drifts.
Where to start with AsyncAPI in a plant
Do not try to document everything at once. A practical first pass, in our view, looks like this:
- Pick the shared events. Start with the five to ten events more than one team consumes: machine state, counts, batch start and end, quality results, alarms that leave the site.
- Write one document per publisher. The edge gateway, the MES and the quality system each own a document for what they send.
- Agree the common parts once. Put the envelope fields (event id, timestamp, source, asset path) in shared components, ideally aligned with CloudEvents, and reference them from every document.
- Store the documents in Git next to the gateway or integration code, with a review step for changes.
- Render and publish them where plant and IT engineers will actually look, then add validation to the deployment pipeline.
The measure of success is simple: when someone asks what an event means, the answer is a link, not a meeting.
Limits and open questions
- Adoption in OT is early. Most plant MQTT namespaces are undocumented or documented in spreadsheets. AsyncAPI’s tooling grew up in software teams, and few OT products export it today.
- 3.0 tooling support varies. Version 3.0 is a breaking change, and not every generator, catalogue or vendor tool supported it equally at release. Check the version your tools read and write.
- Sparkplug payloads are a poor fit. Sparkplug’s Protobuf payload carries many metrics with their own names and types, so describing it as a fixed schema says little. Contextualised UNS payloads in JSON document far better.
- Documents drift. A contract that is not checked against what is actually published becomes fiction within months.
- It does not replace a topic convention. AsyncAPI documents channels; it does not decide how your namespace should be organised.
How to evaluate AsyncAPI for your architecture
- How many teams or vendors publish and consume shared events today?
- Where would the documents live, and how are they reviewed and versioned?
- Do your brokers, catalogue and generators support AsyncAPI 3.0?
- Will you use CloudEvents metadata, and is it in the schemas?
- Is there a schema registry, and do documents reference it rather than copy it?
- Who owns each shared event, and is that recorded in the document?
- Can you detect events on the broker that no document describes?
If the starting point is a namespace nobody has written down, documenting the current events is usually the first deliverable of an IT/OT integration engagement.
Deeper
There are no child pages under this guide yet. These go further:
- Solace Event Portal: one commercial catalogue and governance tool, independently reviewed
- Solace AsyncAPI and the event catalogue: AsyncAPI import, export and code generation in one product
- UNS Broker: the broker whose topics these documents describe
- Event Broker Comparison: the runtime side of the same decision
Back to the event-driven architecture hub.
Frequently asked questions
What is AsyncAPI?
AsyncAPI is an open specification for describing event-driven, asynchronous APIs in a machine-readable YAML or JSON document. It records which servers and protocols an application uses, which channels or topics it sends and receives on, and the structure of each message. It plays the role for events that OpenAPI plays for REST, and it is hosted by the Linux Foundation.
What changed in AsyncAPI 3.0?
AsyncAPI 3.0, released in December 2023, separates channels and messages from the operations performed on them, so channels can be reused across documents. It replaces the confusing publish and subscribe keywords with send and receive from the application's point of view, adds request and reply, splits the server URL into host, pathname and protocol, and widens what can be reused through components.
Is AsyncAPI the same as CloudEvents?
No, and they work together. AsyncAPI describes an application's event interface: channels, operations and message schemas. CloudEvents, a CNCF specification, defines a common envelope of metadata inside each event, such as its source, type, id and time. An AsyncAPI document can describe messages that follow the CloudEvents format.
Does AsyncAPI work with MQTT and Kafka?
Yes. AsyncAPI is protocol-agnostic and uses bindings to capture protocol-specific details. There are bindings for MQTT, Kafka, AMQP, JMS and several vendor protocols, so one document can state an MQTT topic's QoS and retain flag, or a Kafka topic's partitions and key schema, alongside the payload definition.
Do plants need AsyncAPI if they already have a UNS topic convention?
A topic convention says where events live; it does not say what is inside them, who publishes them, which version applies or who to call when they change. AsyncAPI documents that contract. For a single line it may be overkill, but once several teams or vendors publish and consume plant events, an AsyncAPI description per publisher prevents silent breakage.
References and further reading
- AsyncAPI Specification 3.0.0 · AsyncAPI Initiative
- AsyncAPI 3.0.0 Release Notes · AsyncAPI Initiative
- Linux Foundation Will Host AsyncAPI to Support Growth and Collaboration for Industry's Fastest-Growing API Spec · Linux Foundation
- CloudEvents · Cloud Native Computing Foundation
- Cloud Native Computing Foundation Announces the Graduation of CloudEvents · CNCF
- Solace Event Portal · SolaceOne commercial catalogue that imports and exports AsyncAPI.