Skip to content

API Documentation

Learn how to create comprehensive API documentation using VitePress with interactive examples and clear structure.

Overview

API documentation is essential for:

  • REST APIs
  • GraphQL APIs
  • SDK documentation
  • Library references
  • Service integrations

Key Features

📋 Structured Content

  • Endpoint organization
  • Request/response examples
  • Parameter documentation
  • Error handling guides

🔧 Interactive Elements

  • Code examples
  • Try-it-out functionality
  • Response previews
  • Authentication flows

🎯 Developer-Friendly

  • Search functionality
  • Copy-to-clipboard
  • Multiple language examples
  • Versioning support

Project Structure

docs/
├── .vitepress/
│   ├── config.js
│   └── theme/
│       └── components/
│           ├── ApiEndpoint.vue
│           ├── CodeBlock.vue
│           └── TryItOut.vue
├── api/
│   ├── index.md
│   ├── authentication.md
│   ├── endpoints/
│   │   ├── users.md
│   │   ├── posts.md
│   │   └── comments.md
│   ├── errors.md
│   └── changelog.md
└── index.md

Configuration

js
// .vitepress/config.js
export default {
  title: 'API Documentation',
  description: 'Comprehensive API reference and guides',
  
  themeConfig: {
    nav: [
      { text: 'Guide', link: '/guide/' },
      { text: 'API Reference', link: '/api/' },
      { text: 'Examples', link: '/examples/' }
    ],
    
    sidebar: {
      '/api/': [
        {
          text: 'Getting Started',
          items: [
            { text: 'Introduction', link: '/api/' },
            { text: 'Authentication', link: '/api/authentication' },
            { text: 'Rate Limiting', link: '/api/rate-limiting' }
          ]
        },
        {
          text: 'Endpoints',
          items: [
            { text: 'Users', link: '/api/endpoints/users' },
            { text: 'Posts', link: '/api/endpoints/posts' },
            { text: 'Comments', link: '/api/endpoints/comments' }
          ]
        },
        {
          text: 'Reference',
          items: [
            { text: 'Error Codes', link: '/api/errors' },
            { text: 'Changelog', link: '/api/changelog' }
          ]
        }
      ]
    },
    
    search: {
      provider: 'local'
    }
  }
}

API Endpoint Component

vue
<!-- .vitepress/theme/components/ApiEndpoint.vue -->
<template>
  <div class="api-endpoint">
    <div class="endpoint-header">
      <span :class="['method', method.toLowerCase()]">{{ method }}</span>
      <code class="endpoint-url">{{ url }}</code>
    </div>
    
    <div class="endpoint-description">
      <slot name="description"></slot>
    </div>
    
    <div v-if="parameters" class="parameters">
      <h4>Parameters</h4>
      <div class="parameter-table">
        <div 
          v-for="param in parameters" 
          :key="param.name"
          class="parameter-row"
        >
          <div class="param-name">
            <code>{{ param.name }}</code>
            <span v-if="param.required" class="required">*</span>
          </div>
          <div class="param-type">{{ param.type }}</div>
          <div class="param-description">{{ param.description }}</div>
        </div>
      </div>
    </div>
    
    <div class="code-examples">
      <div class="example-tabs">
        <button 
          v-for="lang in languages" 
          :key="lang"
          :class="{ active: activeTab === lang }"
          @click="activeTab = lang"
        >
          {{ lang }}
        </button>
      </div>
      
      <div class="example-content">
        <slot :name="activeTab"></slot>
      </div>
    </div>
    
    <div v-if="response" class="response-example">
      <h4>Response</h4>
      <pre><code>{{ JSON.stringify(response, null, 2) }}</code></pre>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({
  method: String,
  url: String,
  parameters: Array,
  response: Object,
  languages: {
    type: Array,
    default: () => ['curl', 'javascript', 'python']
  }
})

const activeTab = ref(props.languages[0])
</script>

<style scoped>
.api-endpoint {
  border: 1px solid var(--vp-c-divider);
  border-radius: 8px;
  margin: 2rem 0;
  overflow: hidden;
}

.endpoint-header {
  background: var(--vp-c-bg-soft);
  padding: 1rem;
  display: flex;
  align-items: center;
  gap: 1rem;
}

.method {
  padding: 0.25rem 0.5rem;
  border-radius: 4px;
  font-weight: bold;
  font-size: 0.8rem;
  text-transform: uppercase;
}

.method.get { background: #10b981; color: white; }
.method.post { background: #3b82f6; color: white; }
.method.put { background: #f59e0b; color: white; }
.method.delete { background: #ef4444; color: white; }

.endpoint-url {
  font-family: var(--vp-font-family-mono);
  font-size: 1.1rem;
}

.endpoint-description {
  padding: 1rem;
  border-bottom: 1px solid var(--vp-c-divider);
}

.parameters {
  padding: 1rem;
  border-bottom: 1px solid var(--vp-c-divider);
}

.parameter-table {
  display: grid;
  gap: 0.5rem;
}

.parameter-row {
  display: grid;
  grid-template-columns: 1fr 100px 2fr;
  gap: 1rem;
  padding: 0.5rem;
  background: var(--vp-c-bg-soft);
  border-radius: 4px;
}

.param-name code {
  font-weight: bold;
}

.required {
  color: var(--vp-c-danger);
  margin-left: 0.25rem;
}

.param-type {
  color: var(--vp-c-text-2);
  font-family: var(--vp-font-family-mono);
  font-size: 0.9rem;
}

.code-examples {
  border-bottom: 1px solid var(--vp-c-divider);
}

.example-tabs {
  display: flex;
  background: var(--vp-c-bg-soft);
}

.example-tabs button {
  padding: 0.5rem 1rem;
  border: none;
  background: transparent;
  cursor: pointer;
  border-bottom: 2px solid transparent;
}

.example-tabs button.active {
  border-bottom-color: var(--vp-c-brand);
  color: var(--vp-c-brand);
}

.example-content {
  padding: 1rem;
}

.response-example {
  padding: 1rem;
}

.response-example pre {
  background: var(--vp-c-bg-soft);
  padding: 1rem;
  border-radius: 4px;
  overflow-x: auto;
}
</style>

API Documentation Examples

Get User Endpoint

Method: GET
URL: /api/users/{id}

Description: Retrieve a specific user by their ID.

Parameters:

NameTypeRequiredDescription
idstringYesUser ID

Example Request:

bash
curl -X GET \
  https://api.example.com/users/123 \
  -H "Authorization: Bearer YOUR_TOKEN"
javascript
const response = await fetch('https://api.example.com/users/123', {
  headers: {
    'Authorization': 'Bearer YOUR_TOKEN'
  }
});
const user = await response.json();
python
import requests

response = requests.get(
    'https://api.example.com/users/123',
    headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
user = response.json()

Example Response:

json
{
  "id": "123",
  "name": "John Doe",
  "email": "john@example.com",
  "created_at": "2024-01-01T00:00:00Z"
}

Create User Endpoint

Method: POST
URL: /api/users

Description: Create a new user account.

Parameters:

NameTypeRequiredDescription
namestringYesUser full name
emailstringYesUser email address
passwordstringYesUser password (min 8 chars)

Example Request:

bash
curl -X POST \
  https://api.example.com/users \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer YOUR_TOKEN" \
  -d '{
    "name": "Jane Smith",
    "email": "jane@example.com",
    "password": "securepassword"
  }'
javascript
const response = await fetch('https://api.example.com/users', {
  method: 'POST',
  headers: {
    'Content-Type': 'application/json',
    'Authorization': 'Bearer YOUR_TOKEN'
  },
  body: JSON.stringify({
    name: 'Jane Smith',
    email: 'jane@example.com',
    password: 'securepassword'
  })
});
const user = await response.json();
python
import requests

response = requests.post(
    'https://api.example.com/users',
    headers={
        'Content-Type': 'application/json',
        'Authorization': 'Bearer YOUR_TOKEN'
    },
    json={
        'name': 'Jane Smith',
        'email': 'jane@example.com',
        'password': 'securepassword'
    }
)
user = response.json()

Example Response:

json
{
  "id": "124",
  "name": "Jane Smith",
  "email": "jane@example.com",
  "created_at": "2024-01-02T00:00:00Z"
}

Authentication Guide

Overview

Our API uses Bearer token authentication for secure access to resources.

Getting Started

  1. Register your application to get API credentials
  2. Obtain an access token using your credentials
  3. Include the token in your API requests

OAuth 2.0 Flow

Step 1: Authorization Request

GET https://api.example.com/oauth/authorize?
  response_type=code&
  client_id=YOUR_CLIENT_ID&
  redirect_uri=YOUR_REDIRECT_URI&
  scope=read write

Step 2: Exchange Code for Token

bash
curl -X POST https://api.example.com/oauth/token \
  -H "Content-Type: application/x-www-form-urlencoded" \
  -d "grant_type=authorization_code" \
  -d "code=AUTHORIZATION_CODE" \
  -d "client_id=YOUR_CLIENT_ID" \
  -d "client_secret=YOUR_CLIENT_SECRET"

Step 3: Use Access Token

bash
curl -X GET https://api.example.com/users/me \
  -H "Authorization: Bearer ACCESS_TOKEN"

API Keys

For server-to-server communication, you can use API keys:

bash
curl -X GET https://api.example.com/users \
  -H "X-API-Key: YOUR_API_KEY"

Rate Limiting

  • Rate Limit: 1000 requests per hour
  • Headers: Check X-RateLimit-* headers in responses
  • Status Code: 429 when limit exceeded
json
{
  "error": "rate_limit_exceeded",
  "message": "Rate limit exceeded. Try again in 3600 seconds.",
  "retry_after": 3600
}

Error Handling

HTTP Status Codes

CodeDescription
200OK - Request successful
201Created - Resource created successfully
400Bad Request - Invalid request parameters
401Unauthorized - Authentication required
403Forbidden - Insufficient permissions
404Not Found - Resource not found
429Too Many Requests - Rate limit exceeded
500Internal Server Error - Server error

Error Response Format

json
{
  "error": {
    "code": "validation_error",
    "message": "The request contains invalid parameters",
    "details": [
      {
        "field": "email",
        "message": "Email address is required"
      }
    ]
  }
}

Common Errors

Authentication Errors

json
{
  "error": {
    "code": "unauthorized",
    "message": "Invalid or expired access token"
  }
}

Validation Errors

json
{
  "error": {
    "code": "validation_error",
    "message": "Validation failed",
    "details": [
      {
        "field": "name",
        "message": "Name is required"
      },
      {
        "field": "email",
        "message": "Email must be a valid email address"
      }
    ]
  }
}

Rate Limit Errors

json
{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Too many requests",
    "retry_after": 3600
  }
}

Interactive Features

Try It Out Component

For interactive API testing, you can create a custom Vue component:

vue
<!-- .vitepress/theme/components/TryItOut.vue -->
<template>
  <div class="try-it-out">
    <h4>Try it out</h4>
    
    <div class="form-group">
      <label>Base URL:</label>
      <input v-model="baseUrl" type="text" />
    </div>
    
    <div class="form-group">
      <label>Authorization:</label>
      <input v-model="token" type="text" placeholder="Bearer token" />
    </div>
    
    <div class="form-group" v-if="method === 'POST'">
      <label>Request Body:</label>
      <textarea v-model="requestBody" rows="6"></textarea>
    </div>
    
    <button @click="makeRequest" :disabled="loading">
      {{ loading ? 'Sending...' : 'Send Request' }}
    </button>
    
    <div v-if="response" class="response">
      <h5>Response:</h5>
      <pre><code>{{ response }}</code></pre>
    </div>
  </div>
</template>

<script setup>
import { ref } from 'vue'

const props = defineProps({
  method: String,
  endpoint: String
})

const baseUrl = ref('https://api.example.com')
const token = ref('')
const requestBody = ref('{}')
const response = ref('')
const loading = ref(false)

const makeRequest = async () => {
  loading.value = true
  
  try {
    const options = {
      method: props.method,
      headers: {
        'Content-Type': 'application/json'
      }
    }
    
    if (token.value) {
      options.headers.Authorization = `Bearer ${token.value}`
    }
    
    if (props.method === 'POST' && requestBody.value) {
      options.body = requestBody.value
    }
    
    const res = await fetch(`${baseUrl.value}${props.endpoint}`, options)
    const data = await res.json()
    
    response.value = JSON.stringify(data, null, 2)
  } catch (error) {
    response.value = `Error: ${error.message}`
  } finally {
    loading.value = false
  }
}
</script>

<style scoped>
.try-it-out {
  background: var(--vp-c-bg-soft);
  padding: 1rem;
  border-radius: 8px;
  margin: 1rem 0;
}

.form-group {
  margin-bottom: 1rem;
}

.form-group label {
  display: block;
  margin-bottom: 0.5rem;
  font-weight: bold;
}

.form-group input,
.form-group textarea {
  width: 100%;
  padding: 0.5rem;
  border: 1px solid var(--vp-c-divider);
  border-radius: 4px;
  font-family: var(--vp-font-family-mono);
}

button {
  background: var(--vp-c-brand);
  color: white;
  border: none;
  padding: 0.5rem 1rem;
  border-radius: 4px;
  cursor: pointer;
}

button:disabled {
  opacity: 0.5;
  cursor: not-allowed;
}

.response {
  margin-top: 1rem;
  padding-top: 1rem;
  border-top: 1px solid var(--vp-c-divider);
}

.response pre {
  background: var(--vp-c-bg);
  padding: 1rem;
  border-radius: 4px;
  overflow-x: auto;
}
</style>

Best Practices

Documentation Structure

  • Start with authentication and getting started
  • Group related endpoints together
  • Include comprehensive examples
  • Document error scenarios
  • Provide SDKs and libraries

Code Examples

  • Show examples in multiple languages
  • Include complete, runnable code
  • Use realistic data in examples
  • Explain complex parameters
  • Show both success and error responses

Interactive Elements

  • Provide "try it out" functionality
  • Include copy-to-clipboard buttons
  • Show live response examples
  • Allow parameter customization
  • Support different environments

Live Examples

Next Steps


This guide provides a comprehensive foundation for creating API documentation with VitePress. Customize the components and structure to match your specific API requirements.

VitePress Development Guide