Skills
Package reusable filesystem-shaped capabilities that agents in Orca Agent Engine load on demand.
A Skill in Orca Agent Engine is a filesystem-shaped bundle of expertise an agent loads on demand. You upload a skill as a set of files - instructions, reference material, helper scripts - and reference it from one or more agents. Skills are versioned, so the same skill can evolve without breaking agents that pin to a known-good version.
Agent Engine supports custom skills that you upload as multipart bundles. The source field also has an anthropic value for provider-supplied skills, but no upload path produces one - every upload is recorded as custom. Treat anthropic as reserved rather than available.
Get your registry endpoint
Registry endpoint
Examples on this page target your registry endpoint - the deployment host root, with no path
suffix. For CLI, set ORCA_REGISTRY_URL and exactly one of ORCA_ACCESS_TOKEN (Bearer) or
ORCA_API_KEY (x-api-key). For TypeScript SDK, set ORCA_BASE_URL / ORCA_API_KEY (Bearer).
To find the endpoint, see Connect to the registry.
Upload a custom skill
Upload a skill with a multipart POST to /v1/skills. The endpoint accepts the bundle in either of two forms:
- Individual files. Send one multipart file part per file. This is what the
orkCLI does when you repeat--file. - A single ZIP archive. Send exactly one file part whose content type is
application/ziporapplication/x-zip-compressed, or whose filename ends in.zip. The registry unpacks it server-side.
Either way, the bundle must satisfy the same shape:
- Every file shares exactly one top-level directory. Mixed top-level directories are rejected with
all files must share a top-level directory. - That directory contains
SKILL.mdat its root. The registry parses the skill's name and description out of it. - A bundle holds at most 128 files and 30 MB in total. Exceeding either cap returns
413.
The bundle's display name is sent as an optional display_title form field.
The ork CLI takes either form. --file is repeatable for loose files, and that path checks for a local SKILL.md before uploading; a single --file ending in .zip skips that check and uploads the archive.
skill=$(ork agent skills create \
--display-title ticket-routing \
--file /path/to/ticket-routing/SKILL.md \
--file /path/to/ticket-routing/routes.json \
--file /path/to/ticket-routing/examples.md \
-o json)
SKILL_ID=$(jq -r '.id' <<< "$skill")
SKILL_VERSION=$(jq -r '.latest_version' <<< "$skill")Each part's filename carries the path inside the bundle, so it must be prefixed with the top-level directory. The ork CLI derives that prefix from the directory holding SKILL.md; with curl you set it yourself through ;filename=.
To upload the same bundle as an archive, send one ZIP part instead. The directory structure comes from inside the archive, so no filename prefixing is needed:
curl -fsS -X POST "$ORCA_REGISTRY_URL/v1/skills" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-F "display_title=ticket-routing" \
-F "files[]=@/path/to/ticket-routing.zip;type=application/zip"A successful upload returns 200 OK with the new skill:
{
"id": "skill_01H8...",
"type": "skill",
"source": "custom",
"display_title": "ticket-routing",
"latest_version": "1778520248000001",
"created_at": "2026-05-11T17:24:08Z",
"updated_at": "2026-05-11T17:24:08Z"
}Capture the id and reference it from any agent that should load the skill. source is custom for bundles you upload. anthropic is reserved for provider-supplied skills, and no upload path produces one.
Upload a new skill version
Updates are version-additive: upload a new version of the same skill rather than mutating it in place. POST to /v1/skills/{skillId}/versions with the new bundle, in either the individual-files or ZIP form.
curl -fsS -X POST "$ORCA_REGISTRY_URL/v1/skills/$SKILL_ID/versions" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-F "files[]=@/path/to/ticket-routing/SKILL.md;filename=ticket-routing/SKILL.md" \
-F "files[]=@/path/to/ticket-routing/routes.json;filename=ticket-routing/routes.json"Agents that pin a specific version continue to use the version they pinned; agents that omit version pick up the new version on next session start.
Attach skills to an agent
Reference a skill from an agent's skills array when you create or update the agent. Each entry sets type, the skill_id returned at upload, and an optional pinned version.
| Field | Type | Required | Description |
|---|---|---|---|
type | string | Yes | custom for skills you uploaded. anthropic is accepted here but breaks session creation - see the note below. |
skill_id | string | Yes | The ID returned by the skill upload endpoint. custom skills use a skill_ ID, and every path and field that takes one rejects any other prefix. |
version | string | No | Pin to a specific version. Omit to track the latest version. |
Only custom skills work. A type: "anthropic" reference is accepted, stored, and returned on the agent, but no anthropic skill can exist to resolve it against: the upload endpoint records every bundle as custom. Every session you create for that agent fails with 400 skill <skill_id> version <version> not found in workspace, so the session never starts - the agent does not run with the skill missing, it does not run at all. Upload the skill as a custom bundle instead.
$SKILL_ID and $SKILL_VERSION are what the upload above captured.
curl -fsS "$ORCA_REGISTRY_URL/v1/agents" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "support-triage",
"model": "claude-sonnet-4-6",
"system": "You triage support tickets.",
"tools": [{ "type": "agent_toolset" }],
"skills": [
{ "type": "custom", "skill_id": "'"$SKILL_ID"'", "version": "'"$SKILL_VERSION"'" }
]
}'The agent loads the skill into the session on demand; the agent decides when to consult it based on the task at hand.
A skill-bearing agent needs an enabled read tool, or its sessions never start. Skills are
mounted as read-only files and the agent is told to open SKILL.md with read, so an agent that
declares skills without an enabled read fails setup with agent <id> has skills but no enabled read tool - at session start, not at create time. That is why the example above declares
agent_toolset.
On an in-sandbox harness there is a second requirement: read must resolve to always_allow, or
setup fails with in-sandbox agent <id> requires read=always_allow to load skills. So the
selective-toolset recipe - default_config with "enabled": false plus one configs entry per
tool you want back - has to keep read both enabled and, in sandbox, always allowed.
Manage skills
List skills
ork agent skills listThe list takes one filter, source: pass source=custom for the bundles you uploaded. source=anthropic is accepted and returns nothing, since no upload path produces an anthropic skill. Any other value returns 400. limit and page are the only other query parameters the endpoint reads, and neither the CLI nor the SDK exposes source, so use the registry endpoint directly for it.
curl -fsS "$ORCA_REGISTRY_URL/v1/skills?source=custom&limit=20" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN"Retrieve a skill
ork agent skills get $SKILL_IDList versions
curl -fsS "$ORCA_REGISTRY_URL/v1/skills/$SKILL_ID/versions?limit=20" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN"Retrieve a specific version
curl -fsS "$ORCA_REGISTRY_URL/v1/skills/$SKILL_ID/versions/$SKILL_VERSION" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN"Delete a version
curl -fsS -X DELETE "$ORCA_REGISTRY_URL/v1/skills/$SKILL_ID/versions/$SKILL_VERSION" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN"Delete a skill
Deleting a skill requires deleting each of its versions first. While any version is un-archived the delete returns 400 all skill versions must be deleted before deleting the skill, so a freshly uploaded skill cannot be deleted in one call. Once the skill is gone, agents that reference it surface an error on next session start.
curl -fsS -X DELETE "$ORCA_REGISTRY_URL/v1/skills/$SKILL_ID" \
-H "Authorization: Bearer $ORCA_ACCESS_TOKEN"Permissions
Treat every Workspace API key as full access to its Workspace's resources, and separate access with Workspaces. See Control registry access.