# POST /skills

**Resource:** [Skills](./skills.md)  
**MCP tool:** `create_skill`  
**Scopes:** `agent-ops:write`  
**Write operation:** yes

Create a skill owned by your workspace. A skill is one tool_loop: a model, a system prompt, an allowed tool set, and an input/output contract. Set visibility "public" to make it usable by every workspace (only you can still edit it).

## Parameters

| Name | In | Type | Required | Description |
|------|----|------|----------|-------------|
| `name` | body | string | yes | Stable handle used to run it, e.g. "curate_memory". Unique per owner; unique globally when public. |
| `display_name` | body | string | yes |  |
| `description` | body | string | no |  |
| `when_to_use` | body | string | yes | When an agent should reach for this skill. This IS the tool description the agent reads to decide whether to invoke it (agent-invocation skills are compiled into its tool catalog and picked by this text). |
| `visibility` | body | string | no | Default "private". |
| `invocation` | body | string | no | Default "agent" (the agent chooses it as a callable tool, selected by when_to_use). "lifecycle" = always-on: fires on an event (e.g. after a chat turn), never chosen, and NOT exposed as a tool. |
| `execution` | body | string | no | How it runs. Default "tool_loop" (a general agentic loop). "briefing" fetches every allowlisted read once, in parallel, with the input, then does one grounded summarize call — fast, for gather-then-summarize skills. |
| `model` | body | string | yes | The Cloudflare Workers AI model the loop runs on, as a '@cf/...' model id (e.g. '@cf/qwen/qwen3-30b-a3b-fp8', the default). Claude/Anthropic models are not supported. |
| `system_prompt` | body | string | yes | The skill's instructions. |
| `tool_allowlist` | body | array | no | Tool names the loop may call (e.g. search_memory, write_memory). |
| `input_schema` | body | object | no | JSON Schema for the skill's input. |
| `output_schema` | body | object | no | JSON Schema for the skill's output. |
| `status` | body | string | no |  |
| `require_approval` | body | boolean | no | Optional. Set true to route this write into the approval queue for human review instead of executing it immediately (returns 202 + an approval_id). Works even when your key/token has permission to execute directly. |

## Request example

```bash
curl -X POST   "https://api.trustpager.com/functions/v1/api/v1/skills"   -H "Authorization: Bearer YOUR_API_KEY"   -H "Content-Type: application/json"   -d '{"name":"...","display_name":"...","description":"..."}'
```

---
Base URL: `https://api.trustpager.com/functions/v1/api/v1` — Auth: `Authorization: Bearer YOUR_API_KEY`