# Skills

> The Skills operations of the Hub REST API (7 operations).

URL: https://docs.synap.live/docs/reference/hub-api/skills · Generated from Synap-core/backend@c31e261ab (main)

Paths are relative to `/api/hub` on a pod.

## GET /skills/system

List system skill packages

Returns static SKILL.md documentation for the built-in skill packages listed in skills/manifest.json (baseline + workflow). Called by ensureEveSkillsLayout() to populate ~/.eve/skills/ for Claude Code and other text-based agents. Requires hub-protocol.read scope.

Responses:

- `200`: Array of skill packages with file contents
- `403`: Forbidden
- `503`: skills/ directory missing on disk — broken deployment (image didn't COPY skills/)

## GET /briefs

Composed just-in-time teaching briefs for MCP tool names or action verbIds

Returns a composed teaching brief per requested name — teaching core (seeded system skills), a live governance verdict (auto/propose), and per-kind posture emphases. A name may be an MCP `synap_*` tool or a runnable-action `verbId` from GET /capabilities/actions: a verbId resolves its teaching through the MCP tools that teach it and, with `workspaceId`, states its run posture (runs now / files a review). Names with no brief content are omitted. Requires hub-protocol.read scope.

Parameters:

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `tools` | query | string | yes | Comma-separated tool names |
| `workspaceId` | query | string |  |  |
| `door` | query | "chat" \| "automation" |  |  |

Responses:

- `200`: Composed briefs
- `400`: Bad request
- `403`: Forbidden

## GET /skills

List skills

Lists skills visible to the caller across the three-tier scope (pod ∪ user-owned ∪ workspace). Requires hub-protocol.read scope.

Parameters:

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `workspaceId` | query | string |  |  |
| `kind` | query | "instruction" \| "code" \| "declarative" \| "builtin" |  |  |
| `scope` | query | "pod" \| "user" \| "workspace" |  |  |
| `status` | query | "active" \| "inactive" \| "error" \| "all" |  |  |
| `limit` | query | string |  |  |

Responses:

- `200`: Skill list
- `403`: Forbidden
- `500`: Internal error

## POST /skills

Create a skill (capability substrate)

Seeds a `skills` row — AI know-how. Documentation (`body`) + OPTIONAL executable (`code`); `kind` is DERIVED from code presence, so prose-only is an 'instruction' skill and needs a `slug` (the ref load_skill resolves). kind='instruction' injects into the agent prompt; kind='code' is sandbox-executed. Proposal-gated: returns status='proposed' with a proposalId when governance requires review. Optional `requires` writes `skill → requires → tool` links. Requires hub-protocol.write scope.

Request body (`application/json`): object

| Field | Type | Required | Description |
|---|---|---|---|
| `name` | string | yes |  |
| `kind` | "instruction" \| "code" \| "declarative" \| "builtin" |  |  |
| `scope` | "pod" \| "user" \| "workspace" |  |  |
| `agentTypes` | array<string> |  |  |
| `description` | string |  |  |
| `code` | string |  |  |
| `body` | string |  |  |
| `slug` | string |  |  |
| `parameters` | object |  |  |
| `category` | string |  |  |
| `executionMode` | "sync" \| "async" |  |  |
| `timeoutSeconds` | number |  |  |
| `requires` | array<string> |  |  |
| `workspaceId` | string |  |  |

Responses:

- `200`: Created or proposed skill
- `400`: Bad request
- `403`: Forbidden
- `500`: Internal error

## POST /skills/{id}/approve

Approve or revoke a skill's execution

Sets the `approved` flag on a skill — the draft→approve→run gate. Owner-gated (workspace owner, or pod-admin for pod-wide skills) via the governed skillsRouter.setApproved. Requires hub-protocol.write scope.

Parameters:

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes |  |

Request body (`application/json`): object

| Field | Type | Required | Description |
|---|---|---|---|
| `approved` | boolean |  |  |

Responses:

- `200`: Updated approval state
- `400`: Bad request
- `403`: Forbidden
- `404`: Not found
- `500`: Internal error

## POST /skills/{id}/dry-run

Dry-run (preview) a skill to any level

Executes a skill with external writes/sends STUBBED and reads kept real, returning the side effects it intended to perform — a safe preview before approval. Proxies to the Intelligence Service dry-run executor (it owns the sandbox); the acting identity is server-derived. Requires hub-protocol.write scope.

Parameters:

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes |  |

Request body (`application/json`): object

| Field | Type | Required | Description |
|---|---|---|---|
| `parameters` | object |  |  |

Responses:

- `200`: Dry-run result + intended side effects
- `400`: Bad request
- `403`: Forbidden
- `404`: Not found
- `500`: Internal error
- `503`: Intelligence Service unavailable

## DELETE /skills/{id}

Delete a skill (capability substrate)

Deletes a `skills` row. Proposal-gated: returns status='proposed' with a proposalId when governance requires review (AI-initiated deletes propose, human deletes execute). Requires hub-protocol.write scope.

Parameters:

| Name | In | Type | Required | Description |
|---|---|---|---|---|
| `id` | path | string | yes |  |

Responses:

- `200`: Deleted or proposed
- `400`: Bad request
- `403`: Forbidden
- `404`: Not found
- `500`: Internal error
