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