API Documentation Generator

Build, preview, and export clean API docs

API

🫧 Add Endpoint

πŸ“‹ Endpoints

All GET POST PUT DELETE

No endpoints yet. Add one above or load a sample template.

πŸ“„ Generated Documentation

Add endpoints to generate documentation…

⚑ Quick Actions

`; } function downloadFile(name, content, mime) { const blob = new Blob([content], { type: mime }); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = name; a.click(); URL.revokeObjectURL(a.href); } // ── JSON Import/Export ── function exportJSON() { if (endpoints.length === 0) return showToast('No endpoints to export'); downloadFile('api-endpoints.json', JSON.stringify(endpoints, null, 2), 'application/json'); showToast('Exported JSON'); } function importJSON() { document.getElementById('fileInput').click(); } document.getElementById('fileInput').addEventListener('change', e => { const file = e.target.files[0]; if (!file) return; const reader = new FileReader(); reader.onload = ev => { try { const data = JSON.parse(ev.target.result); if (!Array.isArray(data)) throw new Error('Expected array'); endpoints = data.map(ep => ({ ...ep, id: ep.id || Date.now() + Math.random() })); renderAll(); showToast(`Imported ${endpoints.length} endpoints`); } catch { showToast('Invalid JSON file'); } }; reader.readAsText(file); e.target.value = ''; }); // ── Sample Template ── function loadSampleTemplate() { endpoints = [ { id: 1, method: 'GET', path: '/api/v1/users', description: 'Retrieve a paginated list of users', headers: { 'Authorization': 'Bearer ' }, reqBody: null, resBody: { success: true, data: [{ id: 1, name: 'Alice', email: 'alice@example.com' }], total: 42, page: 1 } }, { id: 2, method: 'GET', path: '/api/v1/users/:id', description: 'Get details of a specific user by ID', headers: { 'Authorization': 'Bearer ' }, reqBody: null, resBody: { success: true, data: { id: 1, name: 'Alice', email: 'alice@example.com', role: 'admin', createdAt: '2025-01-15T10:30:00Z' } } }, { id: 3, method: 'POST', path: '/api/v1/users', description: 'Create a new user account', headers: { 'Authorization': 'Bearer ', 'Content-Type': 'application/json' }, reqBody: { name: 'string (required)', email: 'string (required)', password: 'string (min 8 chars)', role: 'string (optional, default: "member")' }, resBody: { success: true, data: { id: 2, name: 'Bob', email: 'bob@example.com', role: 'member' }, message: 'User created successfully' } }, { id: 4, method: 'PUT', path: '/api/v1/users/:id', description: 'Update an existing user\'s profile', headers: { 'Authorization': 'Bearer ', 'Content-Type': 'application/json' }, reqBody: { name: 'string (optional)', email: 'string (optional)', role: 'string (optional)' }, resBody: { success: true, data: { id: 1, name: 'Alice Updated', email: 'alice.new@example.com', role: 'admin' }, message: 'User updated' } }, { id: 5, method: 'DELETE', path: '/api/v1/users/:id', description: 'Permanently delete a user account', headers: { 'Authorization': 'Bearer ' }, reqBody: null, resBody: { success: true, message: 'User deleted successfully' } }, { id: 6, method: 'POST', path: '/api/v1/auth/login', description: 'Authenticate and receive an access token', headers: { 'Content-Type': 'application/json' }, reqBody: { email: 'string (required)', password: 'string (required)' }, resBody: { success: true, data: { token: 'eyJhbGciOiJIUzI1NiIs…', expiresIn: 3600, user: { id: 1, name: 'Alice' } } } }, { id: 7, method: 'GET', path: '/api/v1/products', description: 'List all products with optional filtering', headers: { 'Authorization': 'Bearer ' }, reqBody: null, resBody: { success: true, data: [{ id: 101, name: 'Widget Pro', price: 29.99, category: 'electronics' }], total: 128 } } ]; renderAll(); showToast('Loaded sample template with 7 endpoints'); } // ── Clear All ── function confirmClearAll() { if (endpoints.length === 0) return showToast('Nothing to clear'); showModal('Clear All Endpoints', `This will remove all ${endpoints.length} endpoint(s). This cannot be undone.`, () => { endpoints = []; renderAll(); showToast('All endpoints cleared'); }); } // ── Modal ── function showModal(title, message, onConfirm) { document.getElementById('modalTitle').textContent = title; document.getElementById('modalMessage').textContent = message; const btn = document.getElementById('modalConfirmBtn'); btn.onclick = () => { closeModal(); onConfirm(); }; document.getElementById('confirmModal').classList.add('open'); } function closeModal() { document.getElementById('confirmModal').classList.remove('open'); } // ── Toast ── function showToast(msg) { const t = document.getElementById('toast'); t.textContent = msg; t.classList.add('show'); clearTimeout(t._timer); t._timer = setTimeout(() => t.classList.remove('show'), 2400); } // ── Utility ── function escapeHTML(str) { const d = document.createElement('div'); d.textContent = str; return d.innerHTML; } // ── Init ── renderAll();