import { Metadata } from 'next' import { generateSEO } from '@/lib/seo' import { Badge } from '@/components/ui/badge' import { Card, CardContent, CardHeader, CardTitle } from '@/components/ui/card' const BASE_URL = process.env.NEXT_PUBLIC_APP_URL || 'https://open-prompt.netlify.app' export const metadata: Metadata = generateSEO({ title: 'API Documentation | OpenPrompt', description: 'OpenPrompt Public REST API — run AI prompts and access 177+ AI tools programmatically. No signup required for public endpoints.', url: `${BASE_URL}/docs/api`, keywords: ['OpenPrompt API', 'AI prompts API', 'REST API', 'prompt API', 'AI tools API'], }) as Metadata const endpoints = [ { method: 'GET', path: '/api/v1', description: 'API overview — lists all endpoints, rate limits, and authentication info.', response: '{ name, version, endpoints[], rateLimits }', auth: false, }, { method: 'GET', path: '/api/v1/prompts', description: 'List public prompts with search, filter, sort, and pagination.', params: [ { name: 'q', type: 'string', desc: 'Search term (title, description, tags)' }, { name: 'category', type: 'string', desc: 'Filter by category' }, { name: 'tags', type: 'string', desc: 'Comma-separated tag filter' }, { name: 'sort', type: 'runs | stars | newest', desc: 'Sort order (default: newest)' }, { name: 'page', type: 'number', desc: 'Page number (default: 1)' }, { name: 'limit', type: 'number', desc: 'Results per page (max 100, default 20)' }, ], response: '{ data: Prompt[], pagination: { page, limit, total, totalPages } }', auth: false, }, { method: 'GET', path: '/api/v1/prompts/:slug', description: 'Retrieve a single public prompt by its slug, including template and schema.', response: '{ data: Prompt }', auth: false, }, { method: 'POST', path: '/api/v1/prompts/:slug/run', description: 'Execute a prompt with variable substitution. Supports streaming.', body: [ { name: 'variables', type: 'object', desc: 'Key-value pairs matching the prompt schema' }, { name: 'model', type: 'string', desc: 'Model override (must be in prompt\'s modelAllowed)' }, { name: 'stream', type: 'boolean', desc: 'Stream response as text/plain (default: false)' }, ], response: '{ output: string, model: string, cached: boolean }', auth: false, rateLimit: '10/hr guest · 50/hr authenticated · 500/hr Pro', }, { method: 'GET', path: '/api/v1/tools', description: 'List all 177+ AI tools with name, description, category, and icon.', params: [ { name: 'category', type: 'string', desc: 'Filter by category' }, { name: 'q', type: 'string', desc: 'Search by name or description' }, { name: 'limit', type: 'number', desc: 'Max results (default 50, max 200)' }, ], response: '{ data: Tool[], total, totalAll }', auth: false, }, ] const codeExamples = { listPrompts: `// List top prompts for "marketing" const response = await fetch( 'https://open-prompt.netlify.app/api/v1/prompts?category=marketing&sort=stars&limit=10' ) const { data, pagination } = await response.json() console.log(\`Found \${pagination.total} prompts\`)`, runPrompt: `// Execute the "blog-writer" prompt const response = await fetch( 'https://open-prompt.netlify.app/api/v1/prompts/blog-writer/run', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ variables: { topic: 'The Future of AI Agents', tone: 'professional', length: '800 words', }, model: 'gemini-2.0-flash', }), } ) const { output } = await response.json() console.log(output)`, streamPrompt: `// Stream a prompt response in real-time const response = await fetch( 'https://open-prompt.netlify.app/api/v1/prompts/blog-writer/run', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ variables: { topic: 'AI trends 2026' }, stream: true, // ← enable streaming }), } ) const reader = response.body.getReader() const decoder = new TextDecoder() while (true) { const { done, value } = await reader.read() if (done) break process.stdout.write(decoder.decode(value)) }`, listTools: `// Search for email-related tools const response = await fetch( 'https://open-prompt.netlify.app/api/v1/tools?q=email&limit=5' ) const { data } = await response.json() data.forEach(tool => console.log(\`\${tool.icon} \${tool.name}\`))`, } const methodColors: Record = { GET: 'bg-green-500/15 text-green-600 dark:text-green-400 border-green-500/30', POST: 'bg-blue-500/15 text-blue-600 dark:text-blue-400 border-blue-500/30', PUT: 'bg-amber-500/15 text-amber-600 dark:text-amber-400 border-amber-500/30', DELETE: 'bg-red-500/15 text-red-600 dark:text-red-400 border-red-500/30', } export default function ApiDocsPage() { return (
{/* Header */}

API Documentation

v1.0 Public Beta

OpenPrompt's public REST API lets you run prompts, execute AI tools, and browse the prompt library programmatically. No API key required for public endpoints.

{/* Base URL */}

Base URL

{BASE_URL}/api/v1

Rate Limits

10 req/hr guest ·{' '} 50 req/hr authenticated ·{' '} 500 req/hr Pro

Authentication

Not required for public data

{/* Endpoints */}

Endpoints

{endpoints.map((ep) => (
{ep.method} {ep.path} {!ep.auth && ( No auth )}

{ep.description}

{ep.params && ep.params.length > 0 && (

Query Parameters

{ep.params.map((p, i) => (
{p.name} {p.type} {p.desc}
))}
)} {ep.body && ep.body.length > 0 && (

Request Body (JSON)

{ep.body.map((p, i) => (
{p.name} {p.type} {p.desc}
))}
)}

Response

{ep.response}
{ep.rateLimit && (

Rate limit: {ep.rateLimit}

)}
))}
{/* Code Examples */}

Code Examples

{[ { title: 'List prompts by category', code: codeExamples.listPrompts }, { title: 'Run a prompt with variables', code: codeExamples.runPrompt }, { title: 'Stream a prompt response', code: codeExamples.streamPrompt }, { title: 'Search AI tools', code: codeExamples.listTools }, ].map(({ title, code }) => (

{title}

                                {code}
                            
))}
{/* Rate Limit Headers */}

Rate Limit Headers

Every API response includes rate limit information in the response headers:

{[ { header: 'X-RateLimit-Limit', desc: 'Maximum requests allowed in the current window' }, { header: 'X-RateLimit-Remaining', desc: 'Requests remaining in the current window' }, { header: 'X-RateLimit-Reset', desc: 'Unix timestamp when the window resets' }, { header: 'X-Cache', desc: 'HIT if served from cache, MISS if freshly generated' }, ].map((h, i) => (
{h.header} {h.desc}
))}
{/* Coming Soon */}

🔑 API Keys Coming Soon

Pro users will receive API keys for higher rate limits (500 req/hr) and access to private prompts. Subscribe to Pro to be first in line.

) }