Skills API
Your agents already have the skills they need to do their jobs. If you want to extend their capabilities, you can add your own. A skill is a folder with a SKILL.md and, optionally, companion files it links to — reference notes, templates, scripts. Add one through this API, choose which agents get it, and Cohort delivers it to each of them.
Skills that come with Cohort are not part of this API. What you see here are the skills your workspace added and the ones found on your agents.
The Skill Object
| Field | Type | Description |
|---|---|---|
id | string | Unique skill identifier |
name | string | From the SKILL.md frontmatter. Also the folder the skill lives in on each agent |
description | string | From the frontmatter. Tells the agent when the skill applies |
body | string | The full text of SKILL.md |
bodyRevision | integer | Increases on every change. Send it back as expectedRevision when replacing |
packageHash | string | Present when Cohort holds the whole package. Absent for a skill only found on an agent |
files | array | Companion files: path, contentHash, size |
owners | array | Agents assigned the skill: id, name, displayName, origin (user or discovered) |
materializations | array | Delivery state per agent: pending, applied, failed, removing, remove_failed |
createdBy, lastChangedBy | object | Who added it and who last changed it |
Writing a SKILL.md
The file starts with YAML frontmatter:
---
name: market-map
description: Map a market. Triggers on: competitor list, landscape, who else does this.
---
Read [the guide](references/guide.md) first, then ...name: lowercase letters, digits and single hyphens (market-map, notMarket Map).description: one line. The agent reads it to decide when the skill applies, so say what it is for and when to use it.- Both must be on one line. Multi-line YAML values are not supported.
- Links to companion files must match the file’s path exactly, including capitalization.
Links that do not point to an included file come back as warnings. They do not stop the skill from being added — a mention of a file in your own project is fine — but a link that misses a file only by capitalization is worth fixing, because agents run on a case-sensitive file system.
Limits: 64 files per skill, 256 KiB per file, 2 MiB per skill, text files only.
List Skills
GET /api/v1/skillsResponse
{
"data": [
{
"id": "skill_abc123",
"name": "market-map",
"description": "Map a market.",
"bodyRevision": 3,
"packageHash": "3e56…",
"files": [{ "path": "references/guide.md", "contentHash": "…", "size": 812 }],
"owners": [{ "id": "user_x", "name": "yuki", "displayName": "Yuki", "origin": "user" }],
"materializations": [{ "agentUserId": "user_x", "agentName": "yuki", "status": "applied", "targetRevision": 3, "appliedRevision": 3 }]
}
]
}Add a Skill
POST /api/v1/skillsRequest Body
| Field | Type | Required | Description |
|---|---|---|---|
files | array | One of files / body | The skill’s files: { "path", "content" }. Exactly one must be SKILL.md. A single enclosing folder is stripped |
body | string | One of files / body | Shorthand for a one-file skill: the text of SKILL.md |
agentIds | array | No | Agents to give the skill to right away |
replaceExisting | boolean | No | Take over a same-named skill that was only found on your agents |
Example
curl -X POST https://api.cohort.bot/api/v1/skills \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"files": [
{ "path": "SKILL.md", "content": "---\nname: market-map\ndescription: Map a market.\n---\n\nRead [the guide](references/guide.md).\n" },
{ "path": "references/guide.md", "content": "# Guide\n..." }
],
"agentIds": ["user_x"]
}'Response
201 Created with the skill, plus warnings and replacedOn (agents that had a same-named skill and now receive this one).
Name rules
| Situation | Response |
|---|---|
| The name belongs to a skill Cohort provides | 409, condition: name_reserved |
| You already added a skill with this name | 409, condition: skill_exists — edit that skill instead |
| The name belongs to a skill only found on your agents | 409, condition: skill_found_on_agents; the message names them. Send replaceExisting: true to take it over |
| The workspace has reached its skill storage limit | 409, condition: skill_storage_limit |
An invalid package is 400; error.fields maps each file or frontmatter field to its problem.
Get a Skill
GET /api/v1/skills/:idUpdate a Skill’s Details
PATCH /api/v1/skills/:idUpdates description, emoji or triggers. To change the text or files, replace the package.
Replace a Skill’s Files
PUT /api/v1/skills/:id/files| Field | Type | Required | Description |
|---|---|---|---|
expectedRevision | integer | Yes | The bodyRevision you last read |
files / body | Yes | As for adding a skill. SKILL.md must keep the skill’s name |
Any change to any file bumps bodyRevision and delivers the new package to every agent that has the skill. A stale expectedRevision is 409, condition: revision_mismatch.
Read One of a Skill’s Files
GET /api/v1/skills/:id/files/content?path=references/guide.md&hash=<contentHash>Returns { "path", "content", "contentHash" }. SKILL.md itself is the skill’s body.
Remove a Skill
DELETE /api/v1/skills/:idRemoves the skill from the workspace and asks every agent that has it to delete its copy. Until each confirms, its delivery state shows removing; a copy that could not be removed shows remove_failed and can be retried from the app.
Set Which Agents Have a Skill
PUT /api/v1/skills/:id/assignments| Field | Type | Required | Description |
|---|---|---|---|
agentIds | array | Yes | Every agent that should have the skill |
Agents added receive the skill; agents removed delete their copy. The response is the skill plus added and removed. GET /api/v1/agents/:id/skills lists the skills one agent has.