{} SchemaforAI.dev

API Documentation Standards: OpenAPI, AsyncAPI & Structured Specifications

Guide Published April 2026 · 15 min read

API documentation is structured data for developers. When your API documentation follows established standards like OpenAPI and AsyncAPI, it becomes machine-readable by default. This matters for two reasons: it makes your API easier to integrate with, and it makes your product's capabilities visible to AI engines that parse technical documentation to generate recommendations.

This guide covers the major API documentation standards, provides complete examples you can adapt, and explains how structured API docs relate to broader discoverability across search and AI systems.

The API Documentation Standards Landscape

Three specifications dominate the API documentation space in 2026:

StandardUse CaseCurrent VersionGoverned By
OpenAPIREST / HTTP APIs3.1.0OpenAPI Initiative (Linux Foundation)
AsyncAPIEvent-driven / message-based APIs3.0.0AsyncAPI Initiative (Linux Foundation)
JSON SchemaData validation / schema definitions2020-12JSON Schema Organization

OpenAPI handles the vast majority of API documentation needs. AsyncAPI extends the same philosophy to event-driven architectures. JSON Schema underpins both, providing the data model definitions that describe request bodies, response payloads, and message formats.

OpenAPI Specification (OAS)

The OpenAPI Specification is the industry standard for describing RESTful APIs. Originally known as Swagger, the specification was donated to the Linux Foundation's OpenAPI Initiative in 2015 and has since evolved through major versions.

Complete OpenAPI 3.1 Example

Here is a production-ready OpenAPI document for a visibility tracking API. This example demonstrates the core patterns you need:

openapi: "3.1.0"
info:
  title: Brand Visibility API
  version: "2.0.0"
  description: |
    REST API for tracking brand visibility across AI-generated
    search responses. Provides endpoints for monitoring mention
    rates, citation quality, and competitive positioning.
  contact:
    name: API Support
    email: api-support@example.com
    url: https://docs.example.com/support
  license:
    name: Apache 2.0
    url: https://www.apache.org/licenses/LICENSE-2.0
  termsOfService: https://example.com/terms

servers:
  - url: https://api.example.com/v2
    description: Production
  - url: https://staging-api.example.com/v2
    description: Staging

security:
  - bearerAuth: []

tags:
  - name: Brands
    description: Brand entity management
  - name: Visibility
    description: AI visibility tracking and metrics
  - name: Reports
    description: Scheduled and on-demand reporting

paths:
  /brands:
    get:
      operationId: listBrands
      tags: [Brands]
      summary: List all monitored brands
      description: |
        Returns a paginated list of all brands being monitored
        in the current workspace. Supports filtering by status
        and sorting by name or creation date.
      parameters:
        - name: page
          in: query
          schema:
            type: integer
            minimum: 1
            default: 1
          description: Page number for pagination
        - name: per_page
          in: query
          schema:
            type: integer
            minimum: 1
            maximum: 100
            default: 25
          description: Number of results per page
        - name: status
          in: query
          schema:
            type: string
            enum: [active, paused, archived]
          description: Filter by monitoring status
        - name: sort
          in: query
          schema:
            type: string
            enum: [name, created_at, visibility_score]
            default: name
          description: Sort field
      responses:
        "200":
          description: Successful response with list of brands
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: array
                    items:
                      $ref: "#/components/schemas/Brand"
                  meta:
                    $ref: "#/components/schemas/PaginationMeta"
              example:
                data:
                  - id: "brand_abc123"
                    name: "Acme Corp"
                    domain: "acmecorp.com"
                    status: "active"
                    visibility_score: 72.4
                    created_at: "2026-01-15T10:30:00Z"
                meta:
                  page: 1
                  per_page: 25
                  total: 12
                  total_pages: 1
        "401":
          $ref: "#/components/responses/Unauthorized"
        "429":
          $ref: "#/components/responses/RateLimited"

    post:
      operationId: createBrand
      tags: [Brands]
      summary: Add a new brand to monitor
      description: |
        Creates a new brand entity and begins monitoring its
        visibility across AI-generated search responses.
        Initial data collection takes 24-48 hours.
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/CreateBrandRequest"
            example:
              name: "Acme Corp"
              domain: "acmecorp.com"
              competitors:
                - "competitor1.com"
                - "competitor2.com"
              keywords:
                - "project management software"
                - "team collaboration tool"
      responses:
        "201":
          description: Brand created successfully
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Brand"
        "400":
          $ref: "#/components/responses/BadRequest"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "409":
          description: Brand with this domain already exists
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/Error"

  /brands/{brandId}/visibility:
    get:
      operationId: getVisibilityMetrics
      tags: [Visibility]
      summary: Get AI visibility metrics for a brand
      description: |
        Returns detailed visibility metrics including mention
        rates, citation quality scores, and positional data
        across multiple AI engines.
      parameters:
        - name: brandId
          in: path
          required: true
          schema:
            type: string
          description: Unique brand identifier
        - name: period
          in: query
          schema:
            type: string
            enum: [7d, 30d, 90d, 12m]
            default: 30d
          description: Time period for metrics
        - name: engines
          in: query
          schema:
            type: array
            items:
              type: string
              enum: [chatgpt, claude, perplexity, google_aio]
          style: form
          explode: false
          description: Filter by AI engine (comma-separated)
      responses:
        "200":
          description: Visibility metrics
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/VisibilityReport"
        "401":
          $ref: "#/components/responses/Unauthorized"
        "404":
          $ref: "#/components/responses/NotFound"

components:
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT
      description: |
        JWT token obtained from the /auth/token endpoint.
        Include as: Authorization: Bearer <token>

  schemas:
    Brand:
      type: object
      required: [id, name, domain, status]
      properties:
        id:
          type: string
          description: Unique identifier
          example: "brand_abc123"
        name:
          type: string
          description: Brand display name
          example: "Acme Corp"
        domain:
          type: string
          format: hostname
          description: Primary domain
          example: "acmecorp.com"
        status:
          type: string
          enum: [active, paused, archived]
          description: Current monitoring status
        visibility_score:
          type: number
          format: float
          minimum: 0
          maximum: 100
          description: |
            Composite AI visibility score (0-100).
            Calculated from mention rate, citation quality,
            and positional data across monitored engines.
          example: 72.4
        competitors:
          type: array
          items:
            type: string
            format: hostname
          description: Competitor domains being tracked
        created_at:
          type: string
          format: date-time
          description: ISO 8601 creation timestamp

    CreateBrandRequest:
      type: object
      required: [name, domain]
      properties:
        name:
          type: string
          minLength: 1
          maxLength: 200
          description: Brand display name
        domain:
          type: string
          format: hostname
          description: Primary domain to monitor
        competitors:
          type: array
          items:
            type: string
            format: hostname
          maxItems: 10
          description: Competitor domains (max 10)
        keywords:
          type: array
          items:
            type: string
          maxItems: 50
          description: Keywords to track (max 50)

    VisibilityReport:
      type: object
      properties:
        brand_id:
          type: string
        period:
          type: string
        overall_score:
          type: number
          format: float
        mention_count:
          type: integer
          description: Total mentions across all engines
        avg_position:
          type: number
          format: float
          description: |
            Average mention position (1.0 = always first
            mentioned, higher = mentioned later in responses)
        engines:
          type: array
          items:
            type: object
            properties:
              name:
                type: string
              mentions:
                type: integer
              avg_position:
                type: number
                format: float
              citation_quality:
                type: number
                format: float
                description: 0-100 score for citation accuracy
        trend:
          type: string
          enum: [improving, stable, declining]
          description: Visibility trend over the period

    PaginationMeta:
      type: object
      properties:
        page:
          type: integer
        per_page:
          type: integer
        total:
          type: integer
        total_pages:
          type: integer

    Error:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          description: Machine-readable error code
          example: "BRAND_NOT_FOUND"
        message:
          type: string
          description: Human-readable error description
          example: "No brand found with the specified ID"
        details:
          type: object
          additionalProperties: true
          description: Additional error context

  responses:
    Unauthorized:
      description: Authentication required or token invalid
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "UNAUTHORIZED"
            message: "Invalid or expired authentication token"
    NotFound:
      description: Requested resource not found
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    BadRequest:
      description: Invalid request parameters
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
    RateLimited:
      description: Rate limit exceeded
      headers:
        Retry-After:
          schema:
            type: integer
          description: Seconds until rate limit resets
      content:
        application/json:
          schema:
            $ref: "#/components/schemas/Error"
          example:
            code: "RATE_LIMITED"
            message: "Rate limit exceeded. Try again in 60 seconds."

Key OpenAPI Patterns Explained

Info object: The info section is the first thing both developers and AI engines read. Include a clear description, contact details, and terms of service. This metadata is indexed and used when AI systems describe your API.

Components and $ref: Reusable schema definitions in components/schemas reduce duplication and ensure consistency. When you change a schema, every reference updates automatically. This is equivalent to DRY principles in code.

Examples: Inline example values are critical for both developer experience and AI comprehension. AI engines use these to understand the shape and meaning of your data. Always include realistic examples, not placeholders like "string" or "123".

Error responses: Define error schemas as reusable responses. Consistent error handling is a strong quality signal for AI engines evaluating your API documentation.

Best practice: Use operationId on every operation. This provides a stable, unique identifier that code generators and AI systems use to reference specific endpoints. Choose descriptive names: listBrands is better than getBrands or brands_get.

AsyncAPI for Event-Driven APIs

The AsyncAPI specification is to event-driven architectures what OpenAPI is to REST APIs. It describes message-based APIs that use protocols like WebSocket, Kafka, MQTT, AMQP, and Server-Sent Events.

Complete AsyncAPI 3.0 Example

asyncapi: "3.0.0"
info:
  title: Visibility Events API
  version: "1.0.0"
  description: |
    Real-time event stream for brand visibility changes.
    Subscribe to receive notifications when visibility
    metrics change, new mentions are detected, or
    competitive positioning shifts.
  contact:
    name: Events API Support
    email: events-support@example.com
  license:
    name: Apache 2.0

servers:
  production:
    host: events.example.com
    protocol: wss
    description: Production WebSocket endpoint
    security:
      - type: http
        scheme: bearer
  staging:
    host: events-staging.example.com
    protocol: wss
    description: Staging WebSocket endpoint

channels:
  brandMentions:
    address: /brands/{brandId}/mentions
    description: |
      Stream of new brand mentions detected across AI engines.
      Each message contains the mention context, source engine,
      query that triggered it, and positional data.
    parameters:
      brandId:
        description: Unique brand identifier
    messages:
      newMention:
        $ref: "#/components/messages/MentionDetected"

  visibilityAlerts:
    address: /brands/{brandId}/alerts
    description: |
      Alerts for significant visibility changes. Triggered
      when visibility score changes by more than 5 points
      or when competitive ranking shifts.
    parameters:
      brandId:
        description: Unique brand identifier
    messages:
      visibilityChange:
        $ref: "#/components/messages/VisibilityAlert"

  competitorUpdates:
    address: /workspace/competitors
    description: |
      Workspace-wide competitor activity feed. Aggregates
      notable changes across all monitored competitors.
    messages:
      competitorChange:
        $ref: "#/components/messages/CompetitorUpdate"

operations:
  receiveMention:
    action: receive
    channel:
      $ref: "#/channels/brandMentions"
    summary: Receive new mention notifications
    description: |
      Subscribe to this channel to receive real-time
      notifications when your brand is mentioned in
      AI-generated responses.

  receiveAlert:
    action: receive
    channel:
      $ref: "#/channels/visibilityAlerts"
    summary: Receive visibility change alerts

  receiveCompetitorUpdate:
    action: receive
    channel:
      $ref: "#/channels/competitorUpdates"
    summary: Receive competitor activity updates

components:
  messages:
    MentionDetected:
      name: MentionDetected
      title: New Brand Mention
      contentType: application/json
      payload:
        type: object
        required: [id, brand_id, engine, detected_at]
        properties:
          id:
            type: string
            description: Unique mention identifier
            example: "mention_xyz789"
          brand_id:
            type: string
            example: "brand_abc123"
          engine:
            type: string
            enum: [chatgpt, claude, perplexity, google_aio]
            description: AI engine where mention was detected
          query:
            type: string
            description: User query that triggered the mention
            example: "best project management tools for remote teams"
          position:
            type: integer
            minimum: 1
            description: Position in the response (1 = first mentioned)
            example: 2
          context:
            type: string
            description: Surrounding text context of the mention
            example: "...tools like Asana and Acme Corp offer real-time..."
          citation_type:
            type: string
            enum: [direct_quote, paraphrase, recommendation, comparison]
          sentiment:
            type: string
            enum: [positive, neutral, negative]
          detected_at:
            type: string
            format: date-time

    VisibilityAlert:
      name: VisibilityAlert
      title: Visibility Change Alert
      contentType: application/json
      payload:
        type: object
        required: [brand_id, alert_type, severity]
        properties:
          brand_id:
            type: string
          alert_type:
            type: string
            enum:
              - score_increase
              - score_decrease
              - rank_change
              - new_competitor_detected
              - mention_spike
          severity:
            type: string
            enum: [info, warning, critical]
          previous_value:
            type: number
          current_value:
            type: number
          description:
            type: string
            example: "Visibility score increased from 68.2 to 74.1 (+5.9)"
          triggered_at:
            type: string
            format: date-time

    CompetitorUpdate:
      name: CompetitorUpdate
      title: Competitor Activity Update
      contentType: application/json
      payload:
        type: object
        properties:
          competitor_domain:
            type: string
            format: hostname
          change_type:
            type: string
            enum: [visibility_change, new_content, schema_update]
          summary:
            type: string
          detected_at:
            type: string
            format: date-time

When to Use AsyncAPI

Use AsyncAPI when your API involves any of these patterns:

If your system uses both REST endpoints and event-driven messaging, maintain both OpenAPI and AsyncAPI specifications. Many modern platforms document their REST API with OpenAPI and their event streams with AsyncAPI.

JSON Schema for Data Validation

JSON Schema is the foundation that both OpenAPI and AsyncAPI build on for data type definitions. Understanding JSON Schema independently is valuable because you can use it for configuration validation, form generation, and data documentation beyond API contexts.

Complete JSON Schema Example

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://example.com/schemas/brand-config.json",
  "title": "Brand Configuration",
  "description": "Configuration schema for setting up brand monitoring. Defines required fields, validation rules, and defaults for new brand entities.",
  "type": "object",
  "required": ["name", "domain", "monitoring"],
  "properties": {
    "name": {
      "type": "string",
      "minLength": 1,
      "maxLength": 200,
      "description": "Display name for the brand",
      "examples": ["Acme Corp", "TechStart Inc."]
    },
    "domain": {
      "type": "string",
      "format": "hostname",
      "description": "Primary domain to monitor",
      "examples": ["acmecorp.com"]
    },
    "aliases": {
      "type": "array",
      "items": {
        "type": "string",
        "minLength": 1
      },
      "maxItems": 20,
      "uniqueItems": true,
      "description": "Alternative names, abbreviations, or brand variations",
      "default": [],
      "examples": [["Acme", "ACME Corp", "Acme Corporation"]]
    },
    "monitoring": {
      "type": "object",
      "required": ["engines", "keywords"],
      "properties": {
        "engines": {
          "type": "array",
          "items": {
            "type": "string",
            "enum": ["chatgpt", "claude", "perplexity", "google_aio", "copilot"]
          },
          "minItems": 1,
          "uniqueItems": true,
          "description": "AI engines to monitor for brand mentions"
        },
        "keywords": {
          "type": "array",
          "items": {
            "type": "string",
            "minLength": 2,
            "maxLength": 100
          },
          "minItems": 1,
          "maxItems": 50,
          "description": "Search queries to monitor"
        },
        "frequency": {
          "type": "string",
          "enum": ["hourly", "daily", "weekly"],
          "default": "daily",
          "description": "How often to check for new mentions"
        },
        "competitors": {
          "type": "array",
          "items": {
            "type": "string",
            "format": "hostname"
          },
          "maxItems": 10,
          "default": [],
          "description": "Competitor domains to track for comparison"
        }
      },
      "additionalProperties": false
    },
    "notifications": {
      "type": "object",
      "properties": {
        "email": {
          "type": "string",
          "format": "email",
          "description": "Email address for alert notifications"
        },
        "webhook_url": {
          "type": "string",
          "format": "uri",
          "description": "Webhook endpoint for real-time alerts"
        },
        "alert_threshold": {
          "type": "number",
          "minimum": 1,
          "maximum": 50,
          "default": 5,
          "description": "Minimum visibility score change to trigger alert"
        }
      }
    }
  },
  "additionalProperties": false,
  "examples": [
    {
      "name": "Acme Corp",
      "domain": "acmecorp.com",
      "aliases": ["Acme", "ACME"],
      "monitoring": {
        "engines": ["chatgpt", "claude", "perplexity"],
        "keywords": ["project management software", "team collaboration tool"],
        "frequency": "daily",
        "competitors": ["competitor1.com", "competitor2.com"]
      },
      "notifications": {
        "email": "alerts@acmecorp.com",
        "alert_threshold": 5
      }
    }
  ]
}

Key JSON Schema features demonstrated:

Documentation Tooling

These tools generate interactive, browsable documentation from your OpenAPI and AsyncAPI specifications:

ToolSpecificationTypeKey Feature
Swagger UIOpenAPIFree / OSSInteractive API explorer with "Try it" functionality
RedoclyOpenAPIFreemiumThree-panel layout, SEO-friendly output, API linting
StoplightOpenAPIFreemiumVisual API design, mock servers, style guides
AsyncAPI StudioAsyncAPIFree / OSSVisual editor and documentation generator for AsyncAPI
Bump.shBothFreemiumHosted docs with change tracking and diff detection
Tooling tip: Choose a documentation tool that generates static HTML pages. These are crawlable by search engines and AI systems. JavaScript-rendered documentation (like default Swagger UI) is harder for crawlers to parse. Redocly and Bump.sh both produce SEO-friendly static output.

Best Practices for Machine-Readable API Docs

1. Write Descriptions for Machines and Humans

Every endpoint, parameter, and schema should have a description field. These descriptions are what AI engines read when summarizing your API's capabilities.

# BAD: No description
parameters:
  - name: q
    in: query
    schema:
      type: string

# GOOD: Descriptive, specific, useful
parameters:
  - name: q
    in: query
    description: |
      Full-text search query. Searches across brand name,
      domain, and keyword fields. Supports quoted phrases
      for exact matching. Maximum 200 characters.
    schema:
      type: string
      maxLength: 200
    example: "project management"

2. Version Your API Specification

Maintain your OpenAPI/AsyncAPI specification in version control alongside your API code. This ensures the documentation stays in sync with the implementation.

# Recommended project structure
api/
  openapi.yaml          # OpenAPI specification
  asyncapi.yaml         # AsyncAPI specification (if applicable)
  schemas/
    brand.json          # Shared JSON Schema definitions
    visibility.json
  examples/
    create-brand.json   # Request/response examples
    visibility-report.json
  docs/
    getting-started.md  # Human-readable guides
    authentication.md
    rate-limits.md

3. Include Realistic Examples

AI engines use example values to understand your data model. Always provide realistic examples at both the schema level and the operation level.

# BAD: Placeholder examples
example:
  id: "string"
  name: "string"
  score: 0

# GOOD: Realistic examples that demonstrate actual use
example:
  id: "brand_abc123"
  name: "Acme Corp"
  score: 72.4

4. Use Tags to Organize Endpoints

Tags group related endpoints. Documentation tools use tags to create navigation sections. AI engines use tags to understand the functional areas of your API.

5. Document Error Responses Completely

Every endpoint should document its error responses, not just the success path. AI engines describing your API will include error handling information in their recommendations.

6. Keep Specifications Valid

Use linting tools to catch specification errors before publishing:

# Lint OpenAPI specification
npx @redocly/cli lint openapi.yaml

# Validate AsyncAPI specification
npx @asyncapi/cli validate asyncapi.yaml

# Validate JSON Schema
npx ajv validate -s schema.json -d data.json

API Documentation and AI Visibility

Well-structured API documentation directly affects how AI engines describe and recommend your product. When a developer asks an AI engine "What APIs are available for tracking brand visibility?", the AI draws on parsed API documentation to construct its answer.

Here is how structured API docs contribute to discoverability:

Platforms like 42A have observed that products with comprehensive, publicly accessible API documentation tend to receive more detailed and accurate descriptions in AI-generated technical recommendations. This is because the structured nature of OpenAPI and AsyncAPI specifications gives AI engines precise, parseable data about your product's capabilities.

Important: Do not expose internal or private API documentation publicly if it contains sensitive information. Only publish documentation for your public-facing APIs. Internal APIs should be documented privately within your organization.

Frequently Asked Questions

What is the difference between OpenAPI and Swagger?

Swagger was the original name of the API specification format. In 2015, the specification was donated to the OpenAPI Initiative (part of the Linux Foundation) and renamed to OpenAPI Specification. Swagger now refers to the tooling ecosystem (Swagger UI, Swagger Editor, Swagger Codegen) built around the OpenAPI Specification. OpenAPI 3.0+ is the current standard; Swagger 2.0 is the legacy version.

When should I use AsyncAPI instead of OpenAPI?

Use AsyncAPI for event-driven APIs that use message brokers (Kafka, RabbitMQ, MQTT, WebSockets, Server-Sent Events). Use OpenAPI for synchronous REST APIs with request-response patterns. If your system uses both patterns, maintain both specifications for complete documentation coverage.

Does API documentation affect AI search visibility?

Yes. Well-structured API documentation using OpenAPI or AsyncAPI specifications is machine-readable by design. AI engines can parse these specifications to understand your product's capabilities, which influences how your product is described in AI-generated technical comparisons and recommendations.

Next Steps

Start with an OpenAPI specification for your primary API. Use a linting tool to validate it. Generate interactive documentation with Swagger UI or Redocly. If you have event-driven components, add an AsyncAPI specification for those.

Combine your API documentation with Organization schema and Product schema on your marketing site. This creates a complete picture: your marketing pages tell AI engines what your product does, and your API documentation tells them exactly how it works.

For measuring how your documentation affects AI visibility, see our tools guide for tracking and measurement platforms.