Skip to content

JSON Schema in AsyncAPI

AsyncAPI describes message payloads with JSON Schema. A payload without a schemaFormat is an AsyncAPI Schema Object: JSON Schema Draft 07 plus a few AsyncAPI keywords. This page answers the questions that come up most when writing those payloads.

They describe different things and work together:

  • AsyncAPI describes an event-driven API: servers, channels, operations (send and receive), messages, bindings and security.
  • JSON Schema describes the shape of data. AsyncAPI uses it for each message’s payload and headers.

An AsyncAPI document is itself validated by a JSON Schema (see the schema registry), which is a third, separate thing.

The AsyncAPI Schema Object adds these keywords to Draft 07:

Keyword What it adds
discriminator The property that tells which oneOf/allOf variant a value is
externalDocs A link to external documentation for this schema
deprecated Marks the schema as no longer to be used
x-… Specification extensions for your own tooling
asyncapi: 3.0.0
info:
title: Orders
version: 1.0.0
channels:
orderPlaced:
address: orders.placed
messages:
orderPlaced:
$ref: '#/components/messages/orderPlaced'
operations:
onOrderPlaced:
action: receive
channel:
$ref: '#/channels/orderPlaced'
components:
messages:
orderPlaced:
contentType: application/json
payload:
$ref: '#/components/schemas/OrderPlaced'
examples:
- name: smallOrder
summary: An order with one line
payload:
orderId: 9f4c2a1e-0b7d-4f43-9a51-2a4f0c6f2d10
placedAt: '2026-11-06T10:15:00Z'
lines:
- sku: BOOK-42
quantity: 1
schemas:
OrderPlaced:
type: object
required: [orderId, placedAt, lines]
properties:
orderId:
type: string
format: uuid
placedAt:
type: string
format: date-time
lines:
type: array
minItems: 1
items:
$ref: '#/components/schemas/OrderLine'
OrderLine:
type: object
required: [sku, quantity]
properties:
sku:
type: string
quantity:
type: integer
minimum: 1

There are two places, for two purposes:

  • The message’s examples: whole example messages, each with an optional name, summary, headers and payload, as above. Documentation and mock servers show these.
  • The schema’s examples keyword: example values for one schema or property, for example examples: [BOOK-42] on sku. Use it for single fields.

The specification doesn’t require tools to check message examples against the payload schema. AsyncAPI CLI does for 2.x documents (rule asyncapi2-message-examples), so keep them valid either way.

A JSON object with free-form keys is a map. Describe the values with additionalProperties:

components:
schemas:
StockLevels:
description: Stock per warehouse ID
type: object
additionalProperties:
$ref: '#/components/schemas/Stock'
propertyNames:
pattern: '^WH-[0-9]{3}$'
Stock:
type: object
properties:
available:
type: integer
reserved:
type: integer

propertyNames is optional and constrains the keys.

Draft 07 has no dependentRequired; use if/then (or dependencies):

type: object
properties:
paymentMethod:
type: string
enum: [card, invoice]
cardToken:
type: string
if:
properties:
paymentMethod:
const: card
then:
required: [cardToken]

cardToken is required only when paymentMethod is card.

  • In the same document: $ref: '#/components/schemas/OrderLine'.
  • In another file: $ref: './schemas/order-line.json' or a URL. The file is a schema, not a whole AsyncAPI document.
  • Into another file: $ref: './common.yaml#/components/schemas/Money'.

If your schemas are standalone JSON Schema Draft 07 files, say so with schemaFormat, so tools don’t read AsyncAPI keywords into them:

components:
messages:
orderPlaced:
payload:
schemaFormat: application/schema+json;version=draft-07
schema:
$ref: './schemas/order-placed.schema.json'

Use application/schema+yaml;version=draft-07 for YAML files. In AsyncAPI 2.x, put schemaFormat on the message and the $ref directly in payload. To convert a JSON Schema into an AsyncAPI document, reference it like this from a message: the rest of the document (channels, operations) has to be written, since JSON Schema doesn’t know about them.

Questions

Which JSON Schema version does AsyncAPI use?

Draft 07, in AsyncAPI 2.x and 3.0. For newer drafts, AsyncAPI has no schemaFormat that tools must support, so features such as dependentRequired, unevaluatedProperties and $defs aren't guaranteed to work.

Why does validation say a payload "must match else schema"?

The AsyncAPI 3.0 JSON Schema treats a payload with a schema property as a Multi Format Schema and anything else as a Schema Object, using if/then/else. The error means the payload went to the else branch and is not a valid Schema Object, often because schemaFormat was set on the message 2.x-style, or a non-JSON-Schema definition was put directly in payload.

Why do generated docs show "anonymous-schema-1"?

The AsyncAPI parser gives every inline schema without an ID a generated name. Define the schema under components.schemas and reference it with $ref: the parser then uses the component name.