Skills
Verified request, response and authorization contracts.
Manage skills in Apps & skills → Skills. Use Yours for company skills, or Discover to find skills on skills.sh. App playbooks appear in each app’s drawer under Apps.
A skill is a folder with a SKILL.md and optional scripts, references and binary files. The company's skills are stored in Melso and installed in every Run, in the harness's own skill directory, next to the skills Melso includes. Nothing assigns a skill to a Task or Area.
A skill installed from skills.sh, GitHub or ClawHub records its source in config.origin and follows it: once a day Melso re-installs an unedited copy when the source changed. A copy edited in Melso, or one with auto_update off, is only marked update_available. POST /api/skills/{id}/refresh installs the latest version and resumes updates.
Skill rows carry id, workspace_id, name, description, config, created_by, created_at and updated_at; the detail adds content (the SKILL.md text), files and, for a sourced skill, source_edited. A file carries id, skill_id, path, content and encoding (utf8, or base64 for a binary file). Limits: 1 MiB per file, 8 MiB per skill and 256 files, on decoded size.
Examples use the environment variables from Overview. UUID placeholders must be replaced with your own IDs.
GET /api/skills
Auth: Workspace member.
Response: skill rows without content.
Status: 200. Authentication errors follow Overview.
curl -sS "$MELSO_URL/api/skills" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"GET /api/skills/builtin
Auth: Workspace member.
Response: {name,description}[], sorted by name: the read-only skills Melso installs in every Run. Each is published at /skills/<name>.md. The onboarding guides melso-onboarding and melso-onboarding-mcp are published there too but are not installed in Runs or listed here.
Status: 200.
curl -sS "$MELSO_URL/api/skills/builtin" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"GET /api/skills/search
Auth: Workspace member.
Request: Query q:string, at least 2 characters.
Response: {name,url,source,repo,install_count,description,audit_risk,audits}[] from skills.sh. url is the install URL. audit_risk is the highest risk skills.sh's security audits report (safe, low, medium, high or critical), or null; it informs and never blocks an install.
Status: 200; 400 missing or short query; 502 upstream_unavailable.
curl -sS "$MELSO_URL/api/skills/search?q=pdf" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"POST /api/skills/import
Auth: Workspace member.
Request (JSON): url:string and on_conflict?:"fail"|"overwrite"|"rename"|"skip". url is a skills.sh, GitHub or ClawHub URL, owner/repo@skill, owner/repo, a bare ClawHub slug, or a pasted npx skills add owner/repo --skill name command, which is read and never run.
Request (multipart): field file (a .zip or .skill archive, 16 MiB compressed at most) and optional on_conflict. The archive is rooted on its shallowest SKILL.md; binary files are kept.
Response: with on_conflict (always for an archive): {status,reason?,skill?,existing_skill?} where status is created, updated, conflict, skipped or failed. overwrite replaces the existing skill only for its creator. Without on_conflict, a URL import returns the created skill, or a 409 with existing_skill.
Status: 201 created; 200 updated or skipped; 400 invalid source or archive; 403 overwrite by someone else; 409 conflict; 413 over the limits; 502/503/504 source unavailable or slow.
curl -sS -X POST "$MELSO_URL/api/skills/import" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{"url":"https://skills.sh/anthropics/skills/pdf","on_conflict":"fail"}'
curl -sS -X POST "$MELSO_URL/api/skills/import" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
-F file=@pdf.zip -F on_conflict=renamePOST /api/skills
Auth: Workspace member.
Request: name:string required, description?:string, content?:string (the SKILL.md text), config?:object, files?:{path,content,encoding?}[].
Response: the skill with files.
Status: 201; 400 invalid body or file; 409 name taken.
curl -sS -X POST "$MELSO_URL/api/skills" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
-H "Content-Type: application/json" \
-d '{"name":"release-notes","description":"Write release notes","content":"---\nname: release-notes\ndescription: Write release notes\n---\n"}'GET /api/skills/{id}
Auth: Workspace member.
Response: the skill with content, files and, for a sourced skill, source_edited: true once it was changed in Melso, which pauses its updates.
Status: 200; 404.
curl -sS "$MELSO_URL/api/skills/$SKILL_ID" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"PUT /api/skills/{id}
Auth: the skill's creator or a workspace owner/admin.
Request: any of name, description, content, config, files (replaces every file) and auto_update:boolean, which turns following the source on or off.
Response: the skill with files.
Status: 200; 400 invalid body, or auto_update on a skill with no source; 403; 404; 409 name taken.
curl -sS -X PUT "$MELSO_URL/api/skills/$SKILL_ID" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
-H "Content-Type: application/json" -d '{"auto_update":false}'POST /api/skills/{id}/refresh
Auth: the skill's creator or a workspace owner/admin.
Request: no body.
Response: the skill with files, replaced by its source's current version. Edits made in Melso are discarded and updates resume; the id and creator stay.
Status: 200; 403; 404; 409 the source renamed it to a taken name; 422 no source to update from; 413/502/503/504 source too large, gone or slow.
curl -sS -X POST "$MELSO_URL/api/skills/$SKILL_ID/refresh" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"DELETE /api/skills/{id}
Auth: the skill's creator or a workspace owner/admin.
Status: 204; 403; 404. Runs stop receiving the skill.
curl -sS -X DELETE "$MELSO_URL/api/skills/$SKILL_ID" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"PUT /api/skills/{id}/files
Auth: the skill's creator or a workspace owner/admin.
Request: path:string, content:string, encoding?:"utf8"|"base64". SKILL.md is reserved for the skill's content.
Response: the file. The skill's updated_at moves, so a sourced skill counts as edited.
Status: 200; 400 invalid path, encoding or SKILL.md; 403; 404.
curl -sS -X PUT "$MELSO_URL/api/skills/$SKILL_ID/files" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID" \
-H "Content-Type: application/json" -d '{"path":"scripts/run.sh","content":"#!/bin/sh\necho ok\n"}'DELETE /api/skills/{id}/files/{fileId}
Auth: the skill's creator or a workspace owner/admin.
Status: 204; 403; 404.
curl -sS -X DELETE "$MELSO_URL/api/skills/$SKILL_ID/files/$FILE_ID" \
-H "Authorization: Bearer $MELSO_TOKEN" -H "X-Workspace-ID: $WORKSPACE_ID"