Skills

Install reusable procedures the agent can draw on, and manage which ones are active.

A skill is a reusable procedure you install into a project. It is a Markdown file — instructions the agent reads and follows when the task calls for it. "How we format the monthly revenue report", "how to reconcile the two order tables", "which caveats to attach to churn numbers."

Where Memory is what the agent learns about one user, a skill is what your team has decided is the right way to do something.

How a skill is put together

Every skill is a directory whose entry point is SKILL.md: YAML frontmatter naming it, then a Markdown body.

---
name: revenue-report
description: Formats the monthly revenue report the finance team expects.
---
When asked for the monthly revenue report:

1. Pull net revenue by product line for the requested month.
2. Compare against the same month last year.
3. Present as a table, figures in millions, two decimal places.
4. Call out any line that moved more than 15% year over year.

description is what the agent matches against when deciding whether a skill applies, so write it as a trigger, not a summary.

A skill can be more than one file — supporting templates or reference data live alongside SKILL.md in the same directory.

Built-in versus project skills

Built-inProject
Where fromPackaged with WrenInstalled by you
DeletableNoYes
DownloadableNoYes
OverridableInstall a project skill of the same name and it shadows the built-in

Listing returns both, merged, with isBuiltin telling them apart. Deleting a project skill that shadowed a built-in makes the built-in visible again.

Endpoints Overview

EndpointWhat it does
GET /v2/projects/{projectId}/skillsList the project's skills merged with the built-ins.
POST /v2/projects/{projectId}/skillsCreate a skill from a zip or a JSON body.
GET /v2/projects/{projectId}/skills/{skillName}Read one skill's body and file manifest.
DELETE /v2/projects/{projectId}/skills/{skillName}Delete a project skill.
GET /v2/projects/{projectId}/skills/{skillName}/downloadDownload a skill as a zip.
PUT /v2/projects/{projectId}/skills/{skillName}/disabledEnable or disable without deleting.

Basic Usage

Create a single-file skill

The simplest case — no zip, just the frontmatter fields and the body:

{
  "name": "revenue-report",
  "description": "Formats the monthly revenue report the finance team expects.",
  "content": "When asked for the monthly revenue report:\n\n1. Pull net revenue by product line for the requested month.\n2. Compare against the same month last year.\n3. Present as a table, figures in millions."
}
{
  "name": "revenue-report",
  "fileCount": 1
}

The SKILL.md is assembled server-side. name is lowercase kebab-case and also becomes the directory name.

Create a multi-file skill

Send multipart/form-data with a .zip containing exactly one top-level directory, which must contain SKILL.md:

revenue-report/
├── SKILL.md
└── templates/
    └── summary-table.md
LimitValue
Compressed5 MB
Uncompressed20 MB
Files100

This is the same layout download returns, so a skill round-trips: download it, edit it, upload it again.

List what a project has

{
  "skills": [
    {
      "projectId": 1,
      "name": "revenue-report",
      "description": "Formats the monthly revenue report the finance team expects.",
      "isBuiltin": false,
      "isDisabled": false,
      "lastModified": "2026-08-02T09:20:11.000Z"
    },
    {
      "projectId": 1,
      "name": "data-quality-check",
      "description": "Checks a table for nulls, duplicates and stale partitions.",
      "isBuiltin": true,
      "isDisabled": false,
      "lastModified": "2026-07-18T00:00:00.000Z"
    }
  ]
}

Turn one off without deleting it

{
  "disabled": true
}
{
  "name": "revenue-report",
  "disabled": true
}

A disabled skill stays in the project but is withheld from the agent. It takes effect for the next turn — a turn already running keeps the skills it started with.

Editing a skill

There is no update endpoint. Download, edit, delete, re-create:

// 1. Download the current version as a zip.
const zip = await getBinary(`/v2/projects/1/skills/revenue-report/download`);

// 2. Edit SKILL.md locally, rezip.

// 3. The name is taken, so remove the old one first — 409 otherwise.
await del(`/v2/projects/1/skills/revenue-report`);

// 4. Upload the edited zip.
await postMultipart(`/v2/projects/1/skills`, { file: editedZip });

Re-using an existing skill name returns 409. Built-in skills cannot be overwritten, deleted, or downloaded.

Frontmatter is validated on create, exactly as in the UI upload path — a missing name or description is rejected with 400. No execution check is performed, so a skill that parses but gives bad instructions installs fine. Test it with a turn.

🔗

Learn more