OpenLint
Type to search documentation.

AsyncAPI Rules

Spectral has a built-in “asyncapi” ruleset for the AsyncAPI Specification.

In your ruleset file you can add extends: "spectral:asyncapi" and you’ll get all of the following rules applied.

Recommended indicates whether a rule is enabled by default. Default severity when enabled is the severity the rule reports when active.

For simplicity, the rules are split up into v2 and v3 compliant rules to make it easier to know which apply when.

AsyncAPI v2 and v3

The following rules apply to both AsyncAPI v2 and v3 documents.

asyncapi-channel-parameters

All channel parameters should be defined in the parameters object of the channel. They should also not contain redundant parameters that do not exist in the channel address.

Recommended: Yes

Default severity when enabled: error

asyncapi-info-contact-properties

The asyncapi-info-contact rule will ask you to put in a contact object, and this rule will make sure it’s full of the most useful properties: name, url, and email.

Putting in the name of the developer/team/department/company responsible for the API, along with the support email and help-desk/GitHub Issues/whatever URL means people know where to go for help. This can mean more money in the bank, instead of developers just wandering off or complaining online.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
asyncapi: "2.0.0"
info:
title: Awesome API
description: A very well-defined API
version: "1.0"
contact:
name: A-Team
email: a-team@goarmy.com
url: https://goarmy.com/apis/support

asyncapi-info-contact

Info object should contain contact object.

Hopefully, your API description document is so good that nobody ever needs to contact you with questions, but that is rarely the case. The contact object has a few different options for contact details.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
asyncapi: "2.0.0"
info:
title: Awesome API
version: "1.0"
contact:
name: A-Team
email: a-team@goarmy.com

asyncapi-info-description

AsyncAPI object info description must be present and non-empty string.

Examples can contain Markdown so you can really go to town with them, implementing getting started information like where to find authentication keys, and how to use them.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
asyncapi: "2.0.0"
info:
version: "1.0.0"
title: Descriptive API
description: >+
Some description about the general point of this API, and why it exists when another similar but different API also exists.

asyncapi-info-license-url

Mentioning a license is only useful if people know what the license means, so add a link to the full text for those who need it.

Recommended: No

Default severity when enabled: warn

Good Example

yaml
asyncapi: "2.0.0"
info:
license:
name: MIT
url: https://www.tldrlegal.com/l/mit

asyncapi-info-license

The info object should have a license key.

It can be hard to pick a license, so if you don’t have a lawyer around you can use TLDRLegal and Choose a License to help give you an idea.

How useful this is in court is not entirely known, but having a license is better than not having a license.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
asyncapi: "2.0.0"
info:
license:
name: MIT

asyncapi-latest-version

Checking if the AsyncAPI document is using the latest version.

Recommended: Yes

Default severity when enabled: info

asyncapi-parameter-description

Parameter objects should have a description.

Recommended: No

Default severity when enabled: warn

asyncapi-servers

A non-empty servers object is expected to be located at the root of the document.

Recommended: Yes

Default severity when enabled: warn

asyncapi-unused-components-schema

Potential unused reusable schema entry has been detected.

Warning: This rule may identify false positives when linting a specification that acts as a library (a container storing reusable objects, leveraged by other specifications that reference those objects).

Recommended: Yes

Default severity when enabled: warn

asyncapi-unused-components-server

Potential unused reusable server entry has been detected.

Warning: This rule may identify false positives when linting a specification that acts as a library (a container storing reusable objects, leveraged by other specifications that reference those objects).

Recommended: Yes

Default severity when enabled: warn

AsyncAPI v2

The following rules ONLY apply to AsyncAPI v2 documents.

asyncapi-schema

Validate structure of AsyncAPI specification.

Recommended: Yes

Default severity when enabled: error

asyncapi-server-security

Server security values must match a scheme defined in the components.securitySchemes object. It also checks if there are oauth2 scopes that have been defined for the given security.

Recommended: Yes

Default severity when enabled: error

Good Example

yaml
asyncapi: 2.0.0
servers:
production:
url: test.mosquitto.org
security:
- petstore_auth: []
components:
securitySchemes:
petstore_auth: ...

Bad Example

yaml
asyncapi: 2.0.0
servers:
production:
url: test.mosquitto.org
security:
- not_defined: []
components:
securitySchemes:
petstore_auth: ...

asyncapi-channel-no-empty-parameter

Channel parameter declarations cannot be empty, ex./given/{} is invalid.

Recommended: Yes

Default severity when enabled: warn

asyncapi-channel-no-query-nor-fragment

Query parameters and fragments shouldn’t be used in channel names. Instead, use bindings to define them.

Recommended: Yes

Default severity when enabled: warn

asyncapi-channel-no-trailing-slash

Keep trailing slashes off of channel names, as it can cause some confusion. Most messaging protocols will treat example/foo and example/foo/ as different things. Keep in mind that tooling may replace slashes (/) with protocol-specific notation (e.g.: . for AMQP), therefore, a trailing slash may result in an invalid channel name in some protocols.

Recommended: Yes

Default severity when enabled: warn

asyncapi-channel-servers

Channel servers must be defined in the servers object.

Bad Example

yaml
asyncapi: "2.0.0"
info:
title: Awesome API
description: A very well-defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- development

Good Example

yaml
asyncapi: "2.0.0"
info:
title: Awesome API
description: A very well-defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- production

Recommended: Yes

Default severity when enabled: error

asyncapi-headers-schema-type-object

The schema definition of the application headers must be of type “object”.

Recommended: Yes

Default severity when enabled: error

asyncapi-message-examples

All examples in message object should follow payload and headers schemas.

Bad Example

yaml
asyncapi: "2.0.0"
info:
title: Bad API
version: "1.0.0"
components:
messages:
someMessage:
payload:
type: string
headers:
type: object
examples:
- payload: 2137
headers: someHeader

Good Example

yaml
asyncapi: "2.0.0"
info:
title: Good API
version: "1.0.0"
components:
messages:
someMessage:
payload:
type: string
headers:
type: object
examples:
- payload: foobar
headers:
someHeader: someValue

Recommended: Yes

Default severity when enabled: error

asyncapi-message-messageId-uniqueness

messageId must be unique across all the messages (except those one defined in the components).

Recommended: Yes

Default severity when enabled: error

Bad Example

yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
message:
messageId: turnMessage
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
message:
messageId: turnMessage

Good Example

yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
message:
messageId: turnOnMessage
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
message:
messageId: turnOffMessage

asyncapi-operation-description

Operation objects should have a description.

Recommended: Yes

Default severity when enabled: warn

asyncapi-operation-operationId-uniqueness

operationId must be unique across all the operations (except the ones defined in the components).

Recommended: Yes

Default severity when enabled: error

Bad Example

yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
operationId: turn
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
operationId: turn

Good Example

yaml
channels:
smartylighting.streetlights.1.0.action.{streetlightId}.turn.on:
publish:
operationId: turnOn
smartylighting.streetlights.1.0.action.{streetlightId}.turn.off:
publish:
operationId: turnOff

asyncapi-operation-operationId

This operation ID is essentially a reference for the operation. Tools may use it for defining function names, class method names, and even URL hashes in documentation systems.

Recommended: Yes

Default severity when enabled: error

asyncapi-operation-security

Operation security values must match a scheme defined in the components.securitySchemes object. It also checks if there are oauth2 scopes that have been defined for the given security.

Recommended: Yes

Default severity when enabled: error

Good Example

yaml
channels:
"user/signup":
publish:
security:
- petstore_auth: []
components:
securitySchemes:
petstore_auth: ...

Bad Example

yaml
channels:
"user/signup":
publish:
security:
- not_defined: []
components:
securitySchemes:
petstore_auth: ...

asyncapi-payload-default

default objects should be valid against the payload they decorate.

Recommended: Yes

Default severity when enabled: error

Good Example

yaml
payload:
type: object
properties:
value:
type: integer
required:
- value
default:
value: 17

Bad Example

yaml
payload:
type: object
properties:
value:
type: integer
required:
- value
default:
value: nope!

asyncapi-payload-examples

Values of the examples array should be valid against the payload they decorate.

Recommended: Yes

Default severity when enabled: error

Good Example

yaml
payload:
type: object
properties:
value:
type: integer
required:
- value
examples:
- value: 13
- value: 17

Bad Example

yaml
payload:
type: object
properties:
value:
type: integer
required:
- value
examples:
- value: nope! # Wrong type
- notGoodEither: 17 # Missing required property

asyncapi-payload-unsupported-schemaFormat

AsyncAPI can support various schemaFormat values. When unspecified, one of the following will be assumed:

application/vnd.aai.asyncapi;version=2.0.0 application/vnd.aai.asyncapi+json;version=2.0.0 application/vnd.aai.asyncapi+yaml;version=2.0.0

At this point, explicitly setting schemaFormat is not supported by Spectral, so if you use it this rule will emit an info message and skip validating the payload.

Other formats such as OpenAPI Schema Object, JSON Schema Draft 07, and Avro will be added in various upcoming versions.

Recommended: Yes

Default severity when enabled: info

asyncapi-payload

When schemaFormat is undefined, the payload object should be valid against the AsyncAPI v2 Schema Object definition.

Recommended: Yes

Default severity when enabled: error

asyncapi-schema-default

default objects should be valid against the schema they decorate.

Recommended: Yes

Default severity when enabled: error

asyncapi-schema-examples

Values of the examples array should be valid against the schema they decorate.

Recommended: Yes

Default severity when enabled: error

asyncapi-server-no-empty-variable

Server URL variable declarations cannot be empty, ex.gigantic-server.com/{} is invalid.

Recommended: Yes

Default severity when enabled: warn

asyncapi-server-no-trailing-slash

Server URL should not have a trailing slash.

Some tooling forgets to strip trailing slashes off when it’s joining the servers.url with channels, and you can get awkward URLs like mqtt://example.com/broker//pets. Best to just strip them off yourself.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
servers:
- url: mqtt://example.com
- url: mqtt://example.com/broker

Bad Example

yaml
servers:
- url: mqtt://example.com/
- url: mqtt://example.com/broker/

asyncapi-server-not-example-com

Server URL should not point to example.com.

Recommended: No

Default severity when enabled: warn

asyncapi-server-variables

All server URL variables should be defined in the variables object of the server. They should also not contain redundant variables that do not exist in the server address.

Recommended: Yes

Default severity when enabled: error

asyncapi-tag-description

Tags alone are not very descriptive. Give folks a bit more information to work with.

yaml
tags:
- name: "Aardvark"
description: Funny-nosed pig-head raccoon.
- name: "Badger"
description: Angry short-legged omnivores.

If your tags are business objects then you can use the term to explain them a bit. An ‘Account’ could be a user account, company information, bank account, potential sales lead, or anything. What is clear to the folks writing the document is probably not as clear to others.

yaml
tags:
- name: Invoice Items
description: |+
Giant long explanation about what this business concept is, because other people _might_ not have a clue!

Recommended: No

Default severity when enabled: warn

asyncapi-tags-alphabetical

AsyncAPI object should have alphabetical tags. This will be sorted by the name property.

Recommended: No

Default severity when enabled: warn

Bad Example

yaml
tags:
- name: "Badger"
- name: "Aardvark"

Good Example

yaml
tags:
- name: "Aardvark"
- name: "Badger"

Recommended: No

asyncapi-tags-uniqueness

Tags must not have duplicate names (identifiers).

Recommended: Yes

Default severity when enabled: error

Bad Example

yaml
tags:
- name: "Badger"
- name: "Badger"

Good Example

yaml
tags:
- name: "Aardvark"
- name: "Badger"

asyncapi-tags

AsyncAPI root object should have non-empty tags array.

Why? Well, you can reference tags arbitrarily in operations, and definition is optional…

yaml
/invoices/{id}/items:
tags:
- Invoice Items

Defining tags allows you to add more information like a description. For more information see asyncapi-tag-description.

Recommended: Yes

Default severity when enabled: warn

AsyncAPI v3

The following rules ONLY apply to AsyncAPI v3 documents.

asyncapi-3-channel-no-empty-parameter

Channel address parameter declarations cannot be empty, ex./given/{} is invalid.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-channel-no-query-nor-fragment

Query parameters and fragments shouldn’t be used in channel address. Instead, use bindings to define them, ex./given?test is invalid.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-channel-no-trailing-slash

Keep trailing slashes off of channel address, as it can cause some confusion. Most messaging protocols will treat example/foo and example/foo/ as different things. Keep in mind that tooling may replace slashes (/) with protocol-specific notation (e.g.: . for AMQP), therefore, a trailing slash may result in an invalid channel address in some protocols.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-channel-servers

Channel servers must be defined in the servers object.

Bad Example

yaml
asyncapi: "3.1.0"
info:
title: Awesome API
description: A very well-defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- $ref: #/servers/development

Good Example

yaml
asyncapi: "3.1.0"
info:
title: Awesome API
description: A very well-defined API
version: "1.0"
servers:
production:
url: "stoplight.io"
protocol: "https"
channels:
hello:
servers:
- $ref: #/servers/production

Recommended: Yes

Default severity when enabled: error

asyncapi-3-headers-schema-type-object

The schema definition of the application headers must be of type “object”.

Recommended: Yes

Default severity when enabled: error

asyncapi-3-operation-security

Operations must reference a defined security scheme.

Recommended: Yes

Default severity when enabled: error

asyncapi-3-operation-description

Operation objects should have a description.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-payload-unsupported-schemaFormat

AsyncAPI can support various schemaFormat values. When unspecified, one of the following will be assumed:

application/vnd.aai.asyncapi;version=2.0.0 application/vnd.aai.asyncapi+json;version=2.0.0 application/vnd.aai.asyncapi+yaml;version=2.0.0

At this point, explicitly setting schemaFormat is not supported by Spectral, so if you use it this rule will emit an info message and skip validating the payload.

Other formats such as OpenAPI Schema Object, JSON Schema Draft 07, and Avro will be added in various upcoming versions.

Recommended: Yes

Default severity when enabled: info

asyncapi-3-server-no-empty-variable

Server host and pathname variable declarations cannot be empty, ex.gigantic-server.com{} is invalid.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-server-no-trailing-slash

Server host should not have a trailing slash.

Some tooling forgets to strip trailing slashes off when it’s joining the servers.host with channels, and you can get awkward URLs like mqtt://example.com//pets. Best to just strip them off yourself.

Recommended: Yes

Default severity when enabled: warn

Good Example

yaml
servers:
- host: mqtt://example.com

Bad Example

yaml
servers:
- host: mqtt://example.com/
- host: mqtt://example.com/broker/

asyncapi-3-server-not-example-com

Server host should not point to example.com.

Recommended: No

Default severity when enabled: warn

asyncapi-3-tag-description

Tags alone are not very descriptive. Give folks a bit more information to work with.

yaml
info:
tags:
- name: "Aardvark"
description: Funny-nosed pig-head raccoon.
- name: "Badger"
description: Angry short-legged omnivores.

If your tags are business objects then you can use the term to explain them a bit. An ‘Account’ could be a user account, company information, bank account, potential sales lead, or anything. What is clear to the folks writing the document is probably not as clear to others.

yaml
info:
tags:
- name: Invoice Items
description: |+
Giant long explanation about what this business concept is, because other people _might_ not have a clue!

Recommended: No

Default severity when enabled: warn

asyncapi-3-tags-alphabetical

AsyncAPI object should have alphabetical tags. This will be sorted by the name property.

Recommended: No

Default severity when enabled: warn

Bad Example

yaml
info:
tags:
- name: "Badger"
- name: "Aardvark"

Good Example

yaml
info:
tags:
- name: "Aardvark"
- name: "Badger"

Recommended: No

asyncapi-3-tags-uniqueness

Tags must not have duplicate names (identifiers).

Recommended: Yes

Default severity when enabled: error

Bad Example

yaml
info:
tags:
- name: "Badger"
- name: "Badger"

Good Example

yaml
info:
tags:
- name: "Aardvark"
- name: "Badger"

asyncapi-3-tags

AsyncAPI object should have non-empty tags array.

Why? Well, you can reference tags arbitrarily in operations, and definition is optional…

yaml
invoicedItems:
address: /invoices/{id}/items
tags:
- Invoice Items

Defining tags allows you to add more information like a description. For more information see asyncapi-3-tag-description.

Recommended: Yes

Default severity when enabled: warn

asyncapi-3-document-resolved

Validate structure of AsyncAPI specification when references have been resolved.

Recommended: Yes

Default severity when enabled: error

asyncapi-3-document-unresolved

Validate structure of AsyncAPI specification before references have been resolved.

Recommended: Yes

Default severity when enabled: error

Last updated Oct 24, 2026