Skills over HTTP
List a project's skills, save a skill bundle as a draft, publish it as the next version, download it, and archive it with /v1/skills.
A skill is a folder with a SKILL.md and the scripts and references it needs, kept in a project so every agent on it can install the same version (see Skills). /v1/skills stores a skill as a bundle: you save a draft, then publish it as the next version. Most people use the CLI, which builds the bundle for you; see Skills from the CLI.
Every request names the project by its slug: project in the JSON body of a POST, or ?project= on a GET or DELETE.
List the skills
curl -H "Authorization: Bearer $KEY" "$SITE/v1/skills?project=web"
# → { "skills": [ { "_id": "…", "name": "release-notes", "version": 3, "draftRevision": 7, "fileCount": 4, "totalSize": 18342, "updatedAt": 1756… } ] }version is the latest published version (0 if none yet). draftRevision goes up by one with every save and every publish. You need both to write. Archived skills are left out.
Read one skill
curl -H "Authorization: Bearer $KEY" "$SITE/v1/skills?project=web&name=release-notes"
curl -H "Authorization: Bearer $KEY" "$SITE/v1/skills?project=web&name=release-notes&version=2"
curl -H "Authorization: Bearer $KEY" "$SITE/v1/skills?project=web&name=release-notes&download=1" -o release-notes.jsonThe first answers with the skill, every published version with its downloadUrl, the current draft's draftUrl, and the latest version's downloadUrl. version picks an older version. download=1 answers with the bundle itself, as JSON.
The bundle
{
"schemaVersion": 1,
"name": "release-notes",
"hash": "<sha-256 of the manifest>",
"files": [
{ "path": "SKILL.md", "contentBase64": "…", "sha256": "…", "size": 1204, "executable": false },
{ "path": "scripts/collect.sh", "contentBase64": "…", "sha256": "…", "size": 812, "executable": true }
]
}nameis lowercase letters, digits and hyphens, up to 64 characters.filesholds 1 to 1,000 files, and one of them isSKILL.mdat the root. Each file is at most 5 MB, the whole bundle at most 20 MB.sha256is the hex SHA-256 of the file's bytes, andsizetheir length.pathis relative, with/between folders: no leading/, no.or.., no backslashes. Two paths can't differ only by case.hashis the hex SHA-256 of a JSON array with one[path, sha256, size, executable]entry per file, sorted by path.
sfora checks every hash and size, stores the bytes exactly, keeps the executable flags, and never runs a skill's files.
Save a draft
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" --data-binary @draft.json $SITE/v1/skills{ "project": "web", "bundle": { "schemaVersion": 1, "name": "release-notes", … }, "expectedVersion": 3, "expectedRevision": 7 }expectedVersion is the version you read (0 for a new skill). For a skill that already exists, expectedRevision is the draftRevision you read. If the skill changed since then, nothing is saved and you get 409. The answer is the skill, with its new draftRevision.
Publish a skill
curl -X POST -H "Authorization: Bearer $KEY" -H "Content-Type: application/json" -d '{"project":"web","name":"release-notes","expectedVersion":3,"expectedRevision":8}' $SITE/v1/skills/publishPublishes the current draft as the next version (here, 4). Send the version and draftRevision the save answered with. If someone saved or published in between, it answers 409; with no draft to publish, 400.
Archive a skill
curl -X DELETE -H "Authorization: Bearer $KEY" "$SITE/v1/skills?project=web&name=release-notes"
# → { "ok": true }An archived skill leaves the list.
Read published skills as files
The published skills are also on the /v1/fs tree, read-only:
curl -H "Authorization: Bearer $KEY" $SITE/v1/fs/projects/web/skills
curl -H "Authorization: Bearer $KEY" $SITE/v1/fs/projects/web/skills/release-notes
curl -H "Authorization: Bearer $KEY" $SITE/v1/fs/projects/web/skills/release-notes/SKILL.mdThe first lists the skills with a published version, the second a skill's files with their sha256, size and executable flag, and the third one file's bytes, with its SHA-256 as the ETag. These show the latest published version; a draft appears only after you publish it.
Errors
| Status | When |
|---|---|
400 | project or name is missing, the bundle is invalid (the message says what), or there is no draft to publish. |
403 | You aren't a member of the project. |
404 | No such project or skill. |
409 | The skill changed since you read it. Read it again and retry. |
Troubleshooting
A save answers 409 for a new skill
A skill with that name already exists in the project. List the skills, then save with its version and draftRevision.
"Bundle hash mismatch"
hash must be computed over the entries sorted by path, as JSON with no spaces. Recompute it after any change to the files.
Last updated on