technical-writing 7 min read

Writing API Documentation That Screen Readers Love

A journalist's approach to creating accessible API documentation that actually helps developers build inclusive applications

Illustration of API documentation with a code example showing GET /api/users endpoint, featuring accessibility indicators for screen reader compatibility and WCAG AA compliance

Writing API Documentation That Screen Readers Love

How journalism training taught me to write API docs that work for everyone

The Problem Every API Team Faces

Your REST API passes all automated accessibility tests. Your frontend is WCAG 2.1 AA compliant. But when developers try to build accessible applications using your API, they struggle. Why?

Your API documentation isn’t accessible.

I discovered this the hard way while implementing Smart Accessibility Guardrails across multiple platforms. Teams would build beautifully accessible frontends, only to hit walls when they needed to understand error responses, authentication flows, or data structures that impact screen reader users.

The Journalism Approach to API Documentation

My journalism degree taught me that every piece of writing should answer: Who, What, When, Where, Why, and How. Applied to API documentation, this means:

Who: Define Your Audience’s Accessibility Needs

❌ Bad: "Returns user data" ✅ Good: "Returns user profile including
accessibility preferences for screen reader compatibility and high contrast
settings"

Why this matters: Developers need to know which fields affect assistive technology users.

What: Describe Accessibility Impact Clearly

// ❌ Unclear accessibility impact
{
  "status": "error",
  "code": 400,
  "message": "Invalid input"
}

// ✅ Clear accessibility guidance
{
  "status": "error",
  "code": 400,
  "message": "Email address format is invalid",
  "accessibility": {
    "announce": "Email validation error. Please check the email format.",
    "focus_target": "email_input",
    "severity": "error"
  }
}

When: Timing Matters for Accessibility

Document when accessibility-related API calls should happen:

## Authentication Flow for Assistive Technology

1. **Before page load**: Call `/api/user/preferences` to get accessibility
   settings
2. **During login**: Include `accessibility_preferences: true` in request
3. **After successful auth**: Cache accessibility settings for offline use
4. **On settings change**: Immediately call `/api/user/accessibility` to update

Where: Location Context for Inclusive Design

# OpenAPI specification with accessibility context
paths:
  /api/announcements:
    get:
      summary: 'Get system announcements for screen readers'
      description: |
        Retrieves announcements that should be immediately communicated 
        to screen reader users. Announcements marked as 'urgent' should 
        trigger assertive ARIA live regions.
      parameters:
        - name: priority
          in: query
          description: 'Filter by announcement priority for ARIA live regions'
          schema:
            type: string
            enum: ['polite', 'assertive', 'off']

Why: Explain Accessibility Decisions

Don’t just document what the API does—explain why it matters for accessibility:

## Error Response Format

Our error responses follow this structure to support screen readers:

```json
{
  "error": {
    "code": "VALIDATION_FAILED",
    "message": "The email field contains an invalid email address",
    "field": "email",
    "user_message": "Please enter a valid email address like user@example.com"
  }
}
```

Why this structure?

  • message: Technical description for developers
  • user_message: Screen reader-friendly text for end users
  • field: Enables programmatic focus management

### How: Provide Working Examples

Every accessibility feature needs a complete, testable example:

```javascript
// Example: Implementing accessible form validation with our API
async function validateAccessibly(formData) {
  try {
    const response = await fetch('/api/validate', {
      method: 'POST',
      body: JSON.stringify(formData),
      headers: {
        'Content-Type': 'application/json',
        'Accept': 'application/json'
      }
    });

    const result = await response.json();

    if (!response.ok) {
      // Focus management for screen readers
      if (result.error?.field) {
        const errorField = document.getElementById(result.error.field);
        if (errorField) {
          errorField.focus();
          errorField.setAttribute('aria-invalid', 'true');
        }
      }

      // Announce error to screen readers
      if (result.accessibility?.announce) {
        announceToScreenReader(result.accessibility.announce);
      } else if (result.error?.message) {
        announceToScreenReader(result.error.message);
      }
    }

    return result;
  } catch (error) {
    announceToScreenReader('A network error occurred. Please try again.');
    throw error;
  }
}

function announceToScreenReader(message) {
  const announcement = document.createElement('div');
  announcement.setAttribute('aria-live', 'assertive');
  announcement.setAttribute('aria-atomic', 'true');
  announcement.textContent = message;
  announcement.style.position = 'absolute';
  announcement.style.left = '-10000px';
  document.body.appendChild(announcement);

  setTimeout(() => {
    if (document.body.contains(announcement)) {
      document.body.removeChild(announcement);
    }
  }, 1000);
}

The Smart Accessibility Guardrails Approach to API Docs

Here’s how I integrate accessibility documentation into API development:

1. Accessibility-First OpenAPI Specifications

components:
  schemas:
    StandardError:
      type: object
      required: [code, message]
      properties:
        code:
          type: string
          description: 'Machine-readable error code'
        message:
          type: string
          description: 'Human-readable error description'
        field:
          type: string
          description:
            'Field name that caused the error (for validation errors)'

    AccessibleErrorResponse:
      type: object
      required: [error, accessibility]
      properties:
        error:
          $ref: '#/components/schemas/StandardError'
        accessibility:
          type: object
          properties:
            announce:
              type: string
              description: 'Screen reader announcement text'
            severity:
              type: string
              enum: ['info', 'warning', 'error']
              description: 'ARIA live region priority'
            focus_target:
              type: string
              description: 'Element ID to focus after error'

2. Automated Accessibility Documentation Testing

// Test that ensures API docs include accessibility guidance
describe('API Documentation Accessibility', () => {
  test('all error responses include accessibility fields', async () => {
    // Load your OpenAPI specification
    const fs = require('fs');
    const yaml = require('js-yaml');
    const apiSpec = yaml.load(fs.readFileSync('./api-spec.yaml', 'utf8'));

    Object.values(apiSpec.paths).forEach(pathSpec => {
      Object.values(pathSpec).forEach(operation => {
        const errorResponses = Object.keys(operation.responses).filter(
          code => code.startsWith('4') || code.startsWith('5')
        );

        errorResponses.forEach(errorCode => {
          const response = operation.responses[errorCode];
          const schema = response.content?.['application/json']?.schema;

          // Check if error responses include accessibility guidance
          expect(schema?.properties).toHaveProperty('accessibility');
        });
      });
    });
  });
});

3. Living Documentation with Real Examples

Create documentation that stays current:

## Real Implementation Examples

### Video Streaming API Integration

Here's how to implement screen reader announcements for video playback status:

```javascript
// Video status updates with accessibility support
const updateVideoStatus = async (videoId, status) => {
  try {
    const response = await fetch(`/api/videos/${videoId}/status`, {
      method: 'PATCH',
      body: JSON.stringify({ status }),
      headers: {
        'Content-Type': 'application/json',
        Accept: 'application/json',
      },
    });

    const result = await response.json();

    // Use API-provided accessibility text if available
    if (result.accessibility?.announce) {
      announceToScreenReader(result.accessibility.announce);
    } else {
      // Fallback to generating announcement from status
      const statusMessages = {
        playing: 'Video is now playing',
        paused: 'Video is paused',
        stopped: 'Video has stopped',
        ended: 'Video has ended',
      };
      announceToScreenReader(
        statusMessages[status] || `Video status: ${status}`
      );
    }

    return result;
  } catch (error) {
    announceToScreenReader('Unable to update video status');
    throw error;
  }
};
```

📋 Implementation Status: Example code pattern - adapt to your specific API 🔧 Screen Reader Testing: Recommended with NVDA (free), JAWS, or VoiceOver (built into Mac) � Documentation: Include accessibility guidance in your OpenAPI specs


## The Business Case for Accessible API Documentation

From my research on accessibility implementation across development teams:

- **Increased awareness** of accessibility best practices among developers
- **Faster integration** times for teams building accessible applications
- **Higher developer satisfaction** with clear, actionable documentation
- **Legal compliance** for APIs used in government or educational applications

## Action Items for Your API Team

1. **Audit your current API docs** for accessibility guidance
2. **Add accessibility fields** to error response schemas
3. **Include screen reader examples** in all integration guides
4. **Test with screen readers**: Start with VoiceOver (Mac users) or NVDA (free for Windows)
5. **Automate accessibility doc validation** in your CI/CD pipeline

## Getting Started with Screen Reader Testing

**For Mac users**: VoiceOver is already installed! Press `Cmd + F5` to turn it on and test your documentation.

**For Windows users**: Download [NVDA](https://www.nvaccess.org/) (free) to test how screen readers interact with your API documentation.

**Testing tip**: Navigate your API docs using only the keyboard and screen reader. If it's confusing for you, it will be confusing for users with visual impairments.

## What's Next?

This is part of my larger "Smart Accessibility Guardrails" methodology that I'm applying across cloud infrastructure, mobile applications, and DevOps pipelines. Next week, I'll share how to implement accessibility testing in Azure DevOps pipelines.

**Questions?** I'd love to hear how you're making your API documentation more accessible. Connect with me on [LinkedIn](https://linkedin.com/in/rubyjane/) or share your experiences in the comments.

---

*Ruby Jane Cabagnot is a Cloud Accessibility Engineer, author of "Practical Enterprise React," and international speaker who combines journalism training with technical expertise to create accessible, understandable documentation. She's currently pursuing a Master's in Cloud Engineering at OsloMet.*
RC

Ruby Jane Cabagnot

Accessibility Cloud Engineer

Building inclusive digital experiences through automated testing and AI-powered accessibility tools. Passionate about making the web accessible for everyone.

Related Topics:

#accessibility #technical-writing #api-documentation #wcag #inclusive-design