Documentation
Everything in one place — install and publish skills, build hosted apps, and understand the security model.
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 AI SkillSafe desktop app (one-click install, available for macOS / Windows / Linux) or npx skills add on the command line — see Installing below.
Run a skill anywhere
Once you've built a skill for a repetitive task, "run it anywhere" means one of four things. The right answer turns on a single distinction: a skill runs inside an agent that has your files; an app runs standalone for people who don't have one.
How to run a skill on any of your machines
Keep it a skill and install it from the registry on each machine. For a public or shared skill, npx skills add https://api.skillsafe.ai/@ns/name works anonymously in Claude Code, Cursor, Windsurf, and Codex. A skill you publish is private, so to install it on your own other machines, sign in there first — skillsafe login then skillsafe add @ns/name sends your credential and the registry serves you your own private skill. For a reproducible set across a fleet, declare what a project needs in a checked-in skillsafe.json and run skillsafe sync — signed in, it installs your private skills too. Publish your own local skill with skillsafe publish; it provisions a zero-signup account if you have no credential.
How to share a skill with a teammate who doesn't code
Send a link, not an install. skillsafe publish --share returns a https://skillsafe.ai/share/{id} URL; append ?md and it returns a self-contained plain-text document — provenance, tree hash, install commands, and the complete SKILL.md — that a teammate's agent can fetch in one request and act on immediately. Nothing to install on their side, and no account needed to read it.
How to run a skill on a schedule in the cloud
A skill runs inside your agent, so a schedule needs somewhere to run without you — deploy it as an app, then schedule the app. POST /v1/apps/{slug}/schedules with {"kind":"agent","cron":"0 9 * * mon-fri","timezone":"America/New_York"} runs the app's prompt on a timer, in your timezone, and can email the output or POST it to a webhook. No server to run, no CI runner to configure — see the deploy guide.
How to let people use a skill in a browser
This is where a skill becomes an app. An app is built for a goal and usually composes several skills, each recording how to do some of the steps; the frontend is designed for the goal, not generated from a skill. Deploy with skillsafe deploy (private to you by default) or POST /v1/apps with skill_ids, then design and upload a frontend per the deploy guide. It runs at https://{slug}.skillsafe.ai with accounts, billing, and storage built in — see Apps Platform.
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 AI SkillSafe desktop app (recommended)
Download the AI SkillSafe desktop app (macOS / Windows / Linux). On any skill page, click View in AI 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 | Pro: 10 GB | Team: 10 GB per seat, pooled across all members | Enterprise: 1 TB
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
Agents and snapshots are uncapped on every tier — snapshot bytes draw on your account storage quota. Only the per-snapshot size differs:
- Free: 1 MB per snapshot
- Paid: 10 MB per snapshot
- Team / Enterprise: 50 MB per snapshot
Installing a Skill
No account required to install public skills. There are several ways to install, depending on your workflow:
AI SkillSafe desktop app (recommended)
The AI SkillSafe desktop app (macOS / Windows / Linux) is the simplest way to install. On any skill page, click View in AI 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.
SkillSafe CLI
SkillSafe also ships its own installer CLI, @skillsafe/cli (binary: skillsafe). It is a zero-auth installer — no account or API key needed:
npm install -g @skillsafe/cli
skillsafe add namespace/skill-name Commands: add (alias install), remove, list, update, sync, audit, publish, deploy, login, and report. Installing public or shared skills needs no credential; installing a private skill you own, plus publish, deploy, and report, read one from SKILLSAFE_TOKEN or ~/.skillsafe/config.json (written by skillsafe login). add, sync, and audit send the stored credential when there is one, so your own private skills resolve.
Same skills on every machine
add accepts a pin — skillsafe add @ns/[email protected] — and sync makes that reproducible: declare what a project needs in a checked-in skillsafe.json, and every machine installs exactly that. update deliberately ignores pins and moves everything to latest; sync is the one to use when you want the same versions everywhere.
{
"skills": {
"@anthropics/pptx": "1.2.0",
"@vercel-labs/find-skills": "latest"
}
} Publishing from the command line
skillsafe publish ./my-skill hashes the directory, scans it with the platform scanner, negotiates a delta upload so unchanged files are not re-sent, and saves a private version. It refuses to save when the scan finds anything actionable (critical, high, or medium) unless you pass --force. Add --share for a link-only share, or --public to list it in the registry.
With no credential it provisions a zero-signup temporary account first. That account and everything it publishes is deleted after 7 days unless you attach an email — the command prints the two calls that do it.
skillsafe publish ./my-skill --version 1.0.0 --share The CLI is a convenience, not a requirement: every command wraps a documented HTTP endpoint, so an agent that cannot install an npm package has the same capabilities. See llms-full.txt.
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/
# Windsurf
unzip skill-name.zip -d .windsurf/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:[email protected]/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.
Apps Platform
Any saved skill can be deployed as a hosted mini-app at https://{slug}.skillsafe.ai/. The skill's SKILL.md is snapshotted as the app's system prompt at deploy time; the platform provides hosting, guest access (no account required to run an app), one-click user sign-in, credit-metered billing (you set the markup and keep all of it), data storage, and AI models (GPT and Workers AI, including per-image-billed image generation via gpt-image and flux-klein — Anthropic/Claude models are unavailable at present). Every public app is built from a security-scanned skill and must pass a clean scan — skill and frontend — before listing in the app directory.
Apps have four visibilities: private (owner-only), shared (an email list you manage — each invited address gets an email with the app link and signs in to SkillSafe with that address to use it; revoking an address cuts access immediately), unlisted (anyone with the link), and public (listed in the directory after a clean scan). Manage the shared list from the app dashboard's Settings tab or via POST /v1/apps/{slug}/share-grants.
Create an app
The deploy flow is agent-driven — no account needed to start. Paste this into Claude Code, Cursor, or any agent with web access:
Deploy this as an app on skillsafe.ai — see https://deploy.skillsafe.ai/llms.txt (no account needed). The agent mints a 7-day temp key, deploys, and tells you how to keep the app by verifying your email. Prefer a walkthrough with screenshots? See Turn a Skill Into an App.
Owners can opt in to open source: setting allow_fork on an app makes its complete source — prompt and release files — publicly viewable and lets anyone clone it into their own account with one call. Forks start unlisted with lineage back to the original; pricing, provider keys, and app data are never copied. Owners can also bring their own Anthropic or OpenAI API key (BYOK): runs then dispatch on the owner's provider account and users pay a flat 1-credit overhead per run instead of metered token cost.
What a run costs, and what you earn
A run's base is the model provider's list cost for the tokens it actually consumed, plus a fixed $0.001 per-job overhead (sized so 10% of it is exactly the 1-credit minimum, which keeps both cuts from rounding to nothing on a cheap model). Two separate cuts are added to that base: the platform's 10% margin, and your markup — anything from 0% to 100%, which you set on the app's Settings tab. At the default 10% you and the platform earn the same amount per run, and you keep 100% of your markup: no fee is deducted from it. The user pays base + both cuts, rounded up to whole credits ($1 = 10,000 credits, minimum 1 credit per run).
Earnings accrue per run and settle to your balance in whole cents. They mature 14 days after they arrive and then redeem at face value in US dollars with no payout fee, once you've earned $25. Credits cannot be transferred between accounts — earnings come only from other people's metered usage of your apps, so free promotional credits can never become cash. Runs on a publisher's own provider key (BYOK) are a flat 1 credit with markup disabled, since the publisher's key pays for inference directly.
Deploy guide — the platform API reference
The complete apps platform documentation is the Deploy guide at deploy.skillsafe.ai — a machine-readable reference that agents (and humans) can follow end to end. It covers authentication (including zero-signup temp keys), the save-skill → create-app → upload-release flow, App Specs, database collections and the query DSL, file storage, the cross-app user drive (apps own their apps/{slug}/ folder by default and reach anything else only with granted permission — users share files or folders to apps like handing work to agents), credit metering, and platform limits. Server functions and sandbox exec are documented there too but are currently dormant in production — a release containing functions/ or declaring sandbox: true is rejected until the platform bindings are enabled.
Key endpoints
The deploy and manage endpoints are listed in the API Reference below under Apps. Runtime APIs that hosted apps call at run time (app-user auth, data collections, files) are documented in the Deploy guide.
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, relevance, updated
Additional filter parameters: category, namespace, tag, scan_clean (boolean — only skills with clean scan reports), 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: metadata, optional scan_report, individual file_* fields) |
| 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/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) |
| GET | /v1/share/{shareId}/readme | No | Shared SKILL.md as markdown (records no install) |
| GET | /v1/skills/@{ns}/{name}/app | No | Public hosted app built from this skill, or null |
| 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) |
| Apps | |||
| POST | /v1/apps | Yes (verified) | Deploy an owned skill as a hosted app (snapshots SKILL.md as the system prompt; per-tier cap — 100 apps on Free, 2,000 on Pro, unlimited on Team/Enterprise). Temp deploy keys (POST /v1/auth/temp-key) let unverified accounts deploy 1 app for 7 days. |
| GET | /v1/apps | Yes | List your apps — one page at a time (limit ≤ 200, offset or cursor) with the full match count in meta.pagination.total. Optional visibility, q, and sort=created|updated|popular filter server-side. |
| GET | /v1/apps/{slug} | Yes | Publisher view of an app, including aggregate metering |
| PATCH | /v1/apps/{slug} | Yes | Update slug, metadata, model, pricing, or visibility |
| DELETE | /v1/apps/{slug} | Yes | Soft-delete an app (frees the subdomain) |
| POST | /v1/apps/{slug}/releases | Yes | Upload a frontend bundle or App Spec release (scan-gated for public apps). Add base (a release id or "current") plus delete to ship only the files that changed — everything else carries forward, and an explicit base that another deploy has overtaken answers 409 instead of reverting it |
| GET | /v1/apps/{slug}/releases/{id}/files | Yes | Release file listing with per-file sha256 and the stored scan report — hash locally to work out what to upload |
| GET | /v1/apps/{slug}/releases/{id}/diff?from= | Yes | Added / modified / deleted paths between two releases |
| POST | /v1/apps/{slug}/releases/{id}/promote | Yes | Point the app back at a retained earlier release (instant rollback) |
| GET | /v1/apps/{slug}/schedules | Yes | List an app's schedules (with a human-readable timing string) |
| POST | /v1/apps/{slug}/schedules | Yes | Run the app on a timer: kind: "agent" submits its own prompt, timed by a cron expression in your timezone or a plain interval; output can be emailed or POSTed to a webhook |
| PATCH | /v1/apps/{slug}/schedules/{id} | Yes | Retime, re-enable, or change delivery for a schedule; DELETE removes it |
| POST | /v1/apps/{slug}/fork | Yes (verified) | Clone a forkable app (allow_fork) into your own account |
| GET | /v1/apps/{slug}/source | No | View-source for forkable apps: prompt snapshot + release file listing |
| GET | /v1/apps/{slug}/provider-keys | Yes | BYOK key status per provider (configured, last4 — values are write-only) |
| PUT | /v1/apps/{slug}/provider-keys/{provider} | Yes (verified) | Set your own Anthropic/OpenAI key (BYOK); DELETE removes it |
| GET | /v1/app-api/storage | App token | Caller's storage usage and governing quota (app-user aut_* token) |
| GET | /v1/app-api/collections | App token | Collections the app declared, with their read/write ACLs |
| POST | /v1/app-api/collections/{c}/query | App token | Filter, sort and paginate records (query DSL); reads are ACL-filtered |
| POST | /v1/app-api/collections/{c}/similar | App token | Vector similarity search over a collection's declared embed fields |
| POST | /v1/app-api/search | App token | Server-side web retrieval via a release-declared provider; results are provenance-stamped and cached 24h |
| GET | /v1/apps/search | No | Public app directory (public + active apps) |
| GET | /v1/apps/{slug}/public | Optional | Public listing for a discoverable app |
| GET | /v1/rankings/models | No | 30-day model-usage rankings from real metered runs (aggregates only; powers /rankings/) |
| POST | /v1/import/artifact | No | Paste a Claude artifact's source; returns a draft App Spec + recovered prompt logic, and for HTML artifacts also files + artifact_system_prompt — the artifact's own UI ready to serve as the app frontend |
| 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 | Stripe customer balance (proration credit) |
| GET | /v1/billing/credits | Yes | Usage balance with earned/granted breakdown |
| GET | /v1/billing/credits/history | Yes | Credit ledger history (paginated) |
| POST | /v1/billing/credits/checkout | Yes (verified) | Buy usage credits at face value (pack or custom amount) |
| GET | /v1/billing/redeem | Yes (verified) | Redeemable earnings summary + payout requests |
| POST | /v1/billing/redeem | Yes (verified) | Request an earnings payout (14-day maturity, $25 min, no fee) |
| 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/seats | Yes (verified) | Change seats on a Team/Enterprise subscription (prorated) |
| 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/skills/@{ns}/{name}/pin-demo | Yes | Pin or unpin a demo on the skill page (owner only) |
| 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 |
| 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": "2026-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": "2026-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
- 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.
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 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
The full security documentation — scanner rules and threat patterns, the dual-side verification flow, trust verdicts, the confirmed threat database, and the responsible disclosure policy — lives on the Security page. You can also scan your MCP config for poisoned tool descriptions.
The short version:
- 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: [email protected]