---
title: "Create Skill Route"
method: POST
path: "/skills"
---

# Create Skill Route

`POST /skills`

## Request

- Base URL: `https://api.goodeye.dev/v1`
- URL: `https://api.goodeye.dev/v1/skills`
- Auth: none declared

## Request body

- SaveWorkflowInput: Publish-skill payload aligned with the Claude Code skills convention. Required top-level fields mirror a Claude Code ``SKILL.md`` frontmatter: ``name`` (kebab-case handle) and ``description`` (one-sentence summary). ``outcome`` and ``tags`` are top-level discovery facets surfaced by ``list_skills``; everything else lives in the ``body`` and is opaque to the registry. Skills are always private to the caller. Public sharing is the ``templates`` surface (``publish_template_version`` / ``fork_template``); there is no ``visibility`` knob on a skill row. Unknown fields are silently dropped (``extra="ignore"``). Fields such as ``manifest``, ``visibility``, and ``kpi`` do not cause validation errors and are simply ignored. The server accepts both ``slug`` and ``name`` as input for the skill handle. Responses return both ``name`` and ``slug`` fields with identical values.
  - `name` string, required: Skill name in kebab-case (lowercase letters, digits, and hyphens). Doubles as the slug and is unique within your namespace.
  - `skill_id` string, uuid, nullable: Target a specific skill to edit. Omit it to save in your own namespace: the call updates your own skill of this name, or creates a new one. Supply it to update a specific skill you own or have edit access to; ``name`` must match that skill's name.
  - `description` string, required: One-sentence summary of what the skill does and when to use it. This is the text that decides when the skill fires.
  - `body` string, required: The skill runbook as markdown: the full set of instructions an agent follows on the user's behalf.
  - `tags` string[]: Discovery tags surfaced when listing and searching skills. When omitted on an update, the existing tags are preserved; send an empty list to clear them.
  - `outcome` string, nullable: The business outcome this skill is meant to drive, surfaced as a discovery facet. When omitted on an update, the existing outcome is preserved; send null to clear it.
  - `verifiers` object[], nullable: Semantic verifier references this skill invokes on agent output. Each entry names a deployed verifier by id or id@version. When omitted on an update, the existing list is preserved unchanged.
  - `image_generators` object[], nullable: Image generator references for this skill. Each entry binds a local name (used in generation steps) to a generator reference. The reference is either a platform-managed quality tier (``system:<tier>``) or a specific deployed generator (``uuid`` or ``uuid@version``). When omitted on an update, the existing list is preserved unchanged.
  - `files` FileEntry[], nullable: Sibling files bundled with the skill. Include a 'demo/README.md' writeup with images referenced by relative path inside 'demo/' to render a visual demo on the public template page once the skill is published as a template. A supplied list is a full snapshot: any path you do not include is deleted. Omitting the field entirely preserves the existing tree unchanged; to change specific files without resending the rest, use `update_skill_files` instead.
    - `path` string, required: Normalized relative POSIX path for this file within the bundle (e.g. 'references/rubric.md'). Must not be empty, absolute, contain '..' or '.' segments, empty segments (a trailing slash or 'foo//bar'), backslashes, or ASCII control characters.
    - `executable` boolean: Whether the file should be marked executable when extracted.
    - `purpose` string, nullable: Short label describing the file's role in the skill (optional).
    - `content` string, nullable: Inline file content as a UTF-8 text string, stored verbatim. Use 'content_base64' for binary files. Mutually exclusive with 'content_base64' and 'sha256'.
    - `content_base64` string, nullable: Inline binary file content as base64-encoded bytes, decoded on receipt. Mutually exclusive with 'content' and 'sha256'.
    - `sha256` string, nullable: Hex SHA-256 digest referencing a blob already known to the registry. Mutually exclusive with 'content' and 'content_base64'.
  - `expected_version_token` string, uuid, nullable, required: Concurrency token from the latest known version, required when editing an existing skill so a stale overwrite is rejected. Omit when creating a new skill.
  - `source` 'manual' | 'teach' | 'optimization' | 'description_optimization' | 'audit', nullable: Attributes the saved version to how it was produced ('manual', 'teach', 'optimization', 'description_optimization', or 'audit'); omit to leave it unset.

## Response `201`

Successful Response

- object

## Other responses

- `422`: Validation Error

---

[API](https://skmtc.dev/goodeye/apis/goodeye-api.md) · [All operations](https://skmtc.dev/goodeye/apis/goodeye-api/llms.txt) · [OpenAPI document](https://skmtc.dev/goodeye/apis/goodeye-api/revisions/547cb8bb6ede?raw)
