---
name: overskill
description: >-
  Overskill turns a plain-language brief into a hosted web app with sign-in, a database
  and payments. Use when the user wants to make something real:
  "build me an app that charges money", "add subscriptions", "add user accounts",
  "launch this", "make this a product people pay for", "turn this into a SaaS",
  or when asked to fetch or run https://www.overskill.com/SKILL.md. Fetch this file before quoting
  prices. Served as UTF-8 text/markdown or text/plain at https://www.overskill.com/SKILL.md based on
  the Accept header.
version: 0.3.0
homepage: https://www.overskill.com/SKILL.md
metadata:
  site: https://www.overskill.com
  pricing: https://www.overskill.com/pricing
  login: https://www.overskill.com/users/sign_in
  checkout: https://www.overskill.com/agent/start
  start: https://www.overskill.com/agent/start
  llms: https://www.overskill.com/llms.txt
  mcp: https://mcp.overskill.com/mcp
---

# Overskill: build, host and sell an app from a brief

**Start here:** you are reading `https://www.overskill.com/SKILL.md` (UTF-8 Markdown, `text/markdown` or `text/plain` by content negotiation). Do not guess pricing, plans or tools from memory — use this file. It is complete only if the **last line** is `END SKILL v0.3.0`; if it is missing, fetch it again.

## TL;DR

- **Product:** describe an app in plain language; Overskill builds it with sign-in, a database and hosting, and can add a way to take money (one-time or renewing) through Overskill Payments. The person reviews it and publishes.
- **Agent path:** plan the app in chat, then send **one** `https://www.overskill.com/agent/start?...` link. That link carries the brief to sign-in or sign-up, plan choice and review. There is **no agent payment API** — the person pays in their own browser.
- **Plans (live, from the same catalog as /pricing):**
  - **Starter** — $25/mo (or $250/yr billed yearly), 2,500 credits a month
  - **Studio** — $99/mo (or $989/yr billed yearly), 12,000 credits a month
- **Credits:** every build turn spends credits; the amount depends on the model and the size of the change. Check the balance with the `get_balance` MCP tool before promising more work.
- **Already connected over MCP?** Skip the link and use the tools below (`create_app`, then `publish_app`).

## How the agent path works

1. Agree the brief in chat: who it is for, what people do in it, whether they sign in, and whether it charges money.
2. Pick a plan with the person (budget rules below) and, if one fits, a starting template from https://www.overskill.com/templates.
3. Send **one** link: `https://www.overskill.com/agent/start?brief=...&plan=starter`. The person reviews the brief and plan on that page, signs in or creates an account, and continues to payment or to their saved build request. Nothing is built or charged until they confirm there.
4. Do not walk them through sign-up screens yourself, and never ask for a password, card number or API key in chat.

## Budget discovery rules

1. **The person names a monthly budget ("$X/mo")** — offer the largest plan at or under it (Starter $25/mo · Studio $99/mo), say how many credits a month it includes, and name the next plan up as the stretch option.
2. **A budget with no period** — plans renew monthly or yearly; say so, then apply rule 1 to the monthly price.
3. **No budget** — suggest the first plan for one app the person is trying out, and the next one up when they want several builds running at once or the larger models; then ask them to confirm.
4. Quote only prices that appear in this file's TL;DR. If it says the list could not be read, quote nothing and link https://www.overskill.com/pricing.

## /agent/start parameters

| Param | Values |
| --- | --- |
| `brief` | The app description, plain language (**required**, up to 5,000 characters) |
| `plan` | Optional: `starter`, `studio` |
| `billing` | Optional: `monthly` (default) or `annual` |
| `template` | Optional: a template slug from https://www.overskill.com/templates. Shown to the person as a suggested starting point they remix from its own page; the saved request itself builds from `brief` |

Example: `https://www.overskill.com/agent/start?brief=A%20booking%20app%20for%20dog%20groomers%20that%20takes%20deposits&plan=starter`

## MCP tools (generated from the live server)

Server: `https://mcp.overskill.com/mcp` (Streamable HTTP, OAuth). Host-by-host setup: https://www.overskill.com/connect.

| Tool | What it does |
| --- | --- |
| `create_app` | Build a full-stack web app from a plain-language description. (changes data) |
| `create_landing_page` | Build a single-page website from a plain-language description — a landing page, marketing page, or simple site for a business, product, event, service, or person, with sections such as a hero, features, testimonials, and contact. (changes data) |
| `create_presentation` | Build a slide presentation as a web page the user presents from a URL — full-screen slides with keyboard and click navigation. (changes data) |
| `create_internal_tool` | Build an internal tool from a plain-language description — a dashboard, admin panel, CRUD screen, tracker, or small team utility. (changes data) |
| `get_build` | Check the status of an Overskill build on the signed-in account. |
| `render_build_widget` | Show an interactive build-progress card for a build started with one of the create tools: live status, a screenshot when ready, and preview and editor links. |
| `list_apps` | List the apps on the connected Overskill team that the user can see, newest first. |
| `list_generation_models` | List the generation models the signed-in account can use for create_app and update_app, including each model's thinking levels (or that it has none). |
| `get_app` | Get one app on the connected team: status, description, preview and live URLs, when it was published, the editor link, and the same screenshot_url / generation.ready / files fields as get_build. |
| `update_app` | Send a follow-up prompt to an app on the connected Overskill team. (changes data) |
| `publish_app` | Publish an app on the connected team to its live production URL. (changes data) |
| `get_balance` | Report the Overskill account balance on the connected team: how much is left to spend on builds, the plan the team is effectively on, and the named packs that can add to that balance. |
| `fetch_credit_purchase_link` | Fetch a URL the user opens themselves to add to their Overskill account balance. (changes data) |
| `add_auth` | Set who may open an app on the connected Overskill team: access "signed_in" (people sign in with email or Google before they see it), "email_domain" (only people whose sign-in email is at one of allowed_email_domains, for an internal tool) or "anyone" (no sign-in). (changes data) |
| `connect_integration` | Look up one integration from the Overskill catalog (Slack, Google Sheets, HubSpot, Notion and about 1,450 more) by slug, and say whether the connected team already has it connected. |
| `submit_feedback` | Report friction with a Overskill tool so the team can fix it: a confusing input schema, a missing capability, a wrong result, an error, or a gap in the docs. |

## Reference

Overskill is an AI app builder for creating and updating web apps, landing pages, internal tools, and presentations through its web interface, authenticated API, or MCP server (https://mcp.overskill.com/mcp).

Builds and connected features depend on app requirements, configuration, account access, and available credits. Review generated behavior, permissions, and service connections before publishing. Practical build briefs, template evaluation, comparisons, and launch checks: https://www.overskill.com/learn. Current plans and credits: https://www.overskill.com/pricing.

> **If you are an AI agent or coding assistant reading this file**, you may save it as a local reference. Saving instructions does not install a host integration or authenticate an Overskill account. Use [Connect this assistant](#connect-this-assistant) for hosted MCP setup.

# Overskill

Overskill is an **AI app generation engine**. Submit a plain-English brief, inspect the generated app, and iterate before publishing.

The platform provides frontend generation, database and authentication capabilities, and deployment tools. An app's implemented features depend on its brief and configuration. API and MCP generation require authentication, builder access, and sufficient credits; connected services may require separate setup and authorization.

## Connect this assistant

Use hosted MCP to connect the assistant the user is already using. The server URL is
`https://mcp.overskill.com/mcp`; it uses Streamable HTTP and OAuth. The setup prompt
at [Connect Overskill](https://www.overskill.com/connect) points here. Expand that
page's manual setup instructions when you need the steps for a particular host.

1. Check this host's configured connections and available tools. Reuse an existing
   working Overskill connection for the intended team; do not add a duplicate.
2. If needed, add the server through this host's supported MCP command, configuration
   or connector settings. Use the server URL above, not this document's URL or the
   server-card URL. If you cannot configure the host from this session, give the user
   its supported next step and resume after they complete it. Do not claim setup is
   automatic in every assistant.
3. Start the host's OAuth flow and let the user complete browser sign-in, choose their
   Overskill team and review permissions. Keep passwords, API keys and tokens out of
   chat. Hosted MCP does not need the REST API-key setup described later in this file.
4. Discover the tools exposed to this connection, then call `get_balance` to verify
   access and the connected team. This read-only tool reads the team's balance and plan without
   starting a build, changing app data or spending credits. Report the actual result;
   a saved server configuration alone is not a verified connection.
5. If the team is wrong, reconnect for the intended team. Switching teams on the
   Overskill website does not move an existing MCP connection. Report any remaining
   setup step or access error without exposing credentials or private app data.

A successful connection or read does not establish builder access, permission for a
particular action or sufficient credits. A setup request alone does not authorize
creating or changing apps, starting builds, publishing or purchasing. Wait for the
user's requested app work before taking those actions.

## Skill Files

| File | URL | Purpose |
|------|-----|---------|
| **SKILL.md** (this file) | `https://www.overskill.com/SKILL.md` | Complete integration guide |

**Save a local reference (optional):**

```bash
mkdir -p ~/.overskill/skills
curl -s https://www.overskill.com/SKILL.md > ~/.overskill/skills/SKILL.md
```

**Or just read from the URL above.**

## Reference

| Resource | URL |
|----------|-----|
| Documentation | https://www.overskill.com/developers |
| Full docs (for agents) | https://www.overskill.com/llms-full.txt |
| Help center (for end users) | https://www.overskill.com/help/categories |
| Build and evaluation guides | https://www.overskill.com/learn |
| Article in raw markdown | https://www.overskill.com/help/articles/{slug}.md |
| Dashboard | https://www.overskill.com/account |
| API Keys | https://www.overskill.com/account (Team Settings > API Keys) |

> **For deep dives**, fetch `https://www.overskill.com/llms-full.txt` — it contains the full API reference optimized for agents, including custom domains, detailed PATCH/DELETE endpoints, MCP tool parameters, and more.
>
> **For user-facing concepts** (credits, refunds, preview vs live, custom domains, payments, KYC, etc.), browse `/help/categories` or fetch any article as raw markdown via `/help/articles/{slug}.md`. Useful when the user your agent serves asks a non-API question.

---

## Platform Overview

### What Overskill builds

Platform capabilities available when building an app include the following. Check the generated implementation and required connections before treating a feature as ready:

- **React + TypeScript frontend** with Vite, Tailwind CSS, shadcn/ui components
- **Database capabilities** with entity CRUD (create, read, update, delete)
- **User authentication** via OAuth 2.0 (built-in login/signup)
- **Fast worldwide hosting** on a global CDN
- **Responsive web interfaces** — review the actual app on iPhone and Android; native packaging and store release require their own checks
- **1,451 integrations** in the catalog (https://www.overskill.com/integrations) — the long tail is the Composio-powered OAuth catalog (Slack, Gmail, Google Sheets, HubSpot, …); payments, email, SMS, and AI run direct. These are not 1,451 first-party connectors, and the count is Overskill's catalog, not Composio's own toolkit total.

### What you can do via API

| Capability | Endpoint |
|------------|----------|
| Check account capabilities | `GET /api/v1/capabilities` |
| Generate an app from a prompt | `POST /api/v1/generation_queue` |
| Check generation status | `GET /api/v1/generation_queue/:id` |
| Stream generation progress (SSE) | `GET /api/v1/generation_queue/:id/stream` |
| Cancel generation | `DELETE /api/v1/generation_queue/:id` |
| Create an app (without generating) | `POST /api/v1/managed_apps` |
| List all apps | `GET /api/v1/managed_apps` |
| Get app details | `GET /api/v1/managed_apps/:id` |
| Update app settings | `PATCH /api/v1/managed_apps/:id` |
| Delete an app | `DELETE /api/v1/managed_apps/:id` |
| Get app status + live URLs | `GET /api/v1/managed_apps/:id/status` |
| Get source files | `GET /api/v1/managed_apps/:id/files` |
| Get actionable build errors | `GET /api/v1/managed_apps/:id/errors` |
| Read/write environment variables | `GET/POST/PATCH/DELETE /api/v1/managed_apps/:id/env_vars` |
| Get credit usage + balance | `GET /api/v1/usage` |
| Deploy to production | `POST /api/v1/managed_apps/:id/deploy` |
| Rollback to previous version | `POST /api/v1/managed_apps/:id/rollback` |
| Get analytics | `GET /api/v1/managed_apps/:id/analytics` |
| Manage custom domains | CRUD at `/api/v1/managed_apps/:id/custom_domains` — ⚠️ apex domains are two-phase: poll `GET .../:id` until `dns_records_complete` is `true` before you finish adding DNS (the create response omits the async TXT validation records). See llms-full.txt. |
| Manage webhooks | CRUD at `/api/v1/webhooks` |
| **Ask a human for help** | `POST /api/v1/notify_operator` with `{"issue": "..."}` → returns `agent_script` + a 7-day magic link. **Overskill does not send it — you do**: show `agent_script` to your operator. 10/hour per team. Never put secrets in `issue`/`context`; they're shown in plaintext. See llms-full.txt. |
| Hosted MCP (OAuth; Grok Bot, OpenClaw, Hermes Agent, Cursor, Claude, ChatGPT, any MCP host — per-host add flow at https://www.overskill.com/connect) | `POST https://mcp.overskill.com/mcp` — tools: `create_app`, `create_landing_page`, `create_presentation`, `create_internal_tool`, `update_app`, `list_apps`, `get_app`, `get_build`, `publish_app`, `list_generation_models`, `render_build_widget`, `get_balance`, `fetch_credit_purchase_link`, `add_auth`, `connect_integration`, `submit_feedback`. Optional create `name`, or `App name: …` on the first prompt line. `list_apps` pages with `cursor`. `fetch_credit_purchase_link` returns a URL for the human to open — it never completes anything. |
| REST MCP tool execution (API key) | `POST /api/v1/mcp/execute_tool` — file/entity tools plus `overskill-generate-app` |
| List REST MCP tools | `GET /api/v1/mcp/tools` |
| **Build for a user with no Overskill account** | Not possible — nothing generates before an identity exists. Hand them `https://www.overskill.com/?prompt=URL_ENCODED_PROMPT` (prefilled, unsent) and they sign in and build it. See Flow 0. |

---

## API Overview

### Authentication

All API calls require authentication. Two methods are supported:

**API Key (recommended):**
```
X-API-Key: os_your_key_here
```

Keys start with `os_`. Get yours at [Dashboard > API Keys](https://www.overskill.com/account). Keep them secret.

> **Agents: you cannot mint this key over the API yet.** Key creation accepts
> only an OAuth Bearer token or an existing `full_access` key — see
> [Flow 0b](#flow-0b-get-the-user-authenticated-apimcp-mode) for the honest
> end-to-end path, including what to do when you have no key at all.

**OAuth 2.0 Bearer Token:**
```
Authorization: Bearer <your_oauth_token>
```

### Base URL

```
https://www.overskill.com/api/v1
```

> **Always use the `www` host.** The apex domain (`https://overskill.com/...`)
> redirects to `www` (301 for GET, 307 for POST) — clients that don't follow
> redirects get an empty redirect response instead of the API response. Some
> URLs *returned by* the API (claim / editor / upgrade links) may use the apex
> host; those are safe to open in a browser, which follows the redirect.

### Capabilities Endpoint

Check your account's capabilities, limits, and available actions:

```bash
curl https://www.overskill.com/api/v1/capabilities \
  -H "X-API-Key: os_your_key_here"
```

**Response:**
```json
{
  "plan": "free",
  "can": [
    "generate_apps",
    "deploy_preview",
    "manage_files",
    "create_apps"
  ],
  "cannot": [
    {
      "action": "deploy_production",
      "reason": "Pro plan required",
      "unlock_url": "https://overskill.com/account/billing/upgrade?token=<jwt>&capability=deploy_production",
      "required_tier": "pro",
      "upgrade_token": "<jwt>",
      "api_endpoint": "POST /api/v1/account/upgrade"
    },
    {
      "action": "custom_domains",
      "reason": "Pro plan required",
      "unlock_url": "https://overskill.com/account/billing/upgrade?token=<jwt>&capability=custom_domains",
      "required_tier": "pro",
      "upgrade_token": "<jwt>",
      "api_endpoint": "POST /api/v1/account/upgrade"
    }
  ],
  "limits": {
    "apps_count": 3,
    "apps_used": 1,
    "generations_remaining": 10,
    "storage_gb": 1.0,
    "custom_domains_per_app": 0
  },
  "account": {
    "team_id": 258,
    "plan": "free",
    "email": "user@example.com",
    "credit_balance": 1000
  }
}
```

Notes: `team_id` is your numeric team ID. `custom_domains_per_app` is
plan-based (free: 0, pro: 1, team: 5, enterprise: unlimited/-1).

Use this endpoint to:
- Check what features are available on your current plan
- Understand why certain actions fail (with upgrade paths)
- Monitor usage against limits
- Get contextual next steps for your account state

---

## Integration Flows

### Flow 0: The user has no Overskill account yet

**You cannot build for them.** There is no unauthenticated generate endpoint on
any surface — `/mcp` requires OAuth, `POST /api/v1/mcp/execute_tool` requires an
API key, and `POST /build/anon` requires signup before it builds. Generation
spends real credits, so nothing generates before an identity exists. The old
`POST /api/v1/anonymous_builds` build-now-claim-later lane is off and returns
`404`; do not call it.

What to do instead — hand them a **prefilled, unsent** homepage link:

```
https://www.overskill.com/?prompt=Build+a+coffee+shop+landing+page+with+hours+and+a+menu
```

The prompt arrives already typed into the homepage composer. They sign in (or
sign up), press build, and land in the editor watching their app assemble — in
their own team, on their own credits.

Then continue in Flow 0b to get authenticated so you can act on their behalf.

### Flow 0b: Get the user authenticated (API/MCP mode)

Flow 0 hands an account-less user a link they build from themselves. This flow
covers the next problem: you need an `os_` API key so you can use the rest of
this document, and the user is sitting in a chat window with you, not in a
browser.

**Read this section's honesty note first.** As of today there is **no
API-only path from "user has access to their email" to "agent holds an API
key."** Key creation requires an OAuth Bearer token or an existing
`full_access` key. Everything below is the best *currently working* path, and
each step states plainly whether it is fully automatable or needs the user to
touch a browser once.

#### Decision table — pick your path

| Your situation | Use | Browser needed? |
|---|---|---|
| User has no account at all | **Flow 0** (prefilled `/?prompt=` link — they build it) | Yes, to sign up and build |
| User has an account, you have no key | **Path A** below | Once, to copy the key |
| You are a registered OAuth client | **Path B** below | Once, to authorize |
| You already have a `full_access` key | `POST /api/v1/api_keys` directly | No |

---

#### Path A — Handoff link (recommended today)

The shortest reliable path. One message to the user, one paste back.

**Step 1 — Verify who they are (optional but useful).** The magic-code
endpoints work with no auth and let you confirm the email is real and
registered before you send them anywhere:

```bash
curl -X POST https://www.overskill.com/api/v1/auth/magic_code \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com"}'
```

```json
{ "success": true, "message": "Code sent to u***@example.com", "expires_in": 300 }
```

The user reads the 6-character code from their email and gives it to you:

```bash
curl -X POST https://www.overskill.com/api/v1/auth/verify_code \
  -H "Content-Type: application/json" \
  -d '{"email": "user@example.com", "code": "1r6bv-9axzx"}'
```

```json
{ "success": true, "user_id": 123, "email": "user@example.com",
  "redirect_path": "/account/teams/xyz123" }
```

You can also poll `GET /api/v1/auth/magic_code/status?email=...` to see
whether a code is still pending (`{"pending": true, "expires_in": 240}`).

> ⚠️ **This session cannot mint an API key.** `verify_code` establishes a
> browser-style session cookie, and `POST /api/v1/api_keys` rejects it —
> you will get `401 {"error": "OAuth token or full_access API key required
> to create API keys"}`. Do not build on this. The value of Step 1 is
> confirming the account exists and learning the user's team path.

**Step 2 — Send the user to the keys page.** Give them this link:

```
https://www.overskill.com/account/api_keys
```

That path redirects to their current workspace's key page
(`/account/teams/:team_id/api_keys`), so you do not need to know the team id.
If Step 1 returned a `redirect_path`, the team-scoped URL is
`https://www.overskill.com{redirect_path}/api_keys`.

Ask them to create a key and paste it back. Suggested wording:

> Open https://www.overskill.com/account/api_keys, click **New API Key**,
> name it something like "agent", choose scope **read_write**, and paste the
> `os_...` value back to me. It is shown only once.

**Step 3 — Verify the key before you use it.**

```bash
curl https://www.overskill.com/api/v1/capabilities \
  -H "X-API-Key: os_your_key_here"
```

A 200 confirms the key, and the response tells you the plan, limits, and
which operations are permitted. Call this **before** attempting a build so a
bad paste fails loudly and immediately.

**Step 4 — Confirm the team is the one they meant.** Keys are minted against
the user's *current* workspace, and there is currently no `team_id` parameter
on key creation. If the user belongs to more than one workspace, check that
the apps you see are the ones they expect:

```bash
curl https://www.overskill.com/api/v1/managed_apps \
  -H "X-API-Key: os_your_key_here"
```

If the list looks wrong, the key is scoped to the wrong workspace. The user
must switch workspaces in the dashboard and create a new key.

#### Scope guidance

| Scope | Use when |
|---|---|
| `read_only` | Monitoring, reporting, reading files and analytics |
| `read_write` | **Default for agents** — build, iterate, deploy, manage env vars |
| `full_access` | Only when you must create or revoke further API keys |

Ask for the narrowest scope that does the job. Do not ask for `full_access`
just to have it.

---

#### Path B — OAuth 2.0 authorization code + PKCE

If you are a registered OAuth client, this is the durable path and it yields
a Bearer token that **can** mint API keys.

1. Send the user to the authorize endpoint (they approve in a browser once):

```
https://www.overskill.com/oauth/authorize
  ?client_id=<your_client_id>
  &redirect_uri=<your_redirect_uri>
  &response_type=code
  &code_challenge=<S256 challenge>
  &code_challenge_method=S256
```

2. Exchange the returned `code` at `POST https://www.overskill.com/oauth/token`.
   Keep the `refresh_token` from that response.

3. The access token expires in 24 hours. Renew it yourself — no second browser
   visit — by POSTing to the same endpoint with `grant_type=refresh_token`,
   your `refresh_token` and your `client_id` (no client secret). Each refresh
   returns a **new** refresh token; store it and drop the old one, which stops
   working the moment it is used. A `400 invalid_grant` means start over at
   step 1.

4. Use the token directly, or trade it for a long-lived API key:

```bash
curl -X POST https://www.overskill.com/api/v1/api_keys \
  -H "Authorization: Bearer <access_token>" \
  -H "Content-Type: application/json" \
  -d '{"name": "agent key", "scope": "read_write"}'
```

```json
{ "api_key": "os_...", "team_id": "...", "user_id": "...", "plan": "..." }
```

Save `api_key` immediately — it is never shown again.

> **Client ID Metadata Documents (CIMD) are supported and preferred.**
> `/.well-known/oauth-authorization-server` publishes
> `"client_id_metadata_document_supported": true`: authorize with your
> published https metadata-document URL as `client_id` and we fetch it,
> verify it names itself, and match the `redirect_uris` it declares. There
> is nothing to register and no credential to store.
>
> Dynamic client registration is also live for public PKCE clients
> (`"registration_endpoint": "https://www.overskill.com/oauth/register"`,
> RFC 7591). Either way you get a **public PKCE** client and must send
> `code_challenge_method=S256`; if you ask to register as a confidential
> client we substitute a public one and say so in the response
> (`"token_endpoint_auth_method": "none"` — RFC 7591 §3.2.1), rather than
> refusing the registration. There is no self-serve UI for creating a
> confidential partner client — Path B for a hand-rolled confidential
> client still needs a provisioned `client_id`.

Canonical OAuth metadata:
`GET https://www.overskill.com/.well-known/oauth-authorization-server`

---

#### What does not work yet (do not waste calls on these)

- `POST /api/v1/api_keys` with a `verify_code` session cookie → **401**.
- `POST /api/v1/api_keys` with a `team_id` parameter → the parameter is
  **ignored**; the key is minted against the user's current workspace.
- Switching workspaces over the API → there is no `/api/v1` endpoint for it.
- OAuth 2.0 Device Authorization Grant (RFC 8628 — the "open this URL, type
  this code" flow that would make this whole section one automatable step) →
  **not enabled**. Only `authorization_code` is configured.

If you hit one of these, it is a platform gap, not a mistake on your side.
Fall back to Path A and tell the user plainly that they need one browser
step.

### Flow 1: Generate an app from scratch (single API call)

```bash
curl -X POST https://www.overskill.com/api/v1/generation_queue \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Build a task management app with kanban board, due dates, and team assignments",
    "name": "Task Manager"
  }'
```

Optional parameters: `name` (app display name), `callback_url` (webhook on completion), `ai_model`, `visibility`, `metadata` (custom keys passed through to callbacks).

**Response (202 Accepted):**
```json
{
  "job_id": "abc123",
  "app_id": "QjqEkj",
  "status": "queued",
  "estimated_time_seconds": 45,
  "status_url": "https://www.overskill.com/api/v1/generation_queue/abc123"
}
```

Then poll for completion:

```bash
curl https://www.overskill.com/api/v1/generation_queue/abc123 \
  -H "X-API-Key: os_your_key_here"
```

**Response when complete:**
```json
{
  "job_id": "abc123",
  "app_id": "QjqEkj",
  "status": "completed",
  "progress": 100,
  "message": "Your app is ready!",
  "app": {
    "id": "QjqEkj",
    "name": "Task Manager",
    "status": "generated",
    "preview_url": "https://preview-QjqEkj.overskill.app",
    "production_url": null
  }
}
```

> **Note on `progress` vs `message`:** The `progress` field uses coarse checkpoints (5 → 10 → 25 → 50 → 75 → 100) 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.
>
> **Prefer not to poll?** `GET /api/v1/generation_queue/:id/stream` serves the same status object as Server-Sent Events until the job completes, and `callback_url` (Flow 6) pushes a webhook on completion.

### Flow 2: Iterate on an existing app

```bash
curl -X POST https://www.overskill.com/api/v1/generation_queue \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "app_id": "QjqEkj",
    "prompt": "Add a dark mode toggle and a dashboard with charts showing tasks by status"
  }'
```

### Flow 3: Deploy to production

```bash
curl -X POST https://www.overskill.com/api/v1/managed_apps/QjqEkj/deploy \
  -H "X-API-Key: os_your_key_here"
```

**Response (202 Accepted):**
```json
{
  "deployment_id": 456,
  "status": "queued",
  "message": "Production deployment queued"
}
```

**Deploy is guarded.** A draft or un-built app (no `dist/` bundle) is refused with
**422** instead of being queued — so you never confidently ship a broken app:
```json
{
  "error": "App is not deployable",
  "reason": "No built files found (expected a dist/ bundle) — the app must be built before it can deploy.",
  "recoverable": true,
  "suggested_action": "Build the app (generate content or run a preview build so a dist/ bundle exists), then retry POST /api/v1/managed_apps/QjqEkj/deploy.",
  "fix_url": "https://www.overskill.com/account/apps/QjqEkj/edit"
}
```
On a 422, generate/build the app (e.g. `POST /api/v1/generation_queue`) until a
`dist/` bundle exists, then retry the deploy.

### Flow 4: Get actionable build errors (self-heal)

After a deploy that fails to build, fetch a structured, agent-actionable error
list instead of retrying blind:

```bash
curl https://www.overskill.com/api/v1/managed_apps/QjqEkj/errors \
  -H "X-API-Key: os_your_key_here"
```

**Response (clean app):**
```json
{ "recoverable": true, "errors": [] }
```

**Response (build error recorded):**
```json
{
  "recoverable": true,
  "errors": [
    {
      "message": "Cannot resolve module 'fs'",
      "error_type": "build_error",
      "file": "src/lib/storage.ts",
      "suggested_action": "A module import can't be resolved. Add the missing dependency or fix the import path (PATCH /api/v1/managed_apps/QjqEkj or the files API), then redeploy.",
      "fix_url": "https://www.overskill.com/account/apps/QjqEkj/edit",
      "recoverable": true,
      "occurred_at": "2026-06-08T12:00:00Z"
    }
  ]
}
```

Use `suggested_action` to fix the offending file (via the files API), then deploy again.

### Flow 5: Get source files

```bash
curl https://www.overskill.com/api/v1/managed_apps/QjqEkj/files \
  -H "X-API-Key: os_your_key_here"
```

**Response:**
```json
{
  "app_id": "QjqEkj",
  "files": [
    {
      "path": "src/App.tsx",
      "content": "import React from 'react'...",
      "size": 1234,
      "updated_at": "2026-02-18T12:00:00Z"
    }
  ],
  "count": 24
}
```

Filter by path: `?path=src/pages` to get only files matching that path.

### Flow 5b: Read the app's own manifest (`AGENTS.md`)

Every app carries a generated **`AGENTS.md` at its repo root** — the agent
entry point for operating that specific app. It's synthesized from the app's
live configuration and kept current on every deploy and config change, so it
never drifts from what's actually running. Read it first when you clone or
export a repo, or fetch it via the files API:

```bash
curl "https://www.overskill.com/api/v1/managed_apps/QjqEkj/files?path=AGENTS.md" \
  -H "X-API-Key: os_your_key_here"
```

`AGENTS.md` documents, for that one app: its ID and live URLs, the exact deploy
loop (the deploy / status / errors endpoints above), environment variable
**keys** (names only — never secret values), connected integrations, OAuth
providers, custom domains, custom endpoints, scheduled tasks, and its data
model. It only lists capabilities that are actually enabled for the app, so you
won't chase an endpoint that isn't turned on. Two companion files sit beside it:
`CLAUDE.md` (a pointer to `AGENTS.md`) and `SKILL.md` (the same deploy loop as an
operator skill). All three ship with the GitHub export, so a cloned repo is
self-describing — an agent can read `AGENTS.md` and operate the app with no other
context.

> Per-app manifests roll out behind a flag. If an app's repo doesn't yet include
> `AGENTS.md`, use the deploy loop in this document directly — it's identical.

### Flow 6: Webhooks for async callbacks

Instead of polling, pass a `callback_url` when queuing generation:

```bash
curl -X POST https://www.overskill.com/api/v1/generation_queue \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Build a CRM with contact management",
    "callback_url": "https://your-server.com/webhooks/overskill",
    "metadata": {
      "your_user_id": "user_123",
      "your_project_id": "proj_456"
    }
  }'
```

When generation completes, Overskill POSTs to your callback URL:

```json
{
  "event": "app.generation.completed",
  "app_id": "QjqEkj",
  "app_name": "CRM App",
  "status": "generated",
  "urls": {
    "preview": "https://preview-QjqEkj.overskill.app",
    "production": null,
    "editor": "https://www.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_user_id": "user_123",
    "your_project_id": "proj_456"
  }
}
```

> **Note:** `credits_used` and `tokens_used` are only included when generation metrics are available. Your custom `metadata` keys are passed through; internal keys like `api_key_id` may also appear.

**Callback signatures — two different schemes** (don't mix them up):

- **Registered webhooks** (subscriptions created via `POST /api/v1/webhooks`,
  where you supply your own `secret`) are signed
  `X-Overskill-Signature: t=<unix_ts>,v1=<hex_digest>` with
  `HMAC-SHA256(your_secret, "<timestamp>.<raw_body>")`, plus an
  `X-Overskill-Timestamp` header. Verify by recomputing the digest and
  comparing `v1`.
- **`callback_url` deliveries** (this flow) carry
  `X-OverSkill-Signature: sha256=<hex_digest>` signed with a
  platform-held key — there is currently no per-caller secret, so you
  cannot verify these cryptographically. Treat callback payloads as an
  untrusted hint: on receipt, confirm the state with
  `GET /api/v1/generation_queue/:id` before acting.

### Webhook Events

| Event | When |
|-------|------|
| `app.created` | New app created |
| `app.updated` | App settings changed |
| `app.deleted` | App deleted |
| `app.generation.started` | Generation began |
| `app.generation.completed` | Generation succeeded |
| `app.generation.failed` | Generation failed |
| `app.generation.progress` | Generation progress update |
| `app.deployment.started` | Deployment initiated |
| `app.deployment.completed` | Deployment succeeded |

### Flow 7: Update app settings

```bash
curl -X PATCH https://www.overskill.com/api/v1/managed_apps/QjqEkj \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Updated App Name",
    "visibility": "login_required"
  }'
```

Updatable fields: `name`, `description`, `visibility`, `ai_model`.

### Flow 8: Delete an app

```bash
curl -X DELETE https://www.overskill.com/api/v1/managed_apps/QjqEkj \
  -H "X-API-Key: os_your_key_here"
```

**Response:** `{ "success": true, "message": "App deleted" }`

> **Caution:** This permanently deletes the app and all its files, versions, and data. Always confirm with the user before deleting.

---

## App Visibility

Control who can access your app by setting `visibility` when creating or updating:

| Value | Behavior |
|-------|----------|
| `"public"` | Anyone can access — no login required (default) |
| `"login_required"` | Users must log in with Overskill before accessing |

> **Preview URL behavior:** When an app is set to `login_required`, visiting the preview URL will show an Overskill login page. Users must authenticate before they can see the app. This applies to both preview and production URLs.

Set visibility on creation:
```bash
curl -X POST https://www.overskill.com/api/v1/generation_queue \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "prompt": "Build an internal team dashboard",
    "name": "Team Dashboard",
    "visibility": "login_required"
  }'
```

Or update an existing app:
```bash
curl -X PATCH https://www.overskill.com/api/v1/managed_apps/QjqEkj \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "visibility": "public" }'
```

---

## Environment Variables

Manage per-app environment variables and secrets. Secret values are write-only — they are never returned after creation.

```bash
# List env vars (secret values hidden)
curl https://www.overskill.com/api/v1/managed_apps/QjqEkj/env_vars \
  -H "X-API-Key: os_your_key_here"

# Set an env var
curl -X POST https://www.overskill.com/api/v1/managed_apps/QjqEkj/env_vars \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "key": "STRIPE_KEY", "value": "sk_live_...", "secret": true }'

# Update an env var
curl -X PATCH https://www.overskill.com/api/v1/managed_apps/QjqEkj/env_vars/ENV_VAR_ID \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "value": "new_value" }'

# Delete an env var
curl -X DELETE https://www.overskill.com/api/v1/managed_apps/QjqEkj/env_vars/ENV_VAR_ID \
  -H "X-API-Key: os_your_key_here"
```

Apps can read their own env vars at runtime via `import.meta.env.VITE_KEY` (for VITE_ prefixed vars) or server-side via `env.KEY` in API endpoint handlers.

---

## Usage & Credits

```bash
curl https://www.overskill.com/api/v1/usage \
  -H "X-API-Key: os_your_key_here"
```

**Response:**
```json
{
  "team_id": 258,
  "period": "30d",
  "credits": {
    "balance": 1500,
    "used_in_period": 350,
    "added_in_period": 500,
    "breakdown": {
      "generation": 340,
      "deployment": 0,
      "integration": 10,
      "workflow": 0,
      "storage": 0
    }
  },
  "generations": {
    "total": 42,
    "apps_created": 8,
    "apps_deployed": 3
  },
  "api_key": {
    "key_name": "My Integration",
    "key_prefix": "os_abc123def",
    "total_requests": 120,
    "last_used_at": "2026-07-09T20:54:34Z"
  },
  "subscription": {
    "tier": "pro",
    "credit_tier": "tier_500"
  },
  "next_steps": []
}
```

---

## Custom Domains

Apps are available at `{id}.overskill.app` by default. You can also serve them from your own domain (e.g., `app.yourdomain.com`).

### Add a custom domain via API

```bash
curl -X POST https://www.overskill.com/api/v1/managed_apps/QjqEkj/custom_domains \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "domain": "app.yourdomain.com" }'
```

**Response (201 Created):**
```json
{
  "custom_domain": {
    "id": 123,
    "domain": "app.yourdomain.com",
    "url": "https://app.yourdomain.com",
    "verification_status": "pending",
    "ssl_status": "pending",
    "operational": false
  },
  "dns_records": {
    "type": "CNAME",
    "name": "app",
    "value": "proxy.overskill.app",
    "ttl": 300
  },
  "cname_target": "proxy.overskill.app"
}
```

After adding, configure DNS at your registrar, then poll status:

```bash
# Check DNS/SSL status
curl -X POST https://www.overskill.com/api/v1/managed_apps/QjqEkj/custom_domains/123/check_status \
  -H "X-API-Key: os_your_key_here"
```

Status flow: `pending` → `verified` (DNS confirmed) → `active` (SSL provisioned). SSL certificates are provisioned automatically via Cloudflare.

### All custom domain endpoints

| Action | Endpoint |
|--------|----------|
| List domains | `GET /api/v1/managed_apps/:id/custom_domains` |
| Add domain | `POST /api/v1/managed_apps/:id/custom_domains` |
| Get domain details | `GET /api/v1/managed_apps/:id/custom_domains/:domain_id` |
| Remove domain | `DELETE /api/v1/managed_apps/:id/custom_domains/:domain_id` |
| Set primary domain | `POST .../custom_domains/:domain_id/set_primary` |
| Check DNS/SSL status | `POST .../custom_domains/:domain_id/check_status` |
| Refresh verification | `POST .../custom_domains/:domain_id/refresh` |

> **Plan limits:** custom domains are plan-gated — free: 0, pro: 1 per app, team: 5 per app, enterprise: unlimited. `GET /api/v1/capabilities` reports your `custom_domains_per_app` limit, and the domains list response includes `can_add_more`.
>
> **Dashboard alternative:** You can also manage domains in the app editor at **Settings > Publish > Custom Domain**. For apex domains and automatic DNS setup via Entri, see [`llms-full.txt`](https://www.overskill.com/llms-full.txt).

---

## Rate Limits

Recommended client-side limits to avoid overwhelming the API:

| Operation | Recommended Limit | Window |
|-----------|-------------------|--------|
| Generation (POST generation_queue) | 20 | per hour |
| API reads (GET) | 300 | per minute |
| API writes (POST/PATCH/DELETE) | 60 | per minute |
| Deployments | 10 | per hour |

> **Note:** Server-side rate limiting is being rolled out progressively. Plan your integration with the limits above for forward compatibility.

---

## Error Responses

All errors return JSON:

```json
{
  "error": "Resource not found",
  "message": "The requested resource could not be found"
}
```

| Status | Meaning |
|--------|---------|
| 400 | Bad request — invalid parameters |
| 401 | Unauthorized — missing or invalid API key |
| 403 | Forbidden — insufficient permissions |
| 404 | Not found |
| 422 | Validation failed |
| 429 | Rate limit exceeded |
| 500 | Server error |

---

## MCP Tools

Two surfaces. **Hosted MCP** (`https://mcp.overskill.com/mcp`) is the
JSON-RPC / Streamable HTTP endpoint MCP hosts speak. Sign-in is OAuth
(DCR at `https://www.overskill.com/oauth/register`). **REST MCP**
(`POST /api/v1/mcp/execute_tool`) is an API-key JSON POST — not the MCP
wire protocol — and is the only surface with file and entity tools.

### Hosted `/mcp` (OAuth)

Connect URL: `https://mcp.overskill.com/mcp`. Per-host add flow (Grok Bot,
OpenClaw, Hermes Agent, Cursor, Claude, ChatGPT, any MCP host):
https://www.overskill.com/connect. A persistent or self-hosted bot needs a
public HTTPS Streamable HTTP server with OAuth sign-in, which this is. Tools:

| Tool | Description |
|------|-------------|
| `create_app` | Build a full-stack app from a prompt. Optional `name`, `model`, `thinking_level`, `attachment`. |
| `create_landing_page` | Single-page marketing site. Same optional `name`. |
| `create_presentation` | Slide deck as a web page. Same optional `name`. |
| `create_internal_tool` | Dashboard / admin / team utility. Same optional `name`. |
| `update_app` | Follow-up prompt on an existing `build_id`. |
| `list_apps` | Team apps, newest first. Optional `query`, `limit` (1–50), `cursor` (from `next_cursor`). |
| `get_app` | One app's details. |
| `get_build` | Poll a build. `elapsed_seconds` is the current turn. Ready payload includes `screenshot_url`, `generation.ready`, and `files` (`name` + `mtime`). |
| `publish_app` | Publish to the live production URL (confirm with the user first). |
| `list_generation_models` | Models and thinking levels this account can use. |
| `render_build_widget` | Build-progress card in hosts that render MCP app UI. |
| `get_balance` | The team's account balance, its effective plan, and the named packs that add to it. Read-only. |
| `fetch_credit_purchase_link` | A URL the person opens themselves to add to that balance. Pass a `pack_id` from `get_balance`, plus `idempotency_key` on retries. Returns `requires_human: true` — hand over the URL and stop; nothing is charged and no agent can complete it. |
| `add_auth` | Choose who can open an app: `access` = `signed_in`, `email_domain` (with `allowed_email_domains`) or `anyone`. Sign-in is built into every app, so nothing is generated. Returns `sign_in_url`, `takes_effect` (`live_now` / `on_next_publish` / `on_first_publish`) and `anonymously_readable_tables` — tables whose rows stay readable without signing in; tell the user. Confirm first. |
| `connect_integration` | Look up one catalog integration by `slug` (slack, google-sheets, hubspot, …) and whether this team has it connected. When not, returns `connect_url` for the person to open (`requires_human: true`) — call again to confirm. Then ask `update_app` to use it. |
| `submit_feedback` | Report friction with a tool (`tool_name`, `category`: `confusing_schema` \| `missing_capability` \| `wrong_result` \| `error` \| `docs_gap`, `description`, optional excerpts). Returns `received` + `feedback_id` at once. Never include secrets or personal data. |

Pass `name` when the user already named the app, or put `App name: …` on
its own first line of `prompt`. Poll `get_build` until `status` is `ready`.

### REST `/api/v1/mcp/execute_tool` (API key)

```bash
# List available REST tools
curl https://www.overskill.com/api/v1/mcp/tools \
  -H "X-API-Key: os_your_key_here"

# Generate a new app (no app_id needed)
curl -X POST https://www.overskill.com/api/v1/mcp/execute_tool \
  -H "X-API-Key: os_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "tool": "overskill-generate-app",
    "params": { "name": "My App", "prompt": "Build a todo list app" }
  }'
```

**REST tools** (not exposed on hosted `/mcp`):

| Tool | Category | Description |
|------|----------|-------------|
| `overskill-generate-app` | apps | Create and generate an app from a prompt (no app_id needed) |
| `overskill-submit-feedback` | feedback | Report friction with a tool: `tool_name`, `category`, `description`, optional `input_excerpt` / `output_excerpt` (no app_id needed) |
| `overskill-view-file` | files | View file contents (requires app_id) |
| `overskill-write-file` | files | Create or update a file |
| `overskill-list-files` | files | List files matching a pattern |
| `overskill-delete-file` | files | Delete a file |
| `overskill-create-entity` | entities | Create a new entity (database table) |
| `overskill-query-data` | entities | Query entity data |
| `overskill-insert-data` | entities | Insert a record |
| `overskill-update-data` | entities | Update a record |
| `overskill-delete-data` | entities | Delete a record |

---

## Tips for Agents

- **Poll every 3 seconds** after queuing generation — apps take 30-60 seconds to build. Use the `message` field (not `progress`) for real-time status text.
- **Use `callback_url`** instead of polling when possible — it's more efficient and reliable.
- **Cancel stuck generations** — use `DELETE /api/v1/generation_queue/:id` to cancel.
- **Use descriptive prompts** — include the app type, key features, UI style, and specific requirements.
- **Iterate with follow-up prompts** — send `app_id` + new `prompt` to add features to existing apps.
- **Check `status` before deploying** — only deploy apps with status `generated` or `published`.
- **Don't guess IDs** — list apps first with `GET /managed_apps`, then use actual IDs.
- **Pass `metadata`** in generation requests — custom keys flow through to callback payloads.
- **Ask before destructive actions** — confirm with the user before deleting apps or deploying to production.
- **Visibility options** — set via `visibility` param: `"public"` (default, no login) or `"login_required"` (must log in). See [App Visibility](#app-visibility) above.

---

## Links

| Resource | URL |
|----------|-----|
| Overskill | https://www.overskill.com |
| Dashboard | https://www.overskill.com/account |
| API Documentation | https://www.overskill.com/developers |
| Full docs (for agents) | https://www.overskill.com/llms-full.txt |
| Webhook docs | https://www.overskill.com/developers/webhooks |
| Zapier integration | https://www.overskill.com/developers/zapier |
| Skill install page | https://www.overskill.com/developers/skill |

END SKILL v0.3.0
