API · Asyncapi

AsyncAPI Spec — A Field Guide

AsyncAPI Spec — A Field Guide is the work that makes the systems talk. The API is the contract between the producer and the consumer; the contract is what determines whether the.

John Kihiu12 min read

AsyncAPI is to event-driven APIs what OpenAPI is to REST: a machine-readable specification format for describing message channels, payloads, and bindings so that producers, consumers, and tooling can agree on a contract without reading each other's source code. It matters because message-driven systems — Kafka topics, MQTT streams, WebSocket channels, AMQP queues — have historically had no standard way to document "what messages flow where, in what shape," leaving that knowledge scattered across producer code, consumer code, and tribal knowledge.

The shape of an AsyncAPI document

An AsyncAPI document declares channels (the topics or queues messages flow through), the operations on each channel (send/receive), and messages with their payload schemas — typically JSON Schema, though Avro and Protobuf are also supported. A servers section describes the broker (Kafka cluster, MQTT broker, etc.) and its connection protocol. This is deliberately parallel to OpenAPI's structure so teams already familiar with API specs have a shorter ramp.

YAML · ASYNCAPI DOCUMENT
asyncapi: 3.0.0
info:
  title: Order Events API
  version: 1.0.0
servers:
  production:
    host: kafka.internal:9092
    protocol: kafka
channels:
  orderCreated:
    address: orders.created
    messages:
      OrderCreated:
        payload:
          type: object
          required: [orderId, customerId, total]
          properties:
            orderId: { type: string }
            customerId: { type: string }
            total: { type: number }
operations:
  publishOrderCreated:
    action: send
    channel:
      $ref: '#/channels/orderCreated'

Protocol bindings

Different brokers have protocol-specific concerns an abstract channel definition can't capture — a Kafka topic has partition keys and consumer groups, an MQTT channel has QoS levels and retain flags, an AMQP queue has exchange types and routing keys. AsyncAPI handles this with bindings, a protocol-specific extension block attached to a server, channel, or message that carries these details without polluting the protocol-agnostic core of the spec.

Code generation and tooling

The main practical payoff is generation: the AsyncAPI Generator can produce client/consumer stubs, HTML documentation, and even boilerplate for specific broker SDKs directly from the spec, similar to how OpenAPI generators produce REST clients. Studio, AsyncAPI's browser-based editor, gives real-time validation and a visual channel diagram while authoring the spec, which catches structural mistakes before they reach a producer or consumer implementation.

Treat the spec as the contract, not the documentation

The highest-value use of AsyncAPI is contract-first development: write the spec before the producer or consumer code, generate schemas/stubs from it, and validate messages against it in CI. Treating it as documentation written after the fact loses most of the tooling benefit and drifts out of sync with the real implementation quickly.

Versioning and schema evolution

Event-driven systems are harder to version than request/response APIs because a producer and its consumers deploy independently and a message published today may be consumed days later by a service that hasn't caught up yet. Favour additive, backward-compatible schema changes (new optional fields) over breaking ones, and when a breaking change is unavoidable, version the channel itself (orders.created.v2) rather than silently changing the payload shape underneath existing consumers.

A schema registry is not optional at scale

Once more than a couple of services produce or consume the same event type, pair AsyncAPI's design-time contract with a runtime schema registry (Confluent Schema Registry, AWS Glue Schema Registry, or similar) that actually enforces compatibility at publish time — the spec document alone doesn't stop a producer from emitting a message that violates it.

AsyncAPI vs. OpenAPI vs. CloudEvents

These three solve adjacent but distinct problems: OpenAPI describes synchronous HTTP request/response APIs, AsyncAPI describes the channels and message shapes of an event-driven system broker-agnostically, and CloudEvents standardises the envelope format of an individual event (its metadata — id, source, type, time) independent of the transport. It's common to use CloudEvents as the message envelope format referenced inside an AsyncAPI channel definition, rather than treating them as competing standards.

SpecDescribes
OpenAPISynchronous HTTP endpoints and payloads
AsyncAPIChannels, operations, and messages for event-driven systems
CloudEventsStandard envelope/metadata format for a single event

Wrapping up

AsyncAPI earns its place once more than one or two services produce and consume events without a shared contract — it turns implicit tribal knowledge about topic shapes into a validated, generatable spec. Pair it with a runtime schema registry so the contract is enforced, not just documented, and treat channel versioning the same seriousness you'd give a public REST API's breaking changes.

John Kihiu
Acumatica ERP Developer · Laravel Engineer

Independent software engineer in Nairobi specialising in Acumatica customisations, Laravel backends, and tax fiscalisation integrations across East and Southern Africa.