Skip to main content
A skill is a reusable, versioned instruction module — a SKILL.md document — that agents load on demand. Skills are org-scoped and immutable per version: each push creates a new version identified by its content hash.

The skill object

string
Unique id (e.g. skl_01H...).
string
Unique, human-readable name within the org (e.g. refund-policy).
string | null
Short description of what the skill does.
integer
The highest version number.
string
Creation timestamp.

The skill version object

string
The skill this version belongs to (skl_…).
string
The skill’s slug.
integer
Monotonic version number.
string
SHA-256 of the SKILL.md content. Verifies integrity.
integer
Content size.
string
When this version was pushed.

Create a skill

POST /v1/skills → 201 Created for a new slug, 200 OK when the slug already exists (the push is applied as a new version of it). A skill is never created empty: the create is the first push. Both responses are the skill version object.
string
required
The SKILL.md text. Version 1 of a new slug.
string
Unique slug within the org — lowercase letters, digits and dashes. Required unless you send name.
string
The same thing spelled name. Send one of slug or name.
string
Short description. Defaults to null.
string
SHA-256 hex digest of content. Optional: the server hashes the bytes itself and refuses a digest that does not match.

Retrieve & list

See Pagination.

Push a new version

POST /v1/skills/{id}/versions uploads a new SKILL.md. The body is the document text, optionally with its sha256; the server rejects the request with validation_failed if the hash does not match the content. Pushing bytes identical to the current version mints nothing and answers 200.
string
required
The full SKILL.md text.
string
SHA-256 hex digest of content. Optional: the server hashes the bytes itself and refuses a digest that does not match.
string
Replace the skill’s description as part of this push.
Response

List versions

GET /v1/skills/{id}/versions returns version history, newest first. Cursor-paginated.
Response

Retrieve one version

GET /v1/skills/{id}/versions/{n} — scope agents:read. Returns that immutable version’s metadata with its body: the skill version object plus a content string carrying the raw SKILL.md. This is the second half of progressive disclosure. The list above carries only version, sha256, size_bytes, and created_at; the text itself costs this extra call, so a runtime pays for it once when the skill is actually used rather than on every turn.
{id} accepts a slug or an id, and {n} is the integer version. not_found (404) if either does not resolve.

Delete a skill

DELETE /v1/skills/{id} — scope agents:write. Removes the skill and its whole version history.
Agents referencing the slug — pinned (refund-policy@3) or floating (refund-policy) — fail to resolve it at session start once it is gone. Check what depends on a skill before deleting it.
Response

Pin a version

An agent’s skills[] accepts two reference forms: The naive/ prefix is the whole difference: a bare slug is always one of your skills, a prefixed one is always the platform’s, and your landing-page-copy and the platform’s never collide. Either kind that cannot be resolved fails the agent write with 404 not_found, param: "skills". Skill versions are content-addressed and immutable, so pushing a new SKILL.md never silently changes an already-pinned agent. Use GET /v1/skills/{id}/versions to find the numbers you can pin.
Attach a skill to an agent by slug or id. An unpinned reference (refund-policy) resolves to the latest version at session start; a pinned one (refund-policy@3) is frozen.

The platform catalogue

The platform publishes a small catalogue of skills — landing-page copy, client onboarding, SEO briefs, clip selection and the like — that any agent can reference as naive/<slug>. It is read-only from the API: versions are published with a platform release, and like your own skills they are content-addressed, so a published version never changes.
All three accept any authenticated caller — an API key with any scope, or a signed-in session that does not yet belong to an organization — because a catalogue is something to browse before there is anything to attach it to.

The skill catalogue entry object

string
required
skill_catalog_entry
string
required
The handle you reference as naive/<slug>.
integer
required
The version described; the number to pin.
string
required
Display name.
string
required
One line on what the skill is for.
string[]
required
Families the skill belongs to, e.g. agency, seo, media.
string
required
SHA-256 of content, lowercase hex.
string
required
When this version was published.
string
The raw SKILL.md. Only on the version read; the list never carries it.

List the catalogue

GET /v1/skills/catalog — the newest version of every slug, alphabetical, cursor-paginated (the cursor is a slug). ?tag= narrows to one family and ?search= is free text over slug, name and description; the two compose.
Response

Resolve one naive/<slug>

GET /v1/skills/catalog/{slug} — the newest version of that slug, without content. This is the route that answers “does naive/short-video-hooks exist, and at what version?” — GET /v1/skills/{ref} is your skills and answers 404 for a naive/ name, which is not the same claim. A slug nothing published answers 404 not_found, param: "slug".

Read a catalogue version

GET /v1/skills/catalog/{slug}/versions/{n} — the entry with content. An unknown slug or version answers 404 not_found, param: "slug".