Documentation
Everything you need to save, share, verify, and install skills.
Overview
SkillSafe is the verified registry for AI agent skills. Unlike open registries where anyone can upload unscanned code, SkillSafe scans every skill before sharing and independently re-verifies on install. Cryptographic tree hashes ensure that what the publisher uploaded is byte-for-byte identical to what you receive.
Install skills with the SkillSafe desktop app (one-click install, available for macOS / Windows / Linux) or npx skills add on the command line — see Installing below.
What are Skills?
Skills are reusable instruction sets that teach AI agents (like Claude Code, Cursor, Windsurf, Codex, Gemini, OpenCode, OpenClaw, Cline, Roo, Goose, Copilot, Kiro, Trae, AMP, Aider, VS Code, Antigravity, Droid, and Kilo Code) new capabilities — from code review to deployment automation. Each skill is a directory containing a SKILL.md definition file and any supporting scripts. SkillSafe provides a verified registry where you can save, share, and install skills with security scanning and cryptographic verification.
Quick Start
Prefer tool-specific steps? See the quickstart guides for Claude Code, Cursor, Windsurf, and Codex.
1. Browse and pick a skill
Search the public registry on the Explore page. Every skill page shows its scan verdict, file manifest, dependencies, and version history before you install.
2. Install with the SkillSafe desktop app (recommended)
Download the SkillSafe desktop app (macOS / Windows / Linux). On any skill page, click View in SkillSafe app — the app opens via the skillsafe://install?ns=…&name=…&version=… deep link, re-runs a local scan, compares it to the publisher's scan, and writes files to your tool's skill directory.
2b. Or install from the command line
SkillSafe works with Vercel's skills CLI — every SkillSafe skill is cloneable via git, so npx skills add works natively:
npx skills add https://api.skillsafe.ai/owner/skill-name The skills CLI auto-detects your AI tool (Claude Code, Cursor, Windsurf, Codex) and writes files to the correct location. See Installing for git clone and zip download options.
3. Scan
Scan any skill archive or your MCP server config for security issues with the scan endpoint or via the /scan page. Detects prompt injection, credential theft, exfiltration, and 40+ other threat patterns.
4. Save & Share
Publish your own skills to the registry. Saving is private by default — sharing creates a link with optional public visibility, and requires a scan report. See Saving & Sharing for the API.
Authentication
Sign-In Methods
SkillSafe supports multiple sign-in methods:
- Google Sign-In — One-click OAuth via Google account
- GitHub Sign-In — OAuth via GitHub account
- Email & Password — Sign in with email verification
- API Device Flow —
POST /v1/auth/clicreates a session, user approves in browser, agent polls for API key
API Keys (CLI)
CLI and programmatic requests use a Bearer token:
Authorization: Bearer sk_your_api_key_here API keys are hashed with SHA-256 before storage. The server never stores plaintext keys. Browser sessions use HttpOnly cookies instead of Bearer tokens.
⚠️ Never commit API keys to source control. Use environment variables instead.
🔒 Never share your API keys. Keep them secret and rotate them immediately if compromised.
Key Limits
- All tiers: max 20 active keys per account
Manage keys at /account/keys.
Saving & Sharing
Saving a Skill
Skills are saved privately by default. No email verification or scan report required.
POST /v1/skills/@{namespace}/{name}
Content-Type: multipart/form-data
Fields:
metadata — JSON with version, description, category, tags, changelog, github_repo_url, file_manifest
scan_report — JSON scan report (optional for save)
file_* — individual skill files (one per form field, filename carries relative path) Creating a Share Link
Sharing creates a link others can use to download and verify a saved version. Requires email verification and a scan report.
POST /v1/skills/@{namespace}/{name}/versions/{version}/share
Body (JSON):
visibility — "private" (link-only) or "public" (discoverable via search)
expires_in — "1d", "7d", "30d", or "never"
allow_reshare — boolean (optional) — whether the recipient may reshare Metadata Field Limits
description: max 2,000 characterscategory: max 100 characterstags: max 1,000 characterschangelog: max 5,000 characters
Size Limits
- Max upload: 15 MB per version (v2 format: 10 MB total file content)
- Free: 50 MB total account storage | Paid: 5 GB | Enterprise: 10 GB
Daily Publish Limits
Version saves are rate-limited per account on a rolling 24-hour window:
- Free: 50 versions / 24h
- Paid: 200 versions / 24h
- Enterprise: 1,000 versions / 24h
Agent Limits
- Free: 1 agent, 5 snapshots per agent, 1 MB per snapshot
- Paid: 5 agents, 50 snapshots per agent, 10 MB per snapshot
- Enterprise: unlimited agents & snapshots, 50 MB per snapshot
Installing a Skill
No account required to install public skills. There are several ways to install, depending on your workflow:
SkillSafe desktop app (recommended)
The SkillSafe desktop app (macOS / Windows / Linux) is the simplest way to install. On any skill page, click View in SkillSafe app — the app opens via a skillsafe://install?ns=…&name=…&version=… deep link, re-runs a local scan, dual-verifies against the publisher's scan, and writes files to your tool's skill directory.
npx skills add
SkillSafe works with Vercel's skills CLI. Every SkillSafe skill is cloneable via git, so npx skills add works natively:
npx skills add https://api.skillsafe.ai/owner/skill-name This runs git clone under the hood. SkillSafe synthesizes a git repo on the fly from the skill's file manifest — no actual git repository is stored. The skills CLI auto-detects your AI tool (Claude Code, Cursor, Codex, Windsurf, etc.) and writes files to the correct location.
Download .zip
Every skill page has a Download .zip button. The zip is generated in your browser from the file manifest — no server-side packaging needed. Unzip into your tool's skill directory:
# Claude Code
unzip skill-name.zip -d .claude/skills/skill-name/
# Cursor
unzip skill-name.zip -d .cursor/skills/skill-name/
# Codex
unzip skill-name.zip -d .agents/skills/skill-name/ git clone
Clone directly with git for full control:
git clone --depth 1 https://api.skillsafe.ai/owner/skill-name .claude/skills/skill-name For private skills, authenticate with your API key as the password (username is ignored):
git clone --depth 1 https://x:sk_your_api_key@api.skillsafe.ai/owner/skill-name REST API
Fetch the file manifest and download individual blobs programmatically:
# Get file manifest
GET /v1/skills/@owner/skill-name/download/1.0.0
# Download individual file by hash
GET /v1/blobs/sha256:abc123... Verification Model
SkillSafe uses dual-side verification.
Reports match. Safe to install.
Reports disagree. Review before installing.
Tree hashes mismatch. Do not install.
Searching
Search skills via the REST API. The same query parameters power the Browse Skills page and the in-site search overlay (press /). The Browse page exposes quick trust filters for clean scans and publisher-tested skills.
GET /v1/skills/search?q=formatter&sort=popular&limit=20 Sort: popular, recent, verified, trending, hot, stars, newest, installs, eval_score, relevance, updated
Additional filter parameters: category, namespace, tag, scan_clean (boolean — only skills with clean scan reports), eval_tested (boolean — only skills with publisher eval results), type (skill or skillset), owner_type (filter by owner type).
MCP Tools (legacy / programmatic)
SkillSafe also exposes a JSON-RPC MCP server for backwards compatibility and for tools that prefer programmatic access. The recommended install path is the desktop app or npx skills add — see Installing. If you choose to add the MCP server to your tool's config, the following tools are available:
search_skills— Search by keyword, category, tag, namespace. Supports sorting and pagination.recommend_skills— Describe a task and get ranked skill recommendations.get_skill_info— Get full metadata for a specific skill.install_skill— Download and install a skill into your tool's directory.scan_skill— Run a security scan on a skill before installing.scan_mcp_config— Scan your MCP config for known-vulnerable servers.save_skill— Save a skill to the registry (private by default).share_skill— Create a share link for a saved skill (requires scan report).
See the Quick Start guide for setup instructions per tool.
API Reference
Base URL: https://api.skillsafe.ai. All public endpoints are listed below. Admin-only endpoints are excluded.
| Method | Path | Auth | Description |
|---|---|---|---|
| Account | |||
| GET | /v1/account | Yes | Own profile, tier, and email verification status |
| PATCH | /v1/account | Yes | Update own profile. Body: { "username_display": "..." } |
| POST | /v1/account/verify-email | Yes | Send email verification link |
| POST | /v1/account/claim | No | Verify email and set password via claim token. Body: { "token": "...", "password": "..." } — both fields required. |
| GET | /v1/account/usage | Yes | Storage and API usage statistics |
| GET | /v1/account/skills | Yes | All own skills (private + public) |
| GET | /v1/account/keys | Yes | List active API keys |
| POST | /v1/account/keys | Yes | Generate a new API key |
| DELETE | /v1/account/keys/{id} | Yes | Revoke an API key |
| DELETE | /v1/account/keys | Yes | Revoke all API keys (emergency panic button) |
| DELETE | /v1/account/data | Yes | Purge all skills and data (keep account) |
| DELETE | /v1/account | Yes (verified) | Schedule account deletion (24 h grace period) |
| GET | /v1/users/{username} | No | Public profile for a user (skills, bio) |
| Auth | |||
| POST | /v1/auth/google | No | Google Sign-In; sets HttpOnly session cookie |
| POST | /v1/auth/github | No | GitHub OAuth; sets HttpOnly session cookie |
| POST | /v1/auth/logout | No | Log out and clear session cookie |
| POST | /v1/auth/key-exchange | Yes | Exchange Bearer token for HttpOnly session cookie |
| POST | /v1/auth/cli | No | Create CLI auth session (device flow) |
| GET | /v1/auth/cli/{id} | No | Poll session status; returns API key when approved |
| POST | /v1/auth/cli/{id}/approve | Yes | Approve CLI session from browser |
| POST | /v1/auth/email/send-code | No | Send 6-digit sign-in code to email |
| POST | /v1/auth/email/verify-code | No | Verify code and create session |
| POST | /v1/auth/email/login | No | Sign in with email and password |
| POST | /v1/auth/email/set-password | Yes | Set a first-time password on the account |
| POST | /v1/auth/email/change-password | Yes | Change account password (current password required) |
| POST | /v1/auth/email/register/send-code | No | Send registration verification code |
| POST | /v1/auth/email/register/verify | No | Verify code and create account with password |
| POST | /v1/auth/email/forgot-password | No | Send password-reset code to email |
| POST | /v1/auth/email/reset-password | No | Verify reset code and set new password |
| Skills | |||
| POST | /v1/skills/batch/versions | Optional | Check latest versions for multiple installed skills at once |
| POST | /v1/skills/@{ns}/{name} | Yes | Save a new skill version (multipart: archive + metadata) |
| GET | /v1/skills/@{ns}/{name} | Optional | Skill metadata, latest version, star count |
| DELETE | /v1/skills/@{ns}/{name} | Yes | Delete a skill |
| GET | /v1/skills/@{ns}/{name}/versions | Optional | List all versions (paginated) |
| GET | /v1/skills/@{ns}/{name}/versions/{version} | Optional | Version details including tree hash and scan report |
| GET | /v1/skills/@{ns}/{name}/download/{version} | Optional | Download skill file manifest (public skills only; private skills require auth or a share link) |
| POST | /v1/skills/@{ns}/{name}/negotiate | Yes | Delta upload: determine which files need uploading (v2) |
| POST | /v1/skills/@{ns}/{name}/current-version | Yes | Pin the displayed current version |
| POST | /v1/skills/@{ns}/{name}/versions/{version}/yank | Yes (verified) | Yank a version (marks it unsafe, hides from downloads) |
| POST | /v1/skills/@{ns}/{name}/star | Yes | Star a skill |
| DELETE | /v1/skills/@{ns}/{name}/star | Yes | Unstar a skill |
| GET | /v1/skills/@{ns}/{name}/related | Optional | Other skills from the same GitHub repository |
| GET | /v1/skills/@{ns}/{name}/children | Optional | Child skills in a skillset (paginated) |
| GET | /v1/skills/@{ns}/{name}/readme | Optional | Cached GitHub README in markdown |
| GET | /v1/skills/@{ns}/{name}/versions/{version}/bom | Optional | Bill of Materials: capability inventory for a version |
| GET | /v1/blobs/{hash} | Optional | Download blob by SHA-256 hash (content-addressable, immutable) |
| GET | /v1/skills/search | No | Full-text search; sort by popular/recent/verified/trending/hot/stars/installs/eval_score/relevance/updated/newest |
| POST | /v1/skills/recommend | No | AI-powered skill recommendations from a free-text task description (body: task) |
| POST | /v1/skills/import-github | Yes (verified) | Import a GitHub repo as a public placeholder skill |
| POST | /v1/skills/import-github/batch | Yes (verified) | Batch import multiple sub-skills from a monorepo |
| POST | /v1/skills/discover-github | Yes (verified) | Discover SKILL.md files in a GitHub repository |
| POST | /v1/skills/import-url | Yes (verified) | Import a skill from any URL (GitHub or ClawHub) |
| Sharing | |||
| POST | /v1/skills/@{ns}/{name}/versions/{version}/share | Yes (verified) | Create share link (requires email verification + scan report) |
| GET | /v1/skills/@{ns}/{name}/versions/{version}/shares | Yes | List share links for a version |
| GET | /v1/share/{shareId} | No | Share link metadata (skill, version, expiry, access count) |
| GET | /v1/share/{shareId}/download | Optional | Download via share link (increments access counter) |
| DELETE | /v1/share/{shareId} | Yes | Revoke a share link |
| Verification | |||
| POST | /v1/skills/@{ns}/{name}/versions/{version}/verify | Yes | Submit consumer scan report; returns verdict (verified/divergent/critical) |
| Organizations | |||
| POST | /v1/orgs | Yes (verified) | Create organization (requires email verification) |
| GET | /v1/orgs | Yes | List organizations you belong to |
| GET | /v1/orgs/{orgId} | Yes | Organization details (members only) |
| PATCH | /v1/orgs/{orgId} | Yes | Update org display name (owner only) |
| PATCH | /v1/orgs/{orgId}/name | Yes | Rename org namespace (owner only) |
| DELETE | /v1/orgs/{orgId} | Yes | Delete organization (owner only) |
| GET | /v1/orgs/{orgId}/skills | Yes | List org skills (members only) |
| GET | /v1/orgs/{orgId}/members | Yes | List org members (paginated) |
| POST | /v1/orgs/{orgId}/members/invite | Yes | Invite member by email (admin+ only) |
| PATCH | /v1/orgs/{orgId}/members/{accountId} | Yes | Change member role (admin+ only) |
| DELETE | /v1/orgs/{orgId}/members/{accountId} | Yes | Remove member (admin+ only) |
| GET | /v1/orgs/{orgId}/invitations | Yes | List pending invitations (admin+ only) |
| DELETE | /v1/orgs/{orgId}/invitations/{invId} | Yes | Revoke invitation (admin+ only) |
| POST | /v1/orgs/invitations/{invId}/accept | Yes | Accept email invitation |
| POST | /v1/orgs/{orgId}/join-link | Yes | Create or regenerate join link (admin+ only) |
| DELETE | /v1/orgs/{orgId}/join-link | Yes | Revoke join link (admin+ only) |
| GET | /v1/orgs/join/{linkId} | No | Org info for join page (name, member count) |
| POST | /v1/orgs/join/{linkId}/accept | Yes | Join organization via link |
| POST | /v1/orgs/{orgId}/domain | Yes | Set domain for verification (owner only) |
| POST | /v1/orgs/{orgId}/domain/verify | Yes | Verify domain via DNS TXT record (owner only) |
| DELETE | /v1/orgs/{orgId}/domain | Yes | Remove domain (owner only) |
| Billing | |||
| GET | /v1/billing/config | Yes | Stripe publishable key for frontend checkout |
| GET | /v1/billing/prices | Yes | Available plan prices (paid/enterprise, monthly/yearly) |
| GET | /v1/billing/balance | Yes | Customer credit balance |
| POST | /v1/billing/checkout | Yes (verified) | Create Stripe Checkout session (requires email verification) |
| GET | /v1/billing/portal | Yes (verified) | Stripe Customer Portal session URL |
| GET | /v1/billing/subscription | Yes (verified) | Current subscription plan, status, and renewal date |
| GET | /v1/billing/invoices | Yes (verified) | Invoice history (paginated) |
| GET | /v1/billing/payment-methods | Yes (verified) | List saved payment methods |
| POST | /v1/billing/payment-methods | Yes (verified) | Create SetupIntent for adding a new card |
| DELETE | /v1/billing/payment-methods/{id} | Yes (verified) | Detach payment method |
| POST | /v1/billing/payment-methods/{id}/default | Yes (verified) | Set default payment method |
| POST | /v1/billing/cancel | Yes (verified) | Cancel subscription at period end |
| POST | /v1/billing/reactivate | Yes (verified) | Reactivate cancelled subscription |
| POST | /v1/billing/upgrade-click | Yes | Track upgrade button click (analytics) |
| Backup | |||
| GET | /v1/backup/connections | Yes | List connected backup accounts (e.g. Dropbox) |
| GET | /v1/backup/connect/dropbox | Yes | Start Dropbox OAuth connection flow |
| GET | /v1/backup/callback/dropbox | No | Dropbox OAuth callback (handles redirect) |
| PATCH | /v1/backup/connections/dropbox | Yes | Update backup preferences (auto-backup, frequency) |
| DELETE | /v1/backup/connections/dropbox | Yes | Disconnect Dropbox backup |
| POST | /v1/backup/trigger | Yes | Trigger a manual backup to connected provider |
| GET | /v1/backup/jobs | Yes | List backup jobs (paginated) |
| GET | /v1/backup/jobs/{jobId} | Yes | Get backup job status and details |
| Demos | |||
| POST | /v1/skills/@{ns}/{name}/versions/{version}/demos | Yes | Upload a demo recording for a skill version |
| GET | /v1/skills/@{ns}/{name}/demos | Optional | List demos for a skill (paginated) |
| GET | /v1/demos | Optional | Browse all public demos (paginated, filterable) |
| GET | /v1/demos/{demoId} | Optional | Demo metadata (title, tool, model, star count) |
| GET | /v1/demos/{demoId}/content | Optional | Full demo recording content (messages, tool calls) |
| PATCH | /v1/demos/{demoId} | Yes | Update demo title or visibility (owner only) |
| DELETE | /v1/demos/{demoId} | Yes | Delete a demo (owner only) |
| POST | /v1/demos/{demoId}/star | Yes | Star a demo |
| DELETE | /v1/demos/{demoId}/star | Yes | Unstar a demo |
| POST | /v1/demos/{demoId}/view | No | Track a demo view (increments view counter) |
| POST | /v1/demos/{demoId}/eval-link | Yes | Link an eval result to a demo |
| DELETE | /v1/demos/{demoId}/eval-link/{evalId} | Yes | Unlink an eval result from a demo |
| POST | /v1/skills/@{ns}/{name}/pin-demo | Yes | Pin or unpin a demo on the skill page (owner only) |
| Evals & Benchmarks | |||
| POST | /v1/skills/@{ns}/{name}/versions/{version}/eval | Yes | Upload eval results for a skill version |
| GET | /v1/skills/@{ns}/{name}/eval | No | List all eval results across versions (paginated) |
| GET | /v1/skills/@{ns}/{name}/versions/{version}/eval | No | Eval results for a specific version |
| Badges | |||
| GET | /v1/badge/@{ns}/{name}/verified | No | SVG badge: verification status |
| GET | /v1/badge/@{ns}/{name}/installs | No | SVG badge: total install count |
| GET | /v1/badge/@{ns}/{name}/scan | No | SVG badge: scan report result |
| GET | /v1/badge/@{ns}/{name}/eval | No | SVG badge: latest eval pass rate |
| Security Scanning | |||
| POST | /v1/scan/github | Optional | Scan a public GitHub repo for security issues (returns scan ID) |
| GET | /v1/scan/github | No | Scan a GitHub repo via GET (query params: url, subpath) |
| GET | /v1/scan/{scanId} | No | Get scan results by scan ID |
| GET | /v1/scan/github/bom | No | Bill of Materials for a GitHub repo |
| GET | /v1/scan/github/badge | No | SVG badge for GitHub repo scan status |
| POST | /v1/scan/files | No | Scan raw files without GitHub (max 1000 files, 2 MB/file, 20 MB total) |
| POST | /v1/mcp/scan | No | Scan an MCP server configuration for security issues |
| MCP Server (legacy) | |||
| GET | /mcp | No | JSON manifest listing MCP tools, transport details, and config snippets for each AI tool |
| POST | /mcp | Optional | JSON-RPC 2.0 MCP endpoint (kept for backwards compatibility — new installs should use the desktop app or npx skills add) |
| Stats & Other | |||
| GET | /v1/stats | No | Platform counts: skills, publishers, skills_scanned, skills_verified, scan_reports, threats_caught (confirmed, see threat database), findings_flagged, verified_safe, demos, comments |
| GET | /v1/health | No | API and database health check |
| GET | /v1/cli/version | No | Latest CLI version and download URLs |
| Demo Comments | |||
| GET | /v1/demos/{demoId}/comments | No | List comments on a demo |
| POST | /v1/demos/{demoId}/comments | Yes | Post a comment |
| DELETE | /v1/demos/{demoId}/comments/{commentId} | Yes | Delete own comment |
| POST | /v1/demos/{demoId}/comments/{commentId}/vote | Yes | Toggle upvote on a comment |
| Agents | |||
| POST | /v1/agents | Yes | Create an agent identity |
| GET | /v1/agents | Yes | List your agents (paginated) |
| GET | /v1/agents/{agentId} | Yes | Agent details and metadata |
| PATCH | /v1/agents/{agentId} | Yes | Update agent metadata |
| DELETE | /v1/agents/{agentId} | Yes | Delete an agent and all snapshots |
| POST | /v1/agents/{agentId}/snapshots | Yes | Save a snapshot (multipart: files + metadata) |
| GET | /v1/agents/{agentId}/snapshots | Yes | List snapshots (paginated) |
| GET | /v1/agents/{agentId}/snapshots/latest | Yes | Get the latest snapshot |
| GET | /v1/agents/{agentId}/snapshots/tagged/{versionTag} | Yes | Get snapshot by version tag |
| GET | /v1/agents/{agentId}/snapshots/{snapshotId} | Yes | Get a specific snapshot |
| PATCH | /v1/agents/{agentId}/snapshots/{snapshotId} | Yes | Update snapshot metadata (version_tag) |
| DELETE | /v1/agents/{agentId}/snapshots/{snapshotId} | Yes | Delete a snapshot |
| GET | /v1/agents/{agentId}/snapshots/{snapshotId}/files/* | Yes | Get file content from a snapshot |
| GET | /v1/agents/{agentId}/diff | Yes | Diff two snapshots |
| GET | /v1/agents/{agentId}/snapshots/{snapshotId}/download | Yes | Download all snapshot files |
| POST | /v1/agents/{agentId}/snapshots/{snapshotId}/scan | Yes | Scan a snapshot for security issues |
| GET | /v1/agents/{agentId}/snapshots/{snapshotId}/scan | Yes | Get scan report for a snapshot |
| Publishers | |||
| GET | /v1/publishers/{platform}/{owner} | No | Publisher profile (public) |
| GET | /v1/publishers/{platform}/{owner}/skills | No | List publisher's skills (public) |
| POST | /v1/publishers/claim | Yes | Claim a publisher identity |
| GET | /v1/account/publishers | Yes | List your claimed publishers |
| Feedback | |||
| POST | /v1/feedback | Optional | Submit feedback or bug report |
Response Format
All API responses use a standard JSON envelope.
Success
{
"ok": true,
"data": { ... },
"meta": {
"request_id": "req_...",
"timestamp": "2024-01-01T00:00:00.000Z"
}
} Paginated responses include meta.pagination with has_more and optionally next_cursor, total_count, and total_pages.
Error
{
"ok": false,
"error": {
"code": "not_found",
"message": "Skill not found.",
"status": 404,
"details": {}
},
"meta": {
"request_id": "req_...",
"timestamp": "2024-01-01T00:00:00.000Z"
}
} Error Codes
unauthorized(401) — Missing or invalid API key / sessionforbidden(403) — Insufficient permissions for the resource (also returned when email verification is required)not_found(404) — Resource does not existconflict(409) — Duplicate resource (e.g., version already exists, or max API keys reached)invalid_request(400) — Missing required fields, invalid format, or malformed request bodyinvalid_version(400) — Semver version string is invalid or does not meet requirementsvalidation_error(400) — Input failed schema or business-rule validationrate_limited(429) — Too many requests; checkRetry-Afterheaderstorage_limit_exceeded(413) — Account storage quota exceeded; upgrade to a paid planlink_revoked(410) — Share link has been revoked by the ownerlink_expired(410) — Share link has passed its expiry dateagent_limit_exceeded(403) — Maximum number of agents reached for this tiersnapshot_limit_exceeded(403) — Maximum number of snapshots reached for this agentstorage_error(500) — R2 storage operation failed; retry the requestservice_degraded(502/503) — A dependent service (email, billing) is unavailableinternal_error(500) — Unexpected server error
Rate Limits
Per-IP Sliding Window Limits
All API requests are rate-limited per IP address using a sliding window. Limits vary by endpoint group:
- Auth (
/v1/auth/*): 10 req/min - GitHub import, discover, import-url, verify (
/v1/skills/import-github,/v1/skills/import-url,/v1/skills/discover-github,*/verify): 10 req/min - Batch import (
/v1/skills/import-github/batch): 5 req/min - Agent create, scan, delete (
POST /v1/agents,*/scan,DELETE /v1/agents/*): 10 req/min - Agent snapshot upload (
POST /v1/agents/*/snapshots): 20 req/min - Billing, backup (
/v1/billing/*,/v1/backup/*): 30 req/min - Demo list (
GET /v1/skills/:ns/:name/demos): 40 req/min - Skill save (
POST /v1/skills/@{ns}/{name}): 60 req/min - Skill download (
GET /v1/skills/.../download/*): 60 req/min - Search (
GET /v1/skills/search): 60 req/min - Share, orgs, webhooks, agent read, demo detail/content/comments: 60 req/min each
- MCP server (
POST /mcp): 60 req/min - All other endpoints (
/v1/*): 120 req/min
Rate limit status is returned in response headers:
X-RateLimit-Limit— Maximum requests allowed in the windowX-RateLimit-Remaining— Requests remaining in the current windowX-RateLimit-Reset— Unix timestamp when the window resetsX-RateLimit-Window— Window identifier:"minute","hour", or"day"
When the limit is exceeded, the API returns a 429 status with a Retry-After header indicating how many seconds to wait.
Per-Hour Limits
Some sensitive endpoints have stricter per-hour limits:
- Google/GitHub sign-in: 5 req/hour each
- Email sign-in code (
/v1/auth/email/send-code): 5 req/hour - Email registration code (
/v1/auth/email/register/send-code): 5 req/hour (separate per-IP bucket) - Feedback (
POST /v1/feedback): 5 req/hour
Strict Per-Minute Limits
- Panic key revoke (
DELETE /v1/account/keys): 5 req/min
Scan & Recommend Limits
- Recommend (
POST /v1/skills/recommend): 20 req/min - Scan files (
POST /v1/scan/files): 30 req/min - MCP scan (
POST /v1/mcp/scan): 10 req/min
Feature-Specific Limits
- Demo upload: 20 req/min
- Demo update (
PATCH /v1/demos/:demoId): 20 req/min - Demo comments: 20 req/min (post/delete), 30 req/min (vote)
- Demo view tracking: 10 req/min
- Demo pin: 10 req/min
- Demo eval-link: 20 req/min
- Agent snapshot download: 30 req/min
- Badges (
GET /v1/badge/*): 60 req/min
Demos
Demos are recorded AI agent sessions uploaded to a skill's page. They show the skill in action and help users understand what to expect before installing.
Uploading a demo
POST /v1/skills/@myname/my-skill/versions/1.0.0/demos POST the recording JSON (conforming to the skillsafe-demo/1 schema) to the skill version's /demos endpoint with an authenticated API key. The demo is attached to the specified skill version and appears on the skill page. You can pin one demo per skill as the featured demo.
Browsing demos via API
GET /v1/demos?sort=views&limit=20
GET /v1/skills/@{ns}/{name}/demos
GET /v1/demos/{demoId}
GET /v1/demos/{demoId}/content The /v1/demos/:demoId/content endpoint returns the full recording (messages, tool calls, model). Use /v1/demos/:demoId for lightweight metadata only.
Evals & Benchmarks
Evals let publishers attach automated quality metrics to a skill version. Results are shown on the skill page and power the eval badge.
Uploading eval results
POST /v1/skills/@myname/my-skill/versions/1.0.0/eval POST an eval JSON body with pass_rate, test_cases, and optionally pass_count and model fields to record eval results for a skill version. Requires authentication.
Viewing eval results via API
GET /v1/skills/@{ns}/{name}/eval
GET /v1/skills/@{ns}/{name}/versions/{version}/eval Eval results include pass rate, test case counts, model name, and a regression flag if the score decreased from the previous version.
Badges
Embed live SVG badges in your README or documentation. All badge endpoints return image/svg+xml and are publicly accessible without authentication.
GET /v1/badge/@{ns}/{name}/verified — verification status
GET /v1/badge/@{ns}/{name}/installs — total install count
GET /v1/badge/@{ns}/{name}/scan — scan report result
GET /v1/badge/@{ns}/{name}/eval — latest eval pass rate Example Markdown for a README:



 Agents
Agent Identity lets you save and version your AI agent's configuration files (CLAUDE.md, .cursorrules, etc.) as immutable snapshots. Track changes over time, diff between versions, and scan snapshots for security issues.
Saving a snapshot
POST /v1/agents/:agentId/snapshots — Upload agent configuration files as a multipart form. Each snapshot gets a tree hash (SHA-256) for integrity verification. Optionally tag with a version string.
Diffing snapshots
GET /v1/agents/:agentId/diff?from={snapshotId}&to={snapshotId} — Compare two snapshots to see what files were added, removed, or modified between versions.
Scanning
POST /v1/agents/:agentId/snapshots/:snapshotId/scan — Run a security scan on a snapshot's files. Returns a scan report with findings categorized by severity.
Publishers
Publishers represent the source of imported skills — typically a GitHub user or organization. Claim your publisher identity to manage how your skills appear on SkillSafe.
Claiming a publisher
POST /v1/publishers/claim — Claim a publisher identity. For GitHub publishers, this verifies you control the GitHub account. Requires authentication.
Publisher profiles
GET /v1/publishers/:platform/:owner — Public publisher profile showing metadata, skill count, and verification status. No authentication required.
Security Model
- Integrity verification: SHA-256 tree hashes per version
- Tree hashes: Immutable per-version
- Dual verification: Independent sharer + consumer scans
- API key hashing: SHA-256 before storage
Report issues: security@skillsafe.ai