================================================================================ OVERSKILL API - FULL AGENT DOCUMENTATION Version: 1.3 | Updated: 2026-02-28 ================================================================================ OVERVIEW -------- OverSkill is a platform for generating, deploying, and managing full-stack web apps via API. Send a plain-English prompt and get back a live deployed app. Every app includes: React + TypeScript frontend, secure database, user authentication, and fast worldwide hosting. AUTHENTICATION -------------- All requests require authentication. Two methods are supported: 1. API Key (recommended): X-API-Key: os_your_key_here 2. OAuth 2.0 Bearer Token: Authorization: Bearer Keys start with "os_". Get yours at: https://overskill.com/account (Team Settings > API Keys) BASE URL -------- https://overskill.com/api/v1 ================================================================================ ENDPOINTS ================================================================================ -------------------------------------------------------------------------------- POST /api/v1/generation_queue Generate a new app or iterate on an existing one. -------------------------------------------------------------------------------- Request body: { "prompt": "Build a task management app" (required), "app_id": "QjqEkj" (optional - update existing app), "name": "My App" (optional - app name), "callback_url": "https://..." (optional - webhook on completion), "ai_model": "claude-opus-4-6" (optional - default: claude-opus-4-6), "metadata": {} (optional - custom keys passed through to callbacks) } Response 202 Accepted: { "job_id": "abc123", "app_id": "QjqEkj", "message_id": 456, "status": "queued", "estimated_time_seconds": 45, "webhook_events": ["app.generation.started", "app.generation.completed", "app.generation.failed"], "status_url": "https://overskill.com/api/v1/generation_queue/abc123", "app_url": "https://overskill.com/account/apps/QjqEkj/edit" } Errors: 400 (no prompt), 401 (bad key), 403 (no generation:queue permission), 429 (rate limited) -------------------------------------------------------------------------------- GET /api/v1/generation_queue/:id Check generation status by job ID or message ID. -------------------------------------------------------------------------------- Response 200: { "job_id": "abc123", "app_id": "QjqEkj", "status": "processing" | "completed" | "failed" | "cancelled", "progress": 10 | 25 | 50 | 75 | 100, "message": "Generating your app...", "app": { "id": "QjqEkj", "name": "Task Manager", "status": "generated", "preview_url": "https://preview-QjqEkj.overskill.app", "production_url": null, "created_at": "2026-02-18T12:00:00Z" }, "started_at": "2026-02-18T12:00:00Z", "completed_at": "2026-02-18T12:00:45Z" } Status values: queued, processing, completed, failed, cancelled Progress values: 5 (queued), 10 (executing), 25 (planning), 50 (generating), 75 (processing), 100 (complete) NOTE: The "progress" field uses coarse checkpoints and may stay at 10 for most of the build. The "message" field provides more useful real-time status text describing what the AI is currently doing. Prefer "message" for user-facing progress indicators. -------------------------------------------------------------------------------- POST /api/v1/managed_apps Create a new app (optionally queue generation). -------------------------------------------------------------------------------- Request body: { "name": "My App" (optional - default: "API Created App"), "prompt": "Build a..." (optional - triggers generation if provided), "ai_model": "claude-opus-4-6" (optional), "visibility": "public" | "login_required" (optional - default: "public"), "auto_generate": true | false (optional - default: true if prompt provided) } Response 201: { "app": { "id": "QjqEkj", "name": "My App", "status": "generating", "preview_url": null, "production_url": null, "created_at": "2026-02-18T12:00:00Z" }, "message": "App created and generation queued" } -------------------------------------------------------------------------------- GET /api/v1/managed_apps List all apps for your account. -------------------------------------------------------------------------------- Query params: status - filter by status (draft, generating, generated, published, failed) name - search by name (partial match) page - page number (default: 1) per_page - results per page (default: 25, max: 100) Response 200: { "apps": [ { "id": "QjqEkj", "name": "My App", "description": "...", "status": "generated", "visibility": "public", "ai_model": "claude-opus-4-6", "preview_url": "https://preview-QjqEkj.overskill.app", "production_url": "https://QjqEkj.overskill.app", "published_at": "2026-02-18T...", "created_at": "2026-02-18T...", "updated_at": "2026-02-18T..." } ], "meta": { "current_page": 1, "total_pages": 3, "total_count": 52, "per_page": 25 } } -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:id Get detailed info about a single app. -------------------------------------------------------------------------------- Response 200: { "app": { "id": "QjqEkj", "name": "My App", "description": "...", "status": "generated", "visibility": "public", "ai_model": "claude-opus-4-6", "preview_url": "...", "production_url": "...", "creator": { "id": 123, "email": "user@example.com" }, "versions_count": 5, "files_count": 24, "users_count": 12, "urls": { "editor": "https://overskill.com/account/apps/QjqEkj/edit", "preview": "...", "production": "..." } } } -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:id/status Deployment and generation status with live URLs. -------------------------------------------------------------------------------- Response 200: { "app_id": "QjqEkj", "name": "My App", "status": "generated", "deployment": { "id": 456, "environment": "production", "status": "deployed", "deployed_at": "2026-02-18T..." }, "generation": { "status": "complete", "started_at": "2026-02-18T...", "completed_at": "2026-02-18T..." }, "urls": { "preview": "https://preview-QjqEkj.overskill.app", "production": "https://QjqEkj.overskill.app", "editor": "https://overskill.com/account/apps/QjqEkj/edit" } } -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:id/files Get all source files for an app. -------------------------------------------------------------------------------- Query params: path - filter files by path (e.g., "src/pages" returns files containing that path) Response 200: { "app_id": "QjqEkj", "files": [ { "path": "src/App.tsx", "content": "import React from 'react'...", "size": 1234, "updated_at": "2026-02-18T12:00:00Z" } ], "count": 24 } -------------------------------------------------------------------------------- PATCH /api/v1/managed_apps/:id Update app settings. -------------------------------------------------------------------------------- Request body: { "name": "New Name" (optional), "description": "Updated desc" (optional), "visibility": "public" | "login_required" (optional), "ai_model": "claude-opus-4-6" (optional) } Response 200: { "app": { ...updated fields } } Visibility values: "public" - Anyone can access, no login required (default) "login_required" - Users must log in with OverSkill before accessing NOTE: When visibility is "login_required", both preview and production URLs will show an OverSkill login page. Users must authenticate before they can see the app. Changing visibility takes effect immediately (no redeployment needed). -------------------------------------------------------------------------------- DELETE /api/v1/managed_apps/:id Delete an app and all its resources. -------------------------------------------------------------------------------- Response 200: { "success": true, "message": "App deleted" } -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:id/deploy Deploy an app to production. -------------------------------------------------------------------------------- Response 202: { "deployment_id": 789, "status": "queued", "message": "Production deployment queued" } Note: The deployment is created with internal status "pending". The response returns "queued" for simplicity. When checking deployment status via GET .../status, you will see the actual status: pending, building, deploying, deployed, or failed. -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:id/rollback Rollback to a previous version. -------------------------------------------------------------------------------- Request body: { "version_id": 123 } (optional - defaults to previous version) Response 200: { "message": "Rollback initiated", "version_id": 123 } -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:id/analytics App analytics summary. -------------------------------------------------------------------------------- Query params: period - time period (7d, 30d, 90d; default: 7d) Response 200: { "app_id": "QjqEkj", "period": "7d", "metrics": { "page_views": 1234, "unique_visitors": 456, "sessions": 789 } } ================================================================================ WEBHOOK MANAGEMENT ================================================================================ -------------------------------------------------------------------------------- GET /api/v1/webhooks - List webhook subscriptions POST /api/v1/webhooks - Create webhook subscription GET /api/v1/webhooks/:id - Get webhook details PATCH /api/v1/webhooks/:id - Update webhook DELETE /api/v1/webhooks/:id - Delete webhook POST /api/v1/webhooks/:id/test - Send test event GET /api/v1/webhooks/:id/deliveries - View delivery history -------------------------------------------------------------------------------- Create webhook body: { "url": "https://your-server.com/webhook", "events": ["app.generation.completed", "app.deployment.completed"], "name": "My Webhook" (optional - default: "API Webhook"), "secret": "your_webhook_secret" (optional - used for signature verification), "description": "..." (optional) } Webhook events: app.created, app.updated, app.deleted app.generation.started, app.generation.completed, app.generation.failed app.generation.progress app.deployment.started, app.deployment.completed ================================================================================ MCP (MODEL CONTEXT PROTOCOL) ================================================================================ POST /api/v1/mcp/execute_tool - Execute an MCP tool GET /api/v1/mcp/tools - List available MCP tools Request body for execute_tool: { "tool": "overskill-generate-app", "app_id": "QjqEkj" (required for most tools, NOT needed for generate-app), "params": { ...tool-specific parameters } } Available tools: App Generation (no app_id required): overskill-generate-app - Create a new app from a prompt params: { "name": "My App", "prompt": "Build a...", "description": "...", "model": "..." } Returns: { "success": true, "app_id": "...", "status_url": "...", "preview_url": null } File Operations (require app_id): overskill-view-file - View file contents params: { "path": "src/App.tsx" } overskill-write-file - Create or update a file (triggers preview rebuild) params: { "path": "src/App.tsx", "content": "..." } overskill-list-files - List files matching a pattern params: { "pattern": "src/**/*.tsx" } overskill-delete-file - Delete a file (triggers preview rebuild) params: { "path": "src/old-file.tsx" } Entity Operations (require app_id): overskill-create-entity - Create a database table params: { "name": "tasks", "columns": [...], "user_scoping": "user_scoped" } overskill-query-data - Query records params: { "entity": "tasks", "filters": {...}, "order_by": "...", "limit": 10 } overskill-insert-data - Insert a record params: { "entity": "tasks", "data": {...} } overskill-update-data - Update a record params: { "entity": "tasks", "id": "...", "data": {...} } overskill-delete-data - Delete a record params: { "entity": "tasks", "id": "..." } -------------------------------------------------------------------------------- DELETE /api/v1/generation_queue/:id Cancel a queued or in-progress generation. -------------------------------------------------------------------------------- Response 200: { "cancelled": true, "job_id": "abc123" } ================================================================================ CALLBACK URL PATTERN ================================================================================ When queuing generation with callback_url, OverSkill POSTs to your URL on completion or failure. Callback payload: { "event": "app.generation.completed" | "app.generation.failed", "app_id": "QjqEkj", "app_name": "My App", "status": "generated" | "failed", "urls": { "preview": "https://preview-QjqEkj.overskill.app", "production": null, "editor": "https://overskill.com/account/apps/QjqEkj/edit" }, "generation": { "message_id": 456, "started_at": "2026-02-18T12:00:00Z", "completed_at": "2026-02-18T12:00:45Z" }, "credits_used": 12.5, "tokens_used": { "input": 10000, "output": 5000 }, "metadata": { ...your custom metadata keys passed through } } Notes: - "credits_used" and "tokens_used" are only present when generation metrics are available (may be absent on some failures) - "metadata" includes your custom keys; internal keys like "api_key_id" may also appear — filter by your known keys Signature verification: Header: X-OverSkill-Signature: t=,v1= Header: X-Overskill-Timestamp: To verify: 1. Extract timestamp (t=) and signature (v1=) from X-OverSkill-Signature 2. Compute: HMAC-SHA256(your_webhook_secret, ".") 3. Compare computed hex digest with the v1 value 4. Optionally check timestamp is within acceptable window (e.g., 5 minutes) ================================================================================ POLLING PATTERN ================================================================================ 1. POST /api/v1/generation_queue -> get job_id and app_id 2. Wait 3 seconds 3. GET /api/v1/generation_queue/:job_id -> check status 4. If status == "processing", go to step 2 5. If status == "completed", use app.preview_url 6. If status == "failed", report error Typical generation time: 30-60 seconds. ================================================================================ RATE LIMITS ================================================================================ Recommended client-side limits (plan your integration with these for forward compatibility as server-side enforcement is being rolled out progressively): Generation (POST /generation_queue): 20 per hour per API key API reads (GET): 300 per minute per API key API writes (POST/PATCH/DELETE): 60 per minute per API key Deployments: 10 per hour per API key ================================================================================ ERROR FORMAT ================================================================================ All errors return JSON: { "error": "Error type", "message": "Human-readable description" } HTTP status codes: 400 - Bad request (invalid parameters) 401 - Unauthorized (missing/invalid API key) 403 - Forbidden (insufficient permissions) 404 - Not found 422 - Validation failed (with "errors" array) 429 - Rate limit exceeded 500 - Server error ================================================================================ API KEY PERMISSIONS ================================================================================ read_only: apps:read, users:read, analytics:read, webhooks:read read_write: + apps:write, users:write, webhooks:write full_access: + apps:delete, generation:queue, users:*, webhooks:* generation:queue permission is required for POST /generation_queue. ================================================================================ CUSTOM DOMAINS ================================================================================ Custom domains let you serve an OverSkill app from your own domain (e.g., app.yourdomain.com) instead of {slug}.overskill.app. Manage via API or dashboard (Settings → Publish → Custom Domain). -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:app_id/custom_domains List all custom domains for an app. -------------------------------------------------------------------------------- Response 200: { "custom_domains": [ { "id": 123, "domain": "app.yourdomain.com", "url": "https://app.yourdomain.com", "verification_status": "pending" | "verified" | "failed", "ssl_status": "pending" | "initializing" | "active" | "failed", "primary": false, "active": true, "operational": false, "created_at": "2026-02-28T..." } ], "cname_target": "proxy.overskill.app", "can_add_more": true } -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:app_id/custom_domains Add a custom domain to an app. -------------------------------------------------------------------------------- Request body: { "domain": "app.yourdomain.com" } Response 201: { "custom_domain": { "id": 123, "domain": "app.yourdomain.com", "url": "https://app.yourdomain.com", "verification_status": "pending", "ssl_status": "pending", "operational": false, "is_apex": false, "dns_records": { "type": "CNAME", "name": "app", "value": "proxy.overskill.app", "ttl": 300 } }, "dns_records": { "type": "CNAME", "name": "app", "value": "proxy.overskill.app", "ttl": 300 }, "cname_target": "proxy.overskill.app" } After creating, instruct the user to configure DNS at their registrar: Subdomains (e.g., app.yourdomain.com): Type: CNAME Name: app (or whatever subdomain they chose) Value: proxy.overskill.app TTL: 300 (or Auto) Apex/root domains (e.g., yourdomain.com): Type: A Name: @ Value: provided in response or dashboard TTL: 300 DNS changes typically propagate in 5-15 minutes (up to 48 hours). -------------------------------------------------------------------------------- GET /api/v1/managed_apps/:app_id/custom_domains/:id Get detailed domain info including DNS records and errors. -------------------------------------------------------------------------------- Response 200: { "custom_domain": { "id": 123, "domain": "app.yourdomain.com", "url": "https://app.yourdomain.com", "verification_status": "verified", "ssl_status": "active", "primary": true, "active": true, "operational": true, "is_apex": false, "dns_records": { "type": "CNAME", "name": "app", "value": "proxy.overskill.app", "ttl": 300 }, "verified_at": "2026-02-28T...", "ssl_active_at": "2026-02-28T...", "verification_error": null, "ssl_error": null, "created_at": "2026-02-28T..." } } -------------------------------------------------------------------------------- DELETE /api/v1/managed_apps/:app_id/custom_domains/:id Remove a custom domain. Cleans up Cloudflare hostname automatically. -------------------------------------------------------------------------------- Response 200: { "success": true, "message": "Domain app.yourdomain.com removed" } -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:app_id/custom_domains/:id/set_primary Set a domain as the app's primary custom domain. -------------------------------------------------------------------------------- Response 200: { "custom_domain": { ...updated domain }, "message": "app.yourdomain.com set as primary domain" } -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:app_id/custom_domains/:id/check_status Re-check DNS verification and SSL provisioning status with Cloudflare. -------------------------------------------------------------------------------- Response 200: { "custom_domain": { ...updated domain }, "cloudflare_status": "active", "ssl_status": "active" } Use this to poll after DNS configuration. SSL certificates are provisioned automatically via Cloudflare SSL for SaaS once DNS propagation is confirmed. -------------------------------------------------------------------------------- POST /api/v1/managed_apps/:app_id/custom_domains/:id/refresh Trigger a fresh DNS/SSL verification cycle. -------------------------------------------------------------------------------- Response 200: { "custom_domain": { ...refreshed domain }, "message": "Verification refreshed for app.yourdomain.com" } DOMAIN STATUS FLOW ------------------ pending → verified (DNS confirmed) → active (SSL provisioned + operational) "operational" is true when: verification_status == "verified" AND ssl_status == "active" AGENT WORKFLOW -------------- 1. POST .../custom_domains { "domain": "app.example.com" } 2. Tell user to configure DNS: CNAME app → proxy.overskill.app 3. Wait for DNS propagation (5-15 minutes) 4. POST .../custom_domains/:id/check_status (poll every 30 seconds) 5. When operational == true, domain is live AUTOMATIC DNS SETUP (Dashboard Only) ------------------------------------- For supported registrars (GoDaddy, Namecheap, Google Domains, etc.), users can click "Set Up Automatically" in the dashboard to configure DNS in one click via Entri. This is only available in the dashboard UI, not via API. LIMITS ------ Maximum 5 custom domains per app. ================================================================================ LINKS ================================================================================ Skill file: https://overskill.com/SKILL.md Full docs: https://overskill.com/llms-full.txt API docs: https://overskill.com/developers Dashboard: https://overskill.com/account Webhook docs: https://overskill.com/developers/webhooks Zapier: https://overskill.com/developers/zapier Skill install: https://overskill.com/developers/skill