.params-table td{padding:8px;border-bottom:1px solid var(--border)} .params-table .required{color:var(--danger);font-weight:600} .params-table .optional{color:var(--muted)} .json-block{background:var(--bg);border:1px solid var(--border);border-radius:8px;padding:12px;font-family:'SF Mono',Monaco,Consolas,monospace;font-size:13px;overflow-x:auto;line-height:1.5;white-space:pre;margin:8px 0} .json-block .key{color:var(--accent)} .json-block .string{color:var(--success)} .json-block .number{color:var(--warning)} .json-block .bool{color:var(--accent2)} .json-block .null{color:var(--muted)} .status-table{width:100%;border-collapse:collapse;font-size:13px;margin:10px 0} .status-table th{text-align:left;padding:8px;color:var(--muted);border-bottom:1px solid var(--border)} .status-table td{padding:8px;border-bottom:1px solid var(--border)} .status-code{font-weight:700;font-family:monospace} .status-2xx{color:var(--success)} .status-4xx{color:var(--warning)} .status-5xx{color:var(--danger)} .toc{margin-bottom:20px} .toc h3{font-size:14px;color:var(--muted);margin-bottom:8px;text-transform:uppercase;letter-spacing:1px} .toc a{display:block;padding:6px 12px;color:var(--text);font-size:13px;border-radius:6px;transition:all .2s;border-left:2px solid transparent} .toc a:hover{background:var(--glow);border-left-color:var(--accent);color:var(--accent)} .export-bar{display:flex;gap:8px;flex-wrap:wrap;margin:16px 0} .manual-form .field-group{margin-bottom:12px} .manual-form .param-row{display:grid;grid-template-columns:1fr 100px 80px 1fr 40px;gap:8px;align-items:end;margin-bottom:8px} .manual-form .param-row input,.manual-form .param-row select{padding:8px} .endpoints-list{margin:12px 0} .endpoint-item{display:flex;align-items:center;justify-content:space-between;padding:10px 12px;background:var(--surface);border:1px solid var(--border);border-radius:8px;margin-bottom:6px;cursor:pointer;transition:all .2s} .endpoint-item:hover{border-color:var(--border-hover)} .endpoint-item.active{border-color:var(--accent);background:var(--glow)} .pro-section{margin:32px 0;text-align:center} .pro-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(200px,1fr));gap:12px;margin:16px 0} .pro-card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:20px;text-align:center;position:relative;opacity:0.7} .pro-card .lock{position:absolute;top:12px;right:12px;font-size:18px} .pro-card h4{margin:8px 0 4px;font-size:15px} .pro-card p{font-size:13px;color:var(--muted)} .template-grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(250px,1fr));gap:12px;margin:16px 0} .template-card{background:var(--card);border:1px solid var(--border);border-radius:14px;padding:16px;cursor:pointer;transition:all .2s} .template-card:hover{border-color:var(--accent);transform:translateY(-2px)} .template-card h4{font-size:15px;margin-bottom:4px} .template-card p{font-size:13px;color:var(--muted)} .mobile-toggle{display:none;margin-bottom:12px} .section-title{font-size:18px;font-weight:700;margin-bottom:12px;color:var(--text)} .divider{height:1px;background:var(--border);margin:24px 0} footer{text-align:center;padding:32px 16px;color:var(--muted);font-size:13px;border-top:1px solid var(--border);margin-top:48px} footer a{color:var(--accent)} .preview-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:16px;padding-bottom:12px;border-bottom:1px solid var(--border)} .preview-header h2{font-size:20px} .api-version{font-size:12px;padding:3px 8px;background:var(--glow);color:var(--accent);border-radius:4px} .api-base-url{font-family:monospace;font-size:13px;color:var(--accent2);background:var(--bg);padding:6px 12px;border-radius:6px;display:inline-block;margin:8px 0} .empty-state{text-align:center;padding:60px 20px;color:var(--muted)} .empty-state .icon{font-size:48px;margin-bottom:12px} .empty-state p{font-size:14px} @media(max-width:768px){ .workspace{grid-template-columns:1fr} .api-info-grid{grid-template-columns:1fr} .manual-form .param-row{grid-template-columns:1fr 1fr;gap:6px} .mobile-toggle{display:flex} .preview-panel.mobile-hidden{display:none} .editor-panel.mobile-hidden{display:none} nav{padding:0 12px} .nav-links{gap:8px} }

AI API Documentation Generator

Generate professional API documentation from code, cURL commands, JSON schemas, or manual input. Export as Markdown, HTML, or OpenAPI 3.0 YAML.

๐Ÿ“‹ API Information
๐Ÿ“ฆ Templates

๐Ÿ“ Blog REST API

CRUD endpoints for posts, comments, and users

๐Ÿ›’ E-Commerce API

Products, orders, cart, and payment endpoints

๐Ÿ“Œ Endpoints
Editor
Preview
From Code
From JSON Schema
From cURL
Manual
๐Ÿ“„

Your API documentation will appear here.
Parse code, paste a cURL command, or add endpoints manually.

๐Ÿ”’ Pro Features

Unlock advanced features to supercharge your API documentation workflow

๐Ÿ”’
๐Ÿ“ฅ

OpenAPI Import/Export

Import existing OpenAPI specs and export enhanced versions

๐Ÿ”’
๐Ÿ”

Authentication Docs

Document OAuth2, API keys, JWT, and custom auth flows

๐Ÿ”’
๐Ÿ’ป

SDK Code Samples

Auto-generate code samples in Python, JS, Go, and more

๐Ÿ”’
๐ŸŽจ

Custom Themes

Brand your docs with custom colors, logos, and layouts

๐Ÿ”’
๐Ÿ“„

PDF Export

Generate print-ready PDF documentation

โ˜• Unlock Pro Features โ€” Support on Ko-fi
๐Ÿ“„

Your API documentation will appear here.
Parse code, paste a schema, or add endpoints manually.

๐Ÿ”’ Pro Features

Unlock advanced features to supercharge your API documentation workflow

๐Ÿ”’
๐Ÿ“ฅ

OpenAPI Import/Export

Import existing OpenAPI specs and export enhanced versions

๐Ÿ”’
๐Ÿ”

Authentication Docs

Document OAuth2, API keys, JWT, and custom auth flows

๐Ÿ”’
๐Ÿ’ป

SDK Code Samples

Auto-generate code samples in Python, JS, Go, Ruby, and more

๐Ÿ”’
๐ŸŽจ

Custom Themes

Choose from 10+ themes or create your own branded docs

๐Ÿ”’
๐Ÿ“„

PDF Export

Export beautiful PDF documentation for offline sharing

โ˜• Unlock Pro Features โ€” Support on Ko-fi
'; downloadFile(title.replace(/\s+/g,'-').toLowerCase()+'-api-docs.html', html, 'text/html'); } function exportOpenAPI() { if(endpoints.length === 0) { alert('No endpoints to export.'); return; } const title = document.getElementById('apiTitle').value || 'My API'; const version = document.getElementById('apiVersion').value || '1.0.0'; const baseUrl = document.getElementById('apiBaseUrl').value || 'https://api.example.com'; const desc = document.getElementById('apiDesc').value || ''; let yaml = 'openapi: "3.0.3"\ninfo:\n title: "'+title+'"\n version: "'+version+'"\n'; if(desc) yaml += ' description: "'+desc+'"\n'; yaml += 'servers:\n - url: "'+baseUrl+'"\npaths:\n'; // Group by path const pathMap = {}; endpoints.forEach(ep => { const p = ep.path.replace(/:(\w+)/g, '{$1}'); if(!pathMap[p]) pathMap[p] = {}; pathMap[p][ep.method.toLowerCase()] = ep; }); Object.keys(pathMap).forEach(path => { yaml += ' "'+path+'":\n'; Object.keys(pathMap[path]).forEach(method => { const ep = pathMap[path][method]; yaml += ' '+method+':\n'; yaml += ' summary: "'+((ep.description||'').replace(/"/g,'\\"'))+'"\n'; yaml += ' operationId: "'+method+path.replace(/[^a-zA-Z0-9]/g,'_')+'"\n'; if(ep.params && ep.params.length) { yaml += ' parameters:\n'; ep.params.forEach(p => { const inType = ep.path.includes(':'+p.name) ? 'path' : 'query'; yaml += ' - name: "'+p.name+'"\n in: "'+inType+'"\n required: '+p.required+'\n schema:\n type: "'+mapType(p.type)+'"\n description: "'+(p.description||'')+'"\n'; }); } if(ep.requestBody) { yaml += ' requestBody:\n required: true\n content:\n application/json:\n schema:\n type: object\n'; try { const obj = JSON.parse(ep.requestBody); yaml += ' example:\n'; const lines = JSON.stringify(obj,null,2).split('\n'); lines.forEach(l => { yaml += ' '+l+'\n'; }); } catch(e){} } yaml += ' responses:\n'; if(ep.statusCodes && ep.statusCodes.length) { ep.statusCodes.forEach(s => { yaml += ' "'+s.code+'":\n description: "'+s.desc+'"\n'; if(s.code.startsWith('2') && ep.responseExample) { yaml += ' content:\n application/json:\n schema:\n type: object\n'; try { const obj = JSON.parse(ep.responseExample); yaml += ' example:\n'; JSON.stringify(obj,null,2).split('\n').forEach(l => { yaml += ' '+l+'\n'; }); } catch(e){} } }); } else { yaml += ' "200":\n description: "Success"\n'; } }); }); downloadFile(title.replace(/\s+/g,'-').toLowerCase()+'-openapi.yaml', yaml, 'text/yaml'); } function mapType(t) { t = (t||'string').toLowerCase(); if(t==='int'||t==='integer'||t==='number') return 'integer'; if(t==='bool'||t==='boolean') return 'boolean'; if(t==='float'||t==='double') return 'number'; if(t==='array') return 'array'; if(t==='object') return 'object'; return 'string'; } function downloadFile(name, content, type) { const blob = new Blob([content], {type}); const a = document.createElement('a'); a.href = URL.createObjectURL(blob); a.download = name; a.click(); URL.revokeObjectURL(a.href); } // --- Templates --- function loadTemplate(name) { endpoints = []; if(name === 'blog') { document.getElementById('apiTitle').value = 'Blog REST API'; document.getElementById('apiVersion').value = '2.0.0'; document.getElementById('apiBaseUrl').value = 'https://api.myblog.com/v2'; document.getElementById('apiDesc').value = 'RESTful API for managing blog posts, comments, and users.'; endpoints = [ {method:'GET',path:'/posts',description:'List all blog posts',params:[{name:'page',type:'integer',required:false,description:'Page number'},{name:'limit',type:'integer',required:false,description:'Items per page (default: 20)'},{name:'tag',type:'string',required:false,description:'Filter by tag'}],requestBody:null,responseExample:'[\n {\n "id": 1,\n "title": "Getting Started with REST APIs",\n "slug": "getting-started-rest-apis",\n "excerpt": "Learn the basics of RESTful API design...",\n "author": { "id": 1, "name": "Jane Doe" },\n "tags": ["api", "tutorial"],\n "created_at": "2026-01-15T10:30:00Z"\n }\n]',statusCodes:[{code:'200',desc:'Success'}]}, {method:'GET',path:'/posts/:id',description:'Get a single blog post',params:[{name:'id',type:'integer',required:true,description:'Post ID'}],requestBody:null,responseExample:'{\n "id": 1,\n "title": "Getting Started with REST APIs",\n "content": "Full markdown content here...",\n "author": { "id": 1, "name": "Jane Doe" },\n "tags": ["api", "tutorial"],\n "comments_count": 5,\n "created_at": "2026-01-15T10:30:00Z",\n "updated_at": "2026-01-16T08:00:00Z"\n}',statusCodes:[{code:'200',desc:'Success'},{code:'404',desc:'Post not found'}]}, {method:'POST',path:'/posts',description:'Create a new blog post',params:[],requestBody:'{\n "title": "My New Post",\n "content": "Post content in markdown...",\n "tags": ["javascript", "tutorial"],\n "published": true\n}',responseExample:'{\n "id": 2,\n "title": "My New Post",\n "slug": "my-new-post",\n "created_at": "2026-02-20T14:00:00Z"\n}',statusCodes:[{code:'201',desc:'Created'},{code:'400',desc:'Validation error'},{code:'401',desc:'Unauthorized'}]}, {method:'PUT',path:'/posts/:id',description:'Update a blog post',params:[{name:'id',type:'integer',required:true,description:'Post ID'}],requestBody:'{\n "title": "Updated Title",\n "content": "Updated content...",\n "tags": ["updated"],\n "published": false\n}',responseExample:'{\n "id": 1,\n "title": "Updated Title",\n "updated_at": "2026-02-21T09:00:00Z"\n}',statusCodes:[{code:'200',desc:'Updated'},{code:'404',desc:'Post not found'}]}, {method:'DELETE',path:'/posts/:id',description:'Delete a blog post',params:[{name:'id',type:'integer',required:true,description:'Post ID'}],requestBody:null,responseExample:'{\n "message": "Post deleted successfully"\n}',statusCodes:[{code:'200',desc:'Deleted'},{code:'404',desc:'Post not found'}]}, {method:'GET',path:'/posts/:id/comments',description:'List comments for a post',params:[{name:'id',type:'integer',required:true,description:'Post ID'}],requestBody:null,responseExample:'[\n {\n "id": 1,\n "body": "Great article!",\n "author": { "id": 2, "name": "Bob" },\n "created_at": "2026-01-16T12:00:00Z"\n }\n]',statusCodes:[{code:'200',desc:'Success'}]}, {method:'POST',path:'/posts/:id/comments',description:'Add a comment to a post',params:[{name:'id',type:'integer',required:true,description:'Post ID'}],requestBody:'{\n "body": "This is a great post!"\n}',responseExample:'{\n "id": 3,\n "body": "This is a great post!",\n "created_at": "2026-02-20T15:00:00Z"\n}',statusCodes:[{code:'201',desc:'Created'},{code:'404',desc:'Post not found'}]} ]; } else if(name === 'ecommerce') { document.getElementById('apiTitle').value = 'E-Commerce API'; document.getElementById('apiVersion').value = '3.1.0'; document.getElementById('apiBaseUrl').value = 'https://api.myshop.com/v3'; document.getElementById('apiDesc').value = 'Complete e-commerce API for products, orders, cart management, and payments.'; endpoints = [ {method:'GET',path:'/products',description:'List products',params:[{name:'category',type:'string',required:false,description:'Filter by category'},{name:'min_price',type:'number',required:false,description:'Minimum price'},{name:'max_price',type:'number',required:false,description:'Maximum price'},{name:'sort',type:'string',required:false,description:'Sort by: price, name, rating'},{name:'page',type:'integer',required:false,description:'Page number'}],requestBody:null,responseExample:'{\n "data": [\n {\n "id": "prod_abc123",\n "name": "Wireless Headphones",\n "price": 79.99,\n "currency": "USD",\n "category": "electronics",\n "rating": 4.5,\n "in_stock": true,\n "image_url": "https://cdn.myshop.com/products/headphones.jpg"\n }\n ],\n "pagination": { "page": 1, "total_pages": 10, "total_items": 195 }\n}',statusCodes:[{code:'200',desc:'Success'}]}, {method:'GET',path:'/products/:id',description:'Get product details',params:[{name:'id',type:'string',required:true,description:'Product ID'}],requestBody:null,responseExample:'{\n "id": "prod_abc123",\n "name": "Wireless Headphones",\n "description": "Premium noise-cancelling wireless headphones...",\n "price": 79.99,\n "currency": "USD",\n "category": "electronics",\n "rating": 4.5,\n "reviews_count": 128,\n "variants": [\n { "color": "black", "sku": "WH-BLK-001", "in_stock": true },\n { "color": "white", "sku": "WH-WHT-001", "in_stock": false }\n ]\n}',statusCodes:[{code:'200',desc:'Success'},{code:'404',desc:'Product not found'}]}, {method:'POST',path:'/cart/items',description:'Add item to cart',params:[],requestBody:'{\n "product_id": "prod_abc123",\n "quantity": 2,\n "variant_sku": "WH-BLK-001"\n}',responseExample:'{\n "cart_id": "cart_xyz789",\n "items": [\n {\n "product_id": "prod_abc123",\n "name": "Wireless Headphones",\n "quantity": 2,\n "unit_price": 79.99,\n "subtotal": 159.98\n }\n ],\n "total": 159.98\n}',statusCodes:[{code:'200',desc:'Item added'},{code:'400',desc:'Invalid product or variant'},{code:'409',desc:'Out of stock'}]}, {method:'DELETE',path:'/cart/items/:itemId',description:'Remove item from cart',params:[{name:'itemId',type:'string',required:true,description:'Cart item ID'}],requestBody:null,responseExample:'{\n "cart_id": "cart_xyz789",\n "items": [],\n "total": 0\n}',statusCodes:[{code:'200',desc:'Item removed'},{code:'404',desc:'Item not in cart'}]}, {method:'POST',path:'/orders',description:'Create an order (checkout)',params:[],requestBody:'{\n "cart_id": "cart_xyz789",\n "shipping_address": {\n "name": "John Doe",\n "line1": "123 Main St",\n "city": "San Francisco",\n "state": "CA",\n "zip": "94102",\n "country": "US"\n },\n "payment_method": "pm_card_visa"\n}',responseExample:'{\n "order_id": "ord_def456",\n "status": "confirmed",\n "total": 169.97,\n "items_count": 2,\n "estimated_delivery": "2026-03-01",\n "tracking_url": null\n}',statusCodes:[{code:'201',desc:'Order created'},{code:'400',desc:'Validation error'},{code:'402',desc:'Payment failed'}]}, {method:'GET',path:'/orders/:id',description:'Get order details',params:[{name:'id',type:'string',required:true,description:'Order ID'}],requestBody:null,responseExample:'{\n "order_id": "ord_def456",\n "status": "shipped",\n "items": [\n { "product": "Wireless Headphones", "quantity": 2, "price": 79.99 }\n ],\n "total": 169.97,\n "shipping_address": { "city": "San Francisco", "state": "CA" },\n "tracking_number": "1Z999AA10123456784",\n "created_at": "2026-02-20T16:00:00Z"\n}',statusCodes:[{code:'200',desc:'Success'},{code:'404',desc:'Order not found'}]} ]; } activeEndpointIdx = 0; renderEndpointsList(); renderPreview(); } // --- Init --- renderEndpointsList(); renderPreview(); // Listen for API info changes ['apiTitle','apiVersion','apiBaseUrl','apiDesc'].forEach(id => { document.getElementById(id).addEventListener('input', renderPreview); }); // --- Init --- renderEndpointsList(); // Listen for API info changes ['apiTitle','apiVersion','apiBaseUrl','apiDesc'].forEach(id => { document.getElementById(id).addEventListener('input', renderPreview); });