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.
AsyncAPI vs JSON Schema
Section titled “AsyncAPI vs JSON Schema”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
payloadandheaders.
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 |
A payload with JSON Schema
Section titled “A payload with JSON Schema”asyncapi: 3.0.0info: title: Orders version: 1.0.0channels: 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: 1Where examples go
Section titled “Where examples go”There are two places, for two purposes:
- The message’s
examples: whole example messages, each with an optionalname,summary,headersandpayload, as above. Documentation and mock servers show these. - The schema’s
exampleskeyword: example values for one schema or property, for exampleexamples: [BOOK-42]onsku. 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 map whose values follow another schema
Section titled “A map whose values follow another schema”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: integerpropertyNames is optional and constrains the keys.
A field required only in some cases
Section titled “A field required only in some cases”Draft 07 has no dependentRequired; use if/then (or dependencies):
type: objectproperties: paymentMethod: type: string enum: [card, invoice] cardToken: type: stringif: properties: paymentMethod: const: cardthen: required: [cardToken]cardToken is required only when paymentMethod is card.
Reference other schemas
Section titled “Reference other schemas”- 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'.
Use plain JSON Schema files
Section titled “Use plain JSON Schema files”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.
Related
Section titled “Related”- Schema Object and Multi Format Schema Object
- Avro schemas in AsyncAPI
- Protobuf schemas in AsyncAPI
- Validate AsyncAPI with the schema registry
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.