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
// .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
<!-- .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:
Name | Type | Required | Description |
---|---|---|---|
id | string | Yes | User ID |
Example Request:
curl -X GET \
https://api.example.com/users/123 \
-H "Authorization: Bearer YOUR_TOKEN"
const response = await fetch('https://api.example.com/users/123', {
headers: {
'Authorization': 'Bearer YOUR_TOKEN'
}
});
const user = await response.json();
import requests
response = requests.get(
'https://api.example.com/users/123',
headers={'Authorization': 'Bearer YOUR_TOKEN'}
)
user = response.json()
Example Response:
{
"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:
Name | Type | Required | Description |
---|---|---|---|
name | string | Yes | User full name |
string | Yes | User email address | |
password | string | Yes | User password (min 8 chars) |
Example Request:
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"
}'
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();
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:
{
"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
- Register your application to get API credentials
- Obtain an access token using your credentials
- 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
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
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:
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
{
"error": "rate_limit_exceeded",
"message": "Rate limit exceeded. Try again in 3600 seconds.",
"retry_after": 3600
}
Error Handling
HTTP Status Codes
Code | Description |
---|---|
200 | OK - Request successful |
201 | Created - Resource created successfully |
400 | Bad Request - Invalid request parameters |
401 | Unauthorized - Authentication required |
403 | Forbidden - Insufficient permissions |
404 | Not Found - Resource not found |
429 | Too Many Requests - Rate limit exceeded |
500 | Internal Server Error - Server error |
Error Response Format
{
"error": {
"code": "validation_error",
"message": "The request contains invalid parameters",
"details": [
{
"field": "email",
"message": "Email address is required"
}
]
}
}
Common Errors
Authentication Errors
{
"error": {
"code": "unauthorized",
"message": "Invalid or expired access token"
}
}
Validation Errors
{
"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
{
"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:
<!-- .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
- Component Library - Document component APIs
- Blog Setup - Create blog with VitePress
- Documentation Site - Build documentation sites
This guide provides a comprehensive foundation for creating API documentation with VitePress. Customize the components and structure to match your specific API requirements.